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