refactor event

This commit is contained in:
Timi
2026-08-05 22:50:22 +08:00
parent 22ff13b1fe
commit 1243068fc3
46 changed files with 961 additions and 789 deletions
+50 -49
View File
@@ -1,5 +1,5 @@
<template>
<div v-can="gaoPermissionCodes.stat.read" class="data-charts-page">
<div v-can="permissionCodes.stat.read" class="data-charts-page">
<section class="summary">
<div v-for="item in summaryList" :key="item.label" class="summary-item">
<span v-text="item.label" />
@@ -7,10 +7,10 @@
</div>
</section>
<registration-event-record-calendar
<event-record-calendar
v-model="monthCursor"
v-model:selected-registration-event-id-list="selectedRegistrationEventIdList"
:registration-event-list="registrationEventList"
v-model:selected-event-id-list="selectedEventIdList"
:event-list="eventList"
empty-text="当前月份暂无登记事件记录"
:loading="calendarLoading"
:records="monthRecords"
@@ -34,14 +34,14 @@ import { GridComponent, LegendComponent, TooltipComponent } from "echarts/compon
import { init, use } from "echarts/core";
import { CanvasRenderer } from "echarts/renderers";
import CustomerAPI from "@/api/CustomerAPI";
import RegistrationEventAPI from "@/api/RegistrationEventAPI";
import RegistrationEventRecordAPI from "@/api/RegistrationEventRecordAPI";
import RegistrationEventRecordCalendar from "@/components/RegistrationEventRecordCalendar.vue";
import EventAPI from "@/api/EventAPI";
import EventRecordAPI from "@/api/EventRecordAPI";
import EventRecordCalendar from "@/components/EventRecordCalendar.vue";
import type { CustomerDailyStatView, CustomerGenderStatView } from "@/types/Customer";
import type { RegistrationEvent } from "@/types/RegistrationEvent";
import type { RegistrationEventRecord, RegistrationEventRecordCalendarView, RegistrationEventRecordDailyStatView } from "@/types/RegistrationEventRecord";
import type { EventItem } from "@/types/EventItem";
import type { EventRecord, EventRecordCalendarView, EventRecordDailyStatView } from "@/types/EventRecord";
import { Time } from "timi-web";
import { gaoPermissionCodes } from "@/utils/gaoPermission";
import { permissionCodes } from "@/utils/permission";
interface SummaryItem {
label: string;
@@ -69,12 +69,12 @@ use([
const chartRefs = new Map<string, HTMLElement>();
const chartInstances = new Map<string, ECharts>();
const registrationEventList = ref<RegistrationEvent[]>([]);
const selectedRegistrationEventIdList = ref<string[]>([]);
const eventList = ref<EventItem[]>([]);
const selectedEventIdList = ref<string[]>([]);
const customerDailyStatList = ref<CustomerDailyStatView[]>([]);
const customerGenderStatList = ref<CustomerGenderStatView[]>([]);
const recordDailyStatMap = ref<Record<string, RegistrationEventRecordDailyStatView[]>>({});
const monthRecords = ref<RegistrationEventRecord[]>([]);
const recordDailyStatMap = ref<Record<string, EventRecordDailyStatView[]>>({});
const monthRecords = ref<EventRecord[]>([]);
const loading = ref(false);
const calendarLoading = ref(false);
const monthCursor = ref(getMonthStart(new Date()));
@@ -87,8 +87,8 @@ const beginDate = getDateStart(addDays(new Date(), -6));
const endDate = getDateEnd(new Date());
const dateTextList = buildDateTextList(beginDate, endDate);
const timestampRange = {
beginRegisteredAt: Time.toTimestamp(beginDate),
endRegisteredAt: Time.toTimestamp(endDate)
beginAt: Time.toTimestamp(beginDate),
endAt: Time.toTimestamp(endDate)
};
const summaryList = computed<SummaryItem[]>(() => [
@@ -188,27 +188,27 @@ function resizeCharts(): void {
async function loadChartsData(): Promise<void> {
loading.value = true;
try {
registrationEventList.value = await RegistrationEventAPI.enabledList();
const validRegistrationEventList = registrationEventList.value.filter((item): item is RegistrationEvent & { id: string } => Boolean(item.id));
selectedRegistrationEventIdList.value = validRegistrationEventList.map(item => item.id);
eventList.value = await EventAPI.enabledList();
const valideventList = eventList.value.filter((item): item is EventItem & { id: string } => Boolean(item.id));
selectedEventIdList.value = valideventList.map(item => item.id);
const [customerStatList, genderStatList, recordDailyStatList] = await Promise.all([
CustomerAPI.dailyStat({
beginCreatedAt: timestampRange.beginRegisteredAt,
endCreatedAt: timestampRange.endRegisteredAt
beginCreatedAt: timestampRange.beginAt,
endCreatedAt: timestampRange.endAt
}),
CustomerAPI.genderStat(),
Promise.all(validRegistrationEventList.map(async item => ({
registrationEventId: item.id,
stats: await RegistrationEventRecordAPI.allCustomerRegistrationEventDailyStat({
registrationEventId: item.id,
beginRegisteredAt: timestampRange.beginRegisteredAt,
endRegisteredAt: timestampRange.endRegisteredAt
Promise.all(valideventList.map(async item => ({
eventId: item.id,
stats: await EventRecordAPI.allCustomerEventDailyStat({
eventId: item.id,
beginAt: timestampRange.beginAt,
endAt: timestampRange.endAt
})
})))
]);
customerDailyStatList.value = customerStatList;
customerGenderStatList.value = genderStatList;
recordDailyStatMap.value = Object.fromEntries(recordDailyStatList.map(item => [item.registrationEventId, item.stats]));
recordDailyStatMap.value = Object.fromEntries(recordDailyStatList.map(item => [item.eventId, item.stats]));
} finally {
loading.value = false;
}
@@ -219,9 +219,9 @@ async function loadMonthRecords(): Promise<void> {
const end = getDateEnd(addDays(begin, 41));
calendarLoading.value = true;
try {
const calendarRecordList = await RegistrationEventRecordAPI.calendarRangeList({
beginRegisteredAt: Time.toTimestamp(begin),
endRegisteredAt: Time.toTimestamp(end)
const calendarRecordList = await EventRecordAPI.calendarRangeList({
beginAt: Time.toTimestamp(begin),
endAt: Time.toTimestamp(end)
});
monthRecords.value = calendarRecordList.map(buildCalendarRecord);
} finally {
@@ -295,14 +295,14 @@ function buildCustomerGrowthOption(): EChartsOption {
function buildRecordTrendOption(): EChartsOption {
return {
...buildBaseOption(),
series: registrationEventList.value.map(action => ({
series: eventList.value.map(action => ({
name: action.name || "未命名事件",
type: "bar",
stack: "record",
itemStyle: getRegistrationEventColor(action) ? {
color: getRegistrationEventColor(action)
itemStyle: getEventColor(action) ? {
color: getEventColor(action)
} : undefined,
data: dateTextList.map(dateText => countRecordByRegistrationEventAndDate(action.id || "", dateText))
data: dateTextList.map(dateText => countRecordByEventAndDate(action.id || "", dateText))
}))
};
}
@@ -315,7 +315,7 @@ function buildEventStructureOption(): EChartsOption {
},
xAxis: {
type: "category",
data: registrationEventList.value.map(item => item.name || "未命名事件"),
data: eventList.value.map(item => item.name || "未命名事件"),
axisTick: {
show: false
},
@@ -326,10 +326,10 @@ function buildEventStructureOption(): EChartsOption {
series: [{
name: "登记次数",
type: "bar",
data: registrationEventList.value.map(item => ({
value: countRecordByRegistrationEvent(item.id || ""),
itemStyle: getRegistrationEventColor(item) ? {
color: getRegistrationEventColor(item)
data: eventList.value.map(item => ({
value: countRecordByEvent(item.id || ""),
itemStyle: getEventColor(item) ? {
color: getEventColor(item)
} : undefined
}))
}]
@@ -391,7 +391,7 @@ function sumCustomerNewCount(): number {
}
function sumActionDailyCount(): number {
return registrationEventList.value.reduce((sum, item) => sum + countRecordByRegistrationEvent(item.id || ""), 0);
return eventList.value.reduce((sum, item) => sum + countRecordByEvent(item.id || ""), 0);
}
function getCustomerDailyStat(dateText: string): CustomerDailyStatView | undefined {
@@ -399,28 +399,28 @@ function getCustomerDailyStat(dateText: string): CustomerDailyStatView | undefin
return customerDailyStatList.value.find(item => item.dateValue === dateValue);
}
function countRecordByRegistrationEventAndDate(registrationEventId: string, dateText: string): number {
function countRecordByEventAndDate(eventId: string, dateText: string): number {
const dateValue = Number(dateText.replaceAll("-", ""));
return recordDailyStatMap.value[registrationEventId]?.find(item => item.dateValue === dateValue)?.dailyCount || 0;
return recordDailyStatMap.value[eventId]?.find(item => item.dateValue === dateValue)?.dailyCount || 0;
}
function countRecordByRegistrationEvent(registrationEventId: string): number {
return (recordDailyStatMap.value[registrationEventId] || []).reduce((sum, item) => sum + (item.dailyCount || 0), 0);
function countRecordByEvent(eventId: string): number {
return (recordDailyStatMap.value[eventId] || []).reduce((sum, item) => sum + (item.dailyCount || 0), 0);
}
function getRegistrationEventColor(registrationEvent: RegistrationEvent): string | undefined {
return registrationEvent.color || undefined;
function getEventColor(event: EventItem): string | undefined {
return event.color || undefined;
}
function getGenderCount(genderCode: "MALE" | "FEMALE" | "UNKNOWN"): number {
return customerGenderStatList.value.find(item => item.genderCode === genderCode)?.count || 0;
}
function buildCalendarRecord(record: RegistrationEventRecordCalendarView): RegistrationEventRecord {
function buildCalendarRecord(record: EventRecordCalendarView): EventRecord {
return {
id: record.id,
customerId: record.customerId,
registrationEventId: record.registrationEventId,
eventId: record.eventId,
registeredAt: record.registeredAt,
customer: record.customerId || record.customerCode || record.customerName ? {
id: record.customerId,
@@ -547,3 +547,4 @@ function buildDateTextList(begin: Date, end: Date): string[] {
}
}
</style>