add customer list for StoreCustomerGrowthChart.vue

This commit is contained in:
Timi
2026-09-12 00:43:46 +08:00
parent 1c2cd2506b
commit 4c8dadc7bc
2 changed files with 54 additions and 3 deletions
@@ -15,16 +15,18 @@
<script setup lang="ts">
import { Time } from "timi-web";
import type { EChartsOption } from "echarts";
import type { DefaultLabelFormatterCallbackParams, EChartsOption } from "echarts";
import StoreChartAPI from "@/api/StoreChartAPI";
import ChartRangeSlider from "@/components/ChartRangeSlider.vue";
import type { CustomerDailyStatView } from "@/types/Customer";
import type { CustomerDailyStatCustomerView, CustomerDailyStatView } from "@/types/Customer";
import { buildStoreBaseChartOption, useStoreChart, useStoreChartWindow } from "@/pages/store/component/useStoreChart";
const props = defineProps<{
dateTextList: string[];
}>();
const MAX_TOOLTIP_CUSTOMER_COUNT = 24;
// ---------- 图表数据 ----------
const statList = ref<CustomerDailyStatView[]>([]);
@@ -82,7 +84,12 @@ const chartOption = computed<EChartsOption>(() => ({
yAxisIndex: 1,
data: visibleDateTextList.value.map(dateText => getDailyStat(dateText)?.newCustomerCount || 0)
}
]
],
tooltip: {
trigger: "axis",
formatter: params => formatGrowthTooltip(params),
extraCssText: "max-width: min(19rem, calc(100vw - 2rem));"
}
}));
const { chartElement } = useStoreChart(chartOption);
@@ -115,6 +122,45 @@ function getDailyStat(dateText: string): CustomerDailyStatView | undefined {
return statList.value.find(item => item.dateValue === dateValue);
}
function formatGrowthTooltip(params: DefaultLabelFormatterCallbackParams | DefaultLabelFormatterCallbackParams[]): string {
const firstParam = Array.isArray(params) ? params[0] : params;
const dateText = visibleDateTextList.value[firstParam?.dataIndex ?? -1];
const stat = dateText ? getDailyStat(dateText) : undefined;
if (!dateText || !stat) {
return "";
}
const customerList = stat.customerList || [];
const visibleCustomerList = customerList.slice(0, MAX_TOOLTIP_CUSTOMER_COUNT);
const customerHTML = visibleCustomerList.length
? visibleCustomerList.map(formatCustomerTooltipItem).join("")
: "";
const hiddenCustomerCount = Math.max(0, customerList.length - visibleCustomerList.length);
const hiddenCustomerHTML = hiddenCustomerCount
? `<div style="color:#94a3b8;margin-top:4px;">还有 ${hiddenCustomerCount} 人未显示</div>`
: "";
return [
`<div style="font-weight:700;margin-bottom:6px;">${escapeTooltipHTML(dateText)}</div>`,
`<div>客户总量:${stat.totalCustomerCount || 0} 人</div>`,
`<div>新客户量:${stat.newCustomerCount || 0} 人</div>`,
`<div style="display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:2px 10px;margin-top:6px;">${customerHTML}${hiddenCustomerHTML}</div>`
].join("");
}
function formatCustomerTooltipItem(customer: CustomerDailyStatCustomerView): string {
return `<div style="line-height:1.6;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">${escapeTooltipHTML(customer.name || "未命名客户")}</div>`;
}
function escapeTooltipHTML(value: string): string {
return value.replace(/[&<>"']/g, character => ({
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
"\"": "&quot;",
"'": "&#39;"
}[character] || character));
}
// ---------- 日期 ----------
function getDateStart(dateText: string): Date {
+5
View File
@@ -57,6 +57,11 @@ export type CustomerDailyStatView = {
dateValue?: number;
newCustomerCount?: number;
totalCustomerCount?: number;
customerList?: CustomerDailyStatCustomerView[];
};
export type CustomerDailyStatCustomerView = {
name?: string;
};
export type CustomerGenderStatView = {