up值
This commit is contained in:
parent
e65f57f387
commit
7aed3ce16d
@ -40,7 +40,7 @@ const routes: RouteRecordRaw[] = [
|
||||
path: 'specified-gift-weekly-rank',
|
||||
alias: 'week-star',
|
||||
component: () => import('#/views/resident-activity/week-star.vue'),
|
||||
meta: { title: '指定礼物周榜' },
|
||||
meta: { title: '周星' },
|
||||
},
|
||||
{
|
||||
name: 'ResidentRoomTurnoverReward',
|
||||
|
||||
@ -48,6 +48,15 @@ const fullscreen = ref(false);
|
||||
const visualMode = ref(false);
|
||||
const loading = ref(false);
|
||||
const dashboard = ref<CountryDashboardResult | null>(null);
|
||||
const upDashboards = ref<{
|
||||
day: CountryDashboardResult | null;
|
||||
threeDay: CountryDashboardResult | null;
|
||||
week: CountryDashboardResult | null;
|
||||
}>({
|
||||
day: null,
|
||||
threeDay: null,
|
||||
week: null,
|
||||
});
|
||||
const dateRange = ref<[string, string] | null>([
|
||||
dayjs().subtract(6, 'day').format('YYYY-MM-DD'),
|
||||
dayjs().format('YYYY-MM-DD'),
|
||||
@ -220,7 +229,11 @@ const columns: any[] = [
|
||||
{ align: 'right', dataIndex: 'gamePayoutRate', key: 'gamePayoutRate', title: '游戏返奖率', width: 140 },
|
||||
{ align: 'right', dataIndex: 'gameProfit', key: 'gameProfit', title: '游戏利润', width: 130 },
|
||||
{ align: 'right', dataIndex: 'gameProfitRate', key: 'gameProfitRate', title: '游戏利润率', width: 140 },
|
||||
];
|
||||
].map((column) => ({
|
||||
...column,
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
sorter: compareTableColumn(String(column.dataIndex)),
|
||||
}));
|
||||
const tableScrollX = columns.reduce((totalWidth, item) => totalWidth + Number(item.width || 0), 0);
|
||||
|
||||
const rawRecords = computed(() => dashboard.value?.records || []);
|
||||
@ -238,11 +251,7 @@ const countryOptions = computed(() => {
|
||||
.toSorted((current, next) => current.label.localeCompare(next.label));
|
||||
});
|
||||
const records = computed(() => {
|
||||
const selected = new Set(selectedCountryCodes.value);
|
||||
if (selected.size === 0) {
|
||||
return rawRecords.value;
|
||||
}
|
||||
return rawRecords.value.filter((item) => selected.has(String(item.countryCode || '')));
|
||||
return filterRecordsBySelectedCountries(rawRecords.value);
|
||||
});
|
||||
const chartRecords = computed(() => records.value.filter((item) => item.countryCode !== 'ALL'));
|
||||
const visibleSummary = computed(() => buildVisibleSummary(records.value));
|
||||
@ -273,6 +282,14 @@ const appDataCards = computed(() => {
|
||||
{ label: '30 日留存率', value: formatPercent(summary.d30RetentionRate) },
|
||||
];
|
||||
});
|
||||
const upValueCards = computed(() => {
|
||||
return [
|
||||
{ label: '日 UP 值', value: formatUpValue(upDashboards.value.day) },
|
||||
{ label: '3 日 UP 值', value: formatUpValue(upDashboards.value.threeDay) },
|
||||
{ label: '周 UP 值', value: formatUpValue(upDashboards.value.week) },
|
||||
{ label: '筛选 UP 值', value: formatAmount(calcUpValue(visibleSummary.value)) },
|
||||
];
|
||||
});
|
||||
|
||||
function hasPermission(code: string) {
|
||||
const codes = accessCodes.value;
|
||||
@ -338,15 +355,43 @@ function buildParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
function buildRecentDayParams(dayCount: number) {
|
||||
const end = dayjs();
|
||||
const start = end.subtract(dayCount - 1, 'day');
|
||||
return {
|
||||
periodType: 'DAY',
|
||||
startDate: start.format('YYYY-MM-DD'),
|
||||
endDate: end.format('YYYY-MM-DD'),
|
||||
sysOrigin: query.sysOrigin || undefined,
|
||||
};
|
||||
}
|
||||
|
||||
async function loadDashboard() {
|
||||
if (!canQuery.value) {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
try {
|
||||
dashboard.value = await countryDashboard(buildParams());
|
||||
const [mainDashboard, dayUpDashboard, threeDayUpDashboard, weekUpDashboard] =
|
||||
await Promise.all([
|
||||
countryDashboard(buildParams()),
|
||||
countryDashboard(buildRecentDayParams(1)),
|
||||
countryDashboard(buildRecentDayParams(3)),
|
||||
countryDashboard(buildRecentDayParams(7)),
|
||||
]);
|
||||
dashboard.value = mainDashboard;
|
||||
upDashboards.value = {
|
||||
day: dayUpDashboard,
|
||||
threeDay: threeDayUpDashboard,
|
||||
week: weekUpDashboard,
|
||||
};
|
||||
} catch (error) {
|
||||
dashboard.value = null;
|
||||
upDashboards.value = {
|
||||
day: null,
|
||||
threeDay: null,
|
||||
week: null,
|
||||
};
|
||||
message.error('数据大屏加载失败');
|
||||
throw error;
|
||||
} finally {
|
||||
@ -450,6 +495,19 @@ function resolveMetricRate(record: Record<string, any>, key: string) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
function calcUpValue(summary: Record<string, any>) {
|
||||
const activeUser = toAmount(summary.dailyActiveUser);
|
||||
if (activeUser === 0) {
|
||||
return 0;
|
||||
}
|
||||
return toAmount(summary.totalRecharge) / activeUser;
|
||||
}
|
||||
|
||||
function formatUpValue(result?: CountryDashboardResult | null) {
|
||||
const summary = buildVisibleSummary(filterRecordsBySelectedCountries(result?.records || []));
|
||||
return formatAmount(calcUpValue(summary));
|
||||
}
|
||||
|
||||
function emptySummary(): SummaryMetric {
|
||||
return {
|
||||
countryNewUser: 0,
|
||||
@ -529,6 +587,29 @@ function tableCellText(record: Record<string, any>, key: string) {
|
||||
return formatAmount(record[key] as number | string);
|
||||
}
|
||||
|
||||
function compareTableColumn(key: string) {
|
||||
return (current: Record<string, any>, next: Record<string, any>) => {
|
||||
if (metricColumns.has(key)) {
|
||||
const currentValue = percentMetricColumns.has(key)
|
||||
? resolveMetricRate(current, key)
|
||||
: toAmount(current[key]);
|
||||
const nextValue = percentMetricColumns.has(key)
|
||||
? resolveMetricRate(next, key)
|
||||
: toAmount(next[key]);
|
||||
return currentValue - nextValue;
|
||||
}
|
||||
return String(current[key] || '').localeCompare(String(next[key] || ''));
|
||||
};
|
||||
}
|
||||
|
||||
function filterRecordsBySelectedCountries(list: CountryDashboardMetric[]) {
|
||||
const selected = new Set(selectedCountryCodes.value);
|
||||
if (selected.size === 0) {
|
||||
return list;
|
||||
}
|
||||
return list.filter((item) => selected.has(String(item.countryCode || '')));
|
||||
}
|
||||
|
||||
function rowKey(record: Record<string, any>) {
|
||||
return `${record.countryCode}-${record.periodKey}`;
|
||||
}
|
||||
@ -805,6 +886,19 @@ onBeforeUnmount(() => {
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="panel metric-section">
|
||||
<div class="metric-section__title">UP 值</div>
|
||||
<div class="metric-card-grid metric-card-grid--up">
|
||||
<div
|
||||
v-for="item in upValueCards"
|
||||
:key="item.label"
|
||||
class="metric-card"
|
||||
>
|
||||
<div class="metric-card__label">{{ item.label }}</div>
|
||||
<div class="metric-card__value">{{ item.value }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section class="panel summary-table-panel">
|
||||
@ -956,7 +1050,7 @@ onBeforeUnmount(() => {
|
||||
.metric-section-grid {
|
||||
display: grid;
|
||||
gap: 16px;
|
||||
grid-template-columns: minmax(0, 3fr) minmax(280px, 2fr);
|
||||
grid-template-columns: minmax(0, 3fr) minmax(260px, 2fr) minmax(260px, 2fr);
|
||||
}
|
||||
|
||||
.metric-section {
|
||||
@ -980,6 +1074,10 @@ onBeforeUnmount(() => {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.metric-card-grid--up {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.metric-card {
|
||||
background: #111827;
|
||||
border: 1px solid rgba(45, 212, 191, 0.18);
|
||||
@ -1096,7 +1194,8 @@ onBeforeUnmount(() => {
|
||||
|
||||
.metric-section-grid,
|
||||
.metric-card-grid,
|
||||
.metric-card-grid--app {
|
||||
.metric-card-grid--app,
|
||||
.metric-card-grid--up {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user