add totalNumberValue for rank
This commit is contained in:
@@ -85,20 +85,29 @@
|
|||||||
<template #description>
|
<template #description>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<t-tag
|
<t-tag
|
||||||
|
v-if="rankType === 'TOTAL_DAYS'"
|
||||||
size="small"
|
size="small"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
:content="`累计天数 ${item.totalEventDays || 0}`"
|
:content="`累计天数 ${item.totalEventDays || 0}`"
|
||||||
/>
|
/>
|
||||||
<t-tag
|
<t-tag
|
||||||
|
v-else-if="rankType === 'TOTAL_COUNT'"
|
||||||
size="small"
|
size="small"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
:content="`累计次数 ${item.totalEventCount || 0}`"
|
:content="`累计次数 ${item.totalEventCount || 0}`"
|
||||||
/>
|
/>
|
||||||
<t-tag
|
<t-tag
|
||||||
|
v-else-if="rankType === 'CONTINUOUS_DAYS'"
|
||||||
size="small"
|
size="small"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
:content="`连续天数 ${item.recentContinuousEventDays || 0}`"
|
:content="`连续天数 ${item.recentContinuousEventDays || 0}`"
|
||||||
/>
|
/>
|
||||||
|
<t-tag
|
||||||
|
v-else
|
||||||
|
size="small"
|
||||||
|
variant="outline"
|
||||||
|
:content="`登记数值 ${getTotalNumberValueText(item)}`"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</t-cell>
|
</t-cell>
|
||||||
@@ -138,6 +147,7 @@ import type { CustomerEventRankView, EventRecordRankPage, EventRecordRankType }
|
|||||||
import type { EventItem } from "@/types/EventItem";
|
import type { EventItem } from "@/types/EventItem";
|
||||||
import { getCustomerPhotoURL } from "@/utils/customer";
|
import { getCustomerPhotoURL } from "@/utils/customer";
|
||||||
import { getErrorMessage } from "@/utils/error";
|
import { getErrorMessage } from "@/utils/error";
|
||||||
|
import { formatEventNumberValue } from "@/utils/eventValue";
|
||||||
import { permissionCodes } from "@/utils/permission";
|
import { permissionCodes } from "@/utils/permission";
|
||||||
|
|
||||||
type DateFilterType = "all" | "today" | "yesterday" | "lastWeek" | "thisMonth" | "custom";
|
type DateFilterType = "all" | "today" | "yesterday" | "lastWeek" | "thisMonth" | "custom";
|
||||||
@@ -152,7 +162,8 @@ const router = useRouter();
|
|||||||
const rankTypeOptions: Array<{ label: string; value: EventRecordRankType }> = [
|
const rankTypeOptions: Array<{ label: string; value: EventRecordRankType }> = [
|
||||||
{ label: "按登记天数", value: "TOTAL_DAYS" },
|
{ label: "按登记天数", value: "TOTAL_DAYS" },
|
||||||
{ label: "按登记次数", value: "TOTAL_COUNT" },
|
{ label: "按登记次数", value: "TOTAL_COUNT" },
|
||||||
{ label: "按连续天数", value: "CONTINUOUS_DAYS" }
|
{ label: "按连续天数", value: "CONTINUOUS_DAYS" },
|
||||||
|
{ label: "按登记数值", value: "TOTAL_NUMBER_VALUE" }
|
||||||
];
|
];
|
||||||
const dateOptions: Array<{ label: string; value: DateFilterType }> = [
|
const dateOptions: Array<{ label: string; value: DateFilterType }> = [
|
||||||
{ label: "全部时间", value: "all" },
|
{ label: "全部时间", value: "all" },
|
||||||
@@ -177,25 +188,45 @@ let initialized = false;
|
|||||||
const isCustomRange = computed(() => dateFilterType.value === "custom");
|
const isCustomRange = computed(() => dateFilterType.value === "custom");
|
||||||
const rankTypeLabel = computed(() => rankTypeOptions.find(item => item.value === rankType.value)?.label || "按登记天数");
|
const rankTypeLabel = computed(() => rankTypeOptions.find(item => item.value === rankType.value)?.label || "按登记天数");
|
||||||
const dateFilterLabel = computed(() => dateOptions.find(item => item.value === dateFilterType.value)?.label || "全部时间");
|
const dateFilterLabel = computed(() => dateOptions.find(item => item.value === dateFilterType.value)?.label || "全部时间");
|
||||||
const eventOptions = computed(() => eventList.value.map(item => ({
|
const selectableEventList = computed(() => rankType.value === "TOTAL_NUMBER_VALUE"
|
||||||
|
? eventList.value.filter(item => item.valueType === "NUMBER")
|
||||||
|
: eventList.value);
|
||||||
|
const eventOptions = computed(() => selectableEventList.value.map(item => ({
|
||||||
label: item.name || "未命名事件",
|
label: item.name || "未命名事件",
|
||||||
value: item.id || ""
|
value: item.id || ""
|
||||||
})).filter(item => item.value));
|
})).filter(item => item.value));
|
||||||
const eventFilterLabel = computed(() => {
|
const eventFilterLabel = computed(() => {
|
||||||
if (!eventFilter.value.length || eventFilter.value.length === eventList.value.length) {
|
if (!eventFilter.value.length || eventFilter.value.length === selectableEventList.value.length) {
|
||||||
return "全部事件";
|
return rankType.value === "TOTAL_NUMBER_VALUE" ? "全部有数值事件" : "全部事件";
|
||||||
}
|
}
|
||||||
|
|
||||||
return eventList.value
|
return selectableEventList.value
|
||||||
.filter(item => item.id && eventFilter.value.includes(item.id))
|
.filter(item => item.id && eventFilter.value.includes(item.id))
|
||||||
.map(item => item.name || "未命名事件")
|
.map(item => item.name || "未命名事件")
|
||||||
.join("、");
|
.join("、");
|
||||||
});
|
});
|
||||||
const canLoadRank = computed(() => rankType.value !== "CONTINUOUS_DAYS" || eventFilter.value.length === 1);
|
const selectedNumberEvent = computed(() => {
|
||||||
|
if (rankType.value !== "TOTAL_NUMBER_VALUE" || eventFilter.value.length !== 1) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return selectableEventList.value.find(item => item.id === eventFilter.value[0]);
|
||||||
|
});
|
||||||
|
const canLoadRank = computed(() => {
|
||||||
|
if (rankType.value === "CONTINUOUS_DAYS") {
|
||||||
|
return eventFilter.value.length === 1;
|
||||||
|
}
|
||||||
|
if (rankType.value === "TOTAL_NUMBER_VALUE") {
|
||||||
|
return Boolean(selectedNumberEvent.value);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
const emptyStateText = computed(() => {
|
const emptyStateText = computed(() => {
|
||||||
if (isLoading.value) {
|
if (isLoading.value) {
|
||||||
return "正在加载登记记录排行";
|
return "正在加载登记记录排行";
|
||||||
}
|
}
|
||||||
|
if (rankType.value === "TOTAL_NUMBER_VALUE") {
|
||||||
|
return "数值排行需要选择单个有数值事件";
|
||||||
|
}
|
||||||
return canLoadRank.value ? "暂无登记记录排行" : "连续排行需要选择单个登记事件";
|
return canLoadRank.value ? "暂无登记记录排行" : "连续排行需要选择单个登记事件";
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -299,6 +330,7 @@ async function loadEvents(): Promise<void> {
|
|||||||
eventFilter.value = eventIdList.length
|
eventFilter.value = eventIdList.length
|
||||||
? eventIdList
|
? eventIdList
|
||||||
: eventList.value.map(item => item.id).filter((item): item is string => Boolean(item));
|
: eventList.value.map(item => item.id).filter((item): item is string => Boolean(item));
|
||||||
|
normalizeEventFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function selectRankType(value: DropdownValue): Promise<void> {
|
async function selectRankType(value: DropdownValue): Promise<void> {
|
||||||
@@ -307,11 +339,14 @@ async function selectRankType(value: DropdownValue): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rankType.value = parseRankType(value);
|
rankType.value = parseRankType(value);
|
||||||
|
const filterChanged = normalizeEventFilter();
|
||||||
await replaceFilterQuery();
|
await replaceFilterQuery();
|
||||||
if (!canLoadRank.value) {
|
if (!canLoadRank.value) {
|
||||||
Toast.warning("连续排行需要选择单个登记事件");
|
Toast.warning(rankType.value === "TOTAL_NUMBER_VALUE" ? "数值排行需要选择单个有数值事件" : "连续排行需要选择单个登记事件");
|
||||||
|
}
|
||||||
|
if (!filterChanged) {
|
||||||
|
await reloadRanks();
|
||||||
}
|
}
|
||||||
await reloadRanks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function selectDateFilter(value: DropdownValue): Promise<void> {
|
async function selectDateFilter(value: DropdownValue): Promise<void> {
|
||||||
@@ -348,9 +383,14 @@ function getCustomerInitial(item: CustomerEventRankView): string {
|
|||||||
return getCustomerName(item).slice(0, 1);
|
return getCustomerName(item).slice(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTotalNumberValueText(item: CustomerEventRankView): string {
|
||||||
|
return formatEventNumberValue(selectedNumberEvent.value, item.totalNumberValue);
|
||||||
|
}
|
||||||
|
|
||||||
function buildRankReq(): Omit<EventRecordRankPage, "index" | "size"> {
|
function buildRankReq(): Omit<EventRecordRankPage, "index" | "size"> {
|
||||||
const [beginAt, endAt] = buildUnixRange();
|
const [beginAt, endAt] = buildUnixRange();
|
||||||
const selectedAllEvent = rankType.value !== "CONTINUOUS_DAYS" && (!eventFilter.value.length || eventFilter.value.length === eventList.value.length);
|
const selectedAllEvent = (rankType.value === "TOTAL_DAYS" || rankType.value === "TOTAL_COUNT")
|
||||||
|
&& (!eventFilter.value.length || eventFilter.value.length === eventList.value.length);
|
||||||
return {
|
return {
|
||||||
beginAt,
|
beginAt,
|
||||||
endAt,
|
endAt,
|
||||||
@@ -387,6 +427,19 @@ function parseEventIdList(value: unknown): string[] {
|
|||||||
return text.split(",").map(item => item.trim()).filter(Boolean);
|
return text.split(",").map(item => item.trim()).filter(Boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizeEventFilter(): boolean {
|
||||||
|
const eventIdSet = new Set(selectableEventList.value.map(item => item.id).filter((item): item is string => Boolean(item)));
|
||||||
|
let nextEventIdList = eventFilter.value.filter(item => eventIdSet.has(item));
|
||||||
|
if (!nextEventIdList.length) {
|
||||||
|
nextEventIdList = [...eventIdSet];
|
||||||
|
}
|
||||||
|
const changed = nextEventIdList.join(",") !== eventFilter.value.join(",");
|
||||||
|
if (changed) {
|
||||||
|
eventFilter.value = nextEventIdList;
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
function buildFilterQuery(): Record<string, string> {
|
function buildFilterQuery(): Record<string, string> {
|
||||||
return {
|
return {
|
||||||
rankType: rankType.value,
|
rankType: rankType.value,
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export type EventRecordRankPage = {
|
|||||||
endAt?: number;
|
endAt?: number;
|
||||||
} & BasePage;
|
} & BasePage;
|
||||||
|
|
||||||
export type EventRecordRankType = "TOTAL_DAYS" | "TOTAL_COUNT" | "CONTINUOUS_DAYS";
|
export type EventRecordRankType = "TOTAL_DAYS" | "TOTAL_COUNT" | "CONTINUOUS_DAYS" | "TOTAL_NUMBER_VALUE";
|
||||||
|
|
||||||
export type CustomerEventRankView = {
|
export type CustomerEventRankView = {
|
||||||
rank?: number;
|
rank?: number;
|
||||||
@@ -62,6 +62,7 @@ export type CustomerEventRankView = {
|
|||||||
totalEventDays?: number;
|
totalEventDays?: number;
|
||||||
totalEventCount?: number;
|
totalEventCount?: number;
|
||||||
recentContinuousEventDays?: number;
|
recentContinuousEventDays?: number;
|
||||||
|
totalNumberValue?: number;
|
||||||
latestRegisteredAt?: number;
|
latestRegisteredAt?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user