fix:修改时间趋势分析图的指标问题

This commit is contained in:
hangyu.tao 2026-02-02 11:16:34 +08:00
parent 1134943bb2
commit a2ad9cafde
2 changed files with 96 additions and 99 deletions

View File

@ -479,10 +479,16 @@
<div class="card-header">
<h3><i class="fas fa-chart-line"></i> 时间趋势分析</h3>
<div class="chart-controls">
<select id="trendTypeSelect" class="chart-field-select">
<option value="all" selected>全部指标</option>
<option value="customer">客户数</option>
<option value="demand">需求数</option>
<option value="issue">反馈数</option>
</select>
<select id="trendChartFieldSelect" class="chart-field-select">
<option value="month">按月统计</option>
<option value="day" selected>按天统计</option>
<option value="week">按周统计</option>
<option value="day">按天统计</option>
<option value="month">按月统计</option>
</select>
</div>
</div>

View File

@ -61,7 +61,7 @@ function canDelete() {
}
document.addEventListener("DOMContentLoaded", function () {
console.log("CRM System Main JS v4.0 Loaded - " + new Date().toLocaleString());
console.log("CRM System Main JS v4.5 Loaded - " + new Date().toLocaleString());
// 登录守卫
const token = localStorage.getItem("crmToken");
if (!token && !window.location.pathname.endsWith("login.html")) {
@ -1653,7 +1653,9 @@ document.addEventListener("DOMContentLoaded", function () {
const ctx = canvas.getContext("2d");
const trendType =
document.getElementById("trendTypeSelect")?.value || "customer";
document.getElementById("trendTypeSelect")?.value || "all";
const dateGrain =
document.getElementById("trendChartFieldSelect")?.value || "day";
if (trendChartInstance) {
trendChartInstance.destroy();
@ -1663,11 +1665,23 @@ document.addEventListener("DOMContentLoaded", function () {
const dateMap = {};
customers.forEach((customer) => {
const dateStr = normalizeDateValue(customer.intendedProduct);
if (!dateStr) return;
const dateValue = normalizeDateValue(customer.intendedProduct);
if (!dateValue) return;
if (!dateMap[dateStr]) {
dateMap[dateStr] = {
let dateKey = dateValue;
if (dateGrain === "month") {
dateKey = dateValue.substring(0, 7); // YYYY-MM
} else if (dateGrain === "week") {
// Find Monday of that week
const d = new Date(dateValue);
const day = d.getDay();
const diff = d.getDate() - day + (day === 0 ? -6 : 1);
const monday = new Date(d.setDate(diff));
dateKey = monday.toISOString().split("T")[0] + " (周)";
}
if (!dateMap[dateKey]) {
dateMap[dateKey] = {
customers: new Set(),
demands: 0,
issues: 0,
@ -1676,16 +1690,20 @@ document.addEventListener("DOMContentLoaded", function () {
// Count customers
if (customer.customerName) {
dateMap[dateStr].customers.add(customer.customerName);
dateMap[dateKey].customers.add(customer.customerName);
}
// Count demands and issues based on type
const type = (customer.type || "").toLowerCase();
if (type.includes("需求")) {
dateMap[dateStr].demands++;
dateMap[dateKey].demands++;
}
if (type.includes("问题") || type.includes("功能问题")) {
dateMap[dateStr].issues++;
if (
type.includes("问题") ||
type.includes("功能问题") ||
type.includes("反馈")
) {
dateMap[dateKey].issues++;
}
});
@ -1695,96 +1713,60 @@ document.addEventListener("DOMContentLoaded", function () {
// Prepare datasets based on selected trend type
const datasets = [];
const customerDataset = {
label: "客户数",
data: sortedDates.map((date) => dateMap[date].customers.size),
borderColor: "#FF6B35",
backgroundColor: "rgba(255, 107, 53, 0.1)",
borderWidth: 3,
pointRadius: 5,
pointHoverRadius: 7,
pointBackgroundColor: "#FF6B35",
pointBorderColor: "#fff",
pointBorderWidth: 2,
tension: 0.4,
fill: trendType === "customer",
};
const demandDataset = {
label: "需求数",
data: sortedDates.map((date) => dateMap[date].demands),
borderColor: "#4CAF50",
backgroundColor: "rgba(76, 175, 80, 0.1)",
borderWidth: 3,
pointRadius: 5,
pointHoverRadius: 7,
pointBackgroundColor: "#4CAF50",
pointBorderColor: "#fff",
pointBorderWidth: 2,
tension: 0.4,
fill: trendType === "demand",
};
const issueDataset = {
label: "反馈数",
data: sortedDates.map((date) => dateMap[date].issues),
borderColor: "#2196F3",
backgroundColor: "rgba(33, 150, 243, 0.1)",
borderWidth: 3,
pointRadius: 5,
pointHoverRadius: 7,
pointBackgroundColor: "#2196F3",
pointBorderColor: "#fff",
pointBorderWidth: 2,
tension: 0.4,
fill: trendType === "issue",
};
if (trendType === "customer") {
datasets.push({
label: "客户数",
data: sortedDates.map((date) => dateMap[date].customers.size),
borderColor: "#FF6B35",
backgroundColor: "rgba(255, 107, 53, 0.1)",
borderWidth: 3,
pointRadius: 5,
pointHoverRadius: 7,
pointBackgroundColor: "#FF6B35",
pointBorderColor: "#fff",
pointBorderWidth: 2,
tension: 0.4,
fill: true,
});
datasets.push(customerDataset);
} else if (trendType === "demand") {
datasets.push({
label: "需求数",
data: sortedDates.map((date) => dateMap[date].demands),
borderColor: "#4CAF50",
backgroundColor: "rgba(76, 175, 80, 0.1)",
borderWidth: 3,
pointRadius: 5,
pointHoverRadius: 7,
pointBackgroundColor: "#4CAF50",
pointBorderColor: "#fff",
pointBorderWidth: 2,
tension: 0.4,
fill: true,
});
datasets.push(demandDataset);
} else if (trendType === "issue") {
datasets.push({
label: "问题数",
data: sortedDates.map((date) => dateMap[date].issues),
borderColor: "#F28C28",
backgroundColor: "rgba(242, 140, 40, 0.1)",
borderWidth: 3,
pointRadius: 5,
pointHoverRadius: 7,
pointBackgroundColor: "#F28C28",
pointBorderColor: "#fff",
pointBorderWidth: 2,
tension: 0.4,
fill: true,
});
} else if (trendType === "all") {
datasets.push(
{
label: "客户数",
data: sortedDates.map((date) => dateMap[date].customers.size),
borderColor: "#FF6B35",
backgroundColor: "rgba(255, 107, 53, 0.1)",
borderWidth: 3,
pointRadius: 5,
pointHoverRadius: 7,
pointBackgroundColor: "#FF6B35",
pointBorderColor: "#fff",
pointBorderWidth: 2,
tension: 0.4,
fill: false,
},
{
label: "需求数",
data: sortedDates.map((date) => dateMap[date].demands),
borderColor: "#4CAF50",
backgroundColor: "rgba(76, 175, 80, 0.1)",
borderWidth: 3,
pointRadius: 5,
pointHoverRadius: 7,
pointBackgroundColor: "#4CAF50",
pointBorderColor: "#fff",
pointBorderWidth: 2,
tension: 0.4,
fill: false,
},
{
label: "问题数",
data: sortedDates.map((date) => dateMap[date].issues),
borderColor: "#F28C28",
backgroundColor: "rgba(242, 140, 40, 0.1)",
borderWidth: 3,
pointRadius: 5,
pointHoverRadius: 7,
pointBackgroundColor: "#F28C28",
pointBorderColor: "#fff",
pointBorderWidth: 2,
tension: 0.4,
fill: false,
},
);
datasets.push(issueDataset);
} else {
// all
datasets.push(customerDataset, demandDataset, issueDataset);
}
trendChartInstance = new Chart(ctx, {
@ -1928,6 +1910,15 @@ document.addEventListener("DOMContentLoaded", function () {
});
}
const trendChartFieldSelect = document.getElementById("trendChartFieldSelect");
if (trendChartFieldSelect) {
trendChartFieldSelect.addEventListener("change", function () {
const startDate = document.getElementById("startDate").value;
const endDate = document.getElementById("endDate").value;
applyDateFilter(startDate, endDate);
});
}
// ========== Follow-up Management ==========
const followupSection = document.getElementById("followupSection");
const addFollowUpBtn = document.getElementById("addFollowUpBtn");