灵仙游戏
This commit is contained in:
parent
7aed3ce16d
commit
c35af900cd
@ -91,6 +91,15 @@ export async function saveSpecifiedGiftWeeklyRankConfig(data: Record<string, any
|
||||
return requestClient.post(`${SPECIFIED_GIFT_WEEKLY_RANK_BASE}/config/save`, data);
|
||||
}
|
||||
|
||||
export async function getSpecifiedGiftWeeklyRankCurrentRank(
|
||||
params: Record<string, any>,
|
||||
) {
|
||||
return requestClient.get<Record<string, any>>(
|
||||
`${SPECIFIED_GIFT_WEEKLY_RANK_BASE}/current-rank`,
|
||||
{ params },
|
||||
);
|
||||
}
|
||||
|
||||
export async function pageSpecifiedGiftWeeklyRankSnapshots(params: Record<string, any>) {
|
||||
return requestClient.get<LegacyPageResult<Record<string, any>>>(
|
||||
`${SPECIFIED_GIFT_WEEKLY_RANK_BASE}/snapshot/page`,
|
||||
|
||||
@ -58,6 +58,10 @@ const profileOptions = [
|
||||
{ label: '正式环境', value: 'PROD' },
|
||||
{ label: '测试环境', value: 'TEST' },
|
||||
];
|
||||
const importShowcaseOptions = [
|
||||
{ label: '默认上架', value: true as any },
|
||||
{ label: '默认下架', value: false as any },
|
||||
];
|
||||
|
||||
const contextQuery = reactive({ profile: 'PROD', sysOrigin: '' });
|
||||
const providerForm = reactive(createProviderForm());
|
||||
@ -77,6 +81,7 @@ const totalCatalog = ref(0);
|
||||
const catalogList = ref<Array<Record<string, any>>>([]);
|
||||
const selectedCatalogKeys = ref<Array<number>>([]);
|
||||
const activeProfile = ref('PROD');
|
||||
const importDefaultShowcase = ref(true as any);
|
||||
|
||||
const isCurrentProfileActive = computed(
|
||||
() => activeProfile.value === contextQuery.profile,
|
||||
@ -308,6 +313,7 @@ async function handleImportSelected() {
|
||||
profile: contextQuery.profile,
|
||||
sysOrigin: contextQuery.sysOrigin,
|
||||
vendorGameIds: selectedCatalogKeys.value,
|
||||
defaultShowcase: importDefaultShowcase.value,
|
||||
});
|
||||
selectedCatalogKeys.value = [];
|
||||
message.success(
|
||||
@ -452,6 +458,11 @@ async function handleImportSelected() {
|
||||
<Button :loading="catalogFetching" @click="handleFetchCatalog">
|
||||
重新获取目录
|
||||
</Button>
|
||||
<Select
|
||||
v-model:value="importDefaultShowcase"
|
||||
:options="importShowcaseOptions"
|
||||
style="width: 120px"
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
:loading="catalogImporting"
|
||||
|
||||
@ -102,6 +102,10 @@ const showcaseOptions = [
|
||||
{ label: '上架', value: 'true' as any },
|
||||
{ label: '下架', value: 'false' as any },
|
||||
];
|
||||
const importShowcaseOptions = [
|
||||
{ label: '默认上架', value: true as any },
|
||||
{ label: '默认下架', value: false as any },
|
||||
];
|
||||
const clientOriginOptions = GAME_CLIENT_ORIGIN_OPTIONS.map((item) => ({
|
||||
label: item.name,
|
||||
value: item.value as any,
|
||||
@ -158,6 +162,7 @@ const modalOpen = ref(false);
|
||||
const gameList = ref<Array<Record<string, any>>>([]);
|
||||
const catalogList = ref<Array<Record<string, any>>>([]);
|
||||
const selectedCatalogKeys = ref<Array<number>>([]);
|
||||
const importDefaultShowcase = ref(true as any);
|
||||
const gameForm = reactive<Record<string, any>>(createGameForm());
|
||||
const providerForm = reactive<Record<string, any>>(createProviderForm());
|
||||
|
||||
@ -439,6 +444,7 @@ async function handleImportSelected() {
|
||||
const result = await importBaishunCatalog({
|
||||
sysOrigin: contextQuery.sysOrigin,
|
||||
vendorGameIds: selectedCatalogKeys.value,
|
||||
defaultShowcase: importDefaultShowcase.value,
|
||||
});
|
||||
selectedCatalogKeys.value = [];
|
||||
message.success(
|
||||
@ -629,6 +635,11 @@ async function handleImportSelected() {
|
||||
<Button :loading="catalogFetching" @click="handleFetchCatalog">
|
||||
重新获取目录
|
||||
</Button>
|
||||
<Select
|
||||
v-model:value="importDefaultShowcase"
|
||||
:options="importShowcaseOptions"
|
||||
style="width: 120px"
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
:loading="catalogImporting"
|
||||
|
||||
@ -40,6 +40,7 @@ function createProviderForm(sysOrigin = '') {
|
||||
gameListUrl: defaultGameListUrl,
|
||||
profile: 'PROD',
|
||||
sysOrigin,
|
||||
testRoomId: '',
|
||||
testToken: '',
|
||||
testUid: '',
|
||||
};
|
||||
@ -54,6 +55,10 @@ const profileOptions = [
|
||||
{ label: '正式环境', value: 'PROD' },
|
||||
{ label: '测试环境', value: 'TEST' },
|
||||
];
|
||||
const importShowcaseOptions = [
|
||||
{ label: '默认上架', value: true as any },
|
||||
{ label: '默认下架', value: false as any },
|
||||
];
|
||||
|
||||
const contextQuery = reactive({ profile: 'PROD', sysOrigin: '' });
|
||||
const providerForm = reactive(createProviderForm());
|
||||
@ -73,6 +78,7 @@ const totalCatalog = ref(0);
|
||||
const catalogList = ref<Array<Record<string, any>>>([]);
|
||||
const selectedCatalogKeys = ref<Array<string>>([]);
|
||||
const activeProfile = ref('PROD');
|
||||
const importDefaultShowcase = ref(true as any);
|
||||
|
||||
const isCurrentProfileActive = computed(
|
||||
() => activeProfile.value === contextQuery.profile,
|
||||
@ -258,6 +264,7 @@ async function handleImportSelected() {
|
||||
profile: contextQuery.profile,
|
||||
sysOrigin: contextQuery.sysOrigin,
|
||||
vendorGameIds: selectedCatalogKeys.value,
|
||||
defaultShowcase: importDefaultShowcase.value,
|
||||
});
|
||||
selectedCatalogKeys.value = [];
|
||||
message.success(
|
||||
@ -315,6 +322,9 @@ async function handleImportSelected() {
|
||||
type="password"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="RoomID">
|
||||
<Input v-model:value="providerForm.testRoomId" placeholder="可选" />
|
||||
</FormItem>
|
||||
</div>
|
||||
</CollapsePanel>
|
||||
</Collapse>
|
||||
@ -357,6 +367,11 @@ async function handleImportSelected() {
|
||||
<Button :loading="catalogFetching" @click="handleFetchCatalog">
|
||||
重新获取目录
|
||||
</Button>
|
||||
<Select
|
||||
v-model:value="importDefaultShowcase"
|
||||
:options="importShowcaseOptions"
|
||||
style="width: 120px"
|
||||
/>
|
||||
<Button
|
||||
type="primary"
|
||||
:loading="catalogImporting"
|
||||
|
||||
@ -6,6 +6,7 @@ import { useAccessStore } from '@vben/stores';
|
||||
|
||||
import { listGiftBySysOrigin } from '#/api/legacy/gift';
|
||||
import {
|
||||
getSpecifiedGiftWeeklyRankCurrentRank,
|
||||
getSpecifiedGiftWeeklyRankConfig,
|
||||
pageSpecifiedGiftWeeklyRankConfigs,
|
||||
pageSpecifiedGiftWeeklyRankRewardRecords,
|
||||
@ -103,6 +104,26 @@ const rewardLoading = ref(false);
|
||||
const rewardTotal = ref(0);
|
||||
const rewardList = ref<Array<Record<string, any>>>([]);
|
||||
|
||||
const rankLoading = ref(false);
|
||||
const rankList = ref<Array<Record<string, any>>>([]);
|
||||
const rankMeta = reactive<{
|
||||
activityStatus: string;
|
||||
configId: string;
|
||||
cycleKey: string;
|
||||
giftConfigs: Array<Record<string, any>>;
|
||||
periodEndAt: string;
|
||||
periodStartAt: string;
|
||||
timezone: string;
|
||||
}>({
|
||||
activityStatus: '',
|
||||
configId: '',
|
||||
cycleKey: '',
|
||||
giftConfigs: [],
|
||||
periodEndAt: '',
|
||||
periodStartAt: '',
|
||||
timezone: 'Asia/Riyadh',
|
||||
});
|
||||
|
||||
const form = reactive<Record<string, any>>(createEmptyForm());
|
||||
|
||||
const configQuery = reactive({
|
||||
@ -125,6 +146,10 @@ const rewardQuery = reactive({
|
||||
status: '',
|
||||
});
|
||||
|
||||
const rankQuery = reactive({
|
||||
limit: 20,
|
||||
});
|
||||
|
||||
const rewardStatusOptions = [
|
||||
{ label: '成功', value: 'SUCCESS' },
|
||||
{ label: '失败', value: 'FAILED' },
|
||||
@ -155,6 +180,13 @@ const snapshotColumns = [
|
||||
{ dataIndex: 'period', key: 'period', title: '结算区间', width: 320 },
|
||||
];
|
||||
|
||||
const rankColumns = [
|
||||
{ dataIndex: 'rank', key: 'rank', title: '名次', width: 90 },
|
||||
{ dataIndex: 'user', key: 'user', title: '用户', width: 280 },
|
||||
{ dataIndex: 'countryName', key: 'countryName', title: '国家', width: 150 },
|
||||
{ dataIndex: 'scoreGold', key: 'scoreGold', title: '当前金币积分', width: 160 },
|
||||
];
|
||||
|
||||
const rewardColumns = [
|
||||
{ dataIndex: 'cycleKey', key: 'cycleKey', title: '周期', width: 140 },
|
||||
{ dataIndex: 'rank', key: 'rank', title: '名次', width: 90 },
|
||||
@ -301,6 +333,39 @@ async function loadConfigDetail(id: number | string) {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadCurrentRank() {
|
||||
if (!selectedSysOrigin.value) {
|
||||
rankList.value = [];
|
||||
Object.assign(rankMeta, {
|
||||
activityStatus: '',
|
||||
configId: '',
|
||||
cycleKey: '',
|
||||
giftConfigs: [],
|
||||
periodEndAt: '',
|
||||
periodStartAt: '',
|
||||
timezone: 'Asia/Riyadh',
|
||||
});
|
||||
return;
|
||||
}
|
||||
rankLoading.value = true;
|
||||
try {
|
||||
const result = await getSpecifiedGiftWeeklyRankCurrentRank({
|
||||
limit: rankQuery.limit,
|
||||
sysOrigin: selectedSysOrigin.value,
|
||||
});
|
||||
rankList.value = Array.isArray(result.records) ? result.records : [];
|
||||
rankMeta.activityStatus = String(result.activityStatus || '');
|
||||
rankMeta.configId = String(result.configId || '');
|
||||
rankMeta.cycleKey = String(result.cycleKey || '');
|
||||
rankMeta.giftConfigs = Array.isArray(result.giftConfigs) ? result.giftConfigs : [];
|
||||
rankMeta.periodEndAt = String(result.periodEndAt || '');
|
||||
rankMeta.periodStartAt = String(result.periodStartAt || '');
|
||||
rankMeta.timezone = String(result.timezone || 'Asia/Riyadh');
|
||||
} finally {
|
||||
rankLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadSnapshots(reset = false) {
|
||||
if (!selectedSysOrigin.value) {
|
||||
snapshotList.value = [];
|
||||
@ -346,7 +411,12 @@ async function loadRewardRecords(reset = false) {
|
||||
}
|
||||
|
||||
async function reloadPageData() {
|
||||
await Promise.all([loadConfigList(true), loadSnapshots(true), loadRewardRecords(true)]);
|
||||
await Promise.all([
|
||||
loadConfigList(true),
|
||||
loadCurrentRank(),
|
||||
loadSnapshots(true),
|
||||
loadRewardRecords(true),
|
||||
]);
|
||||
}
|
||||
|
||||
function syncGiftSelection(slot: Record<string, any>, giftId: number | string | undefined) {
|
||||
@ -660,6 +730,74 @@ watch(
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Card :bordered="false" class="mt-16" title="当前排行榜">
|
||||
<Space class="toolbar" wrap>
|
||||
<Tag :color="statusColor(rankMeta.activityStatus)">
|
||||
{{ configStatusTextMap[rankMeta.activityStatus] || rankMeta.activityStatus || '未配置' }}
|
||||
</Tag>
|
||||
<Tag color="processing">{{ rankMeta.cycleKey || '-' }}</Tag>
|
||||
<Tag>{{ rankMeta.timezone || '-' }}</Tag>
|
||||
<span class="sub-text">
|
||||
{{ rankMeta.periodStartAt || '-' }} ~ {{ rankMeta.periodEndAt || '-' }}
|
||||
</span>
|
||||
<div class="tag-stack">
|
||||
<Tag
|
||||
v-for="item in rankMeta.giftConfigs"
|
||||
:key="`${rankMeta.configId}-${item.giftId}`"
|
||||
color="gold"
|
||||
>
|
||||
{{ item.giftName || item.giftId }}
|
||||
</Tag>
|
||||
</div>
|
||||
<Select
|
||||
v-model:value="rankQuery.limit"
|
||||
:options="[
|
||||
{ label: 'Top 20', value: 20 },
|
||||
{ label: 'Top 50', value: 50 },
|
||||
{ label: 'Top 100', value: 100 },
|
||||
]"
|
||||
style="width: 120px"
|
||||
@change="loadCurrentRank"
|
||||
/>
|
||||
<Button :loading="rankLoading" type="primary" @click="loadCurrentRank">
|
||||
刷新排行
|
||||
</Button>
|
||||
</Space>
|
||||
|
||||
<Table
|
||||
:columns="rankColumns"
|
||||
:data-source="rankList"
|
||||
:loading="rankLoading"
|
||||
:pagination="false"
|
||||
row-key="userId"
|
||||
:scroll="{ x: 680 }"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'user'">
|
||||
<div class="user-cell">
|
||||
<Image
|
||||
v-if="record.userAvatar"
|
||||
:preview="false"
|
||||
:src="record.userAvatar"
|
||||
class="avatar"
|
||||
/>
|
||||
<div v-else class="avatar placeholder">U</div>
|
||||
<div class="user-meta">
|
||||
<div>{{ record.userNickname || '-' }}</div>
|
||||
<div class="sub-text">
|
||||
{{ record.account || record.userId }}
|
||||
<span v-if="record.countryCode"> · {{ record.countryCode }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'countryName'">
|
||||
{{ record.countryName || record.countryCode || '-' }}
|
||||
</template>
|
||||
</template>
|
||||
</Table>
|
||||
</Card>
|
||||
|
||||
<Card :bordered="false" class="mt-16" title="上周快照">
|
||||
<Space class="toolbar" wrap>
|
||||
<Select
|
||||
|
||||
@ -274,7 +274,7 @@ INSERT INTO sys_menu (
|
||||
SELECT
|
||||
1700000256,
|
||||
(SELECT id FROM sys_menu WHERE alias = 'ResidentActivityManager' LIMIT 1),
|
||||
'指定礼物周榜',
|
||||
'周星',
|
||||
'resident-activity/week-star/index',
|
||||
2,
|
||||
'form',
|
||||
@ -299,7 +299,7 @@ SET
|
||||
LIMIT 1
|
||||
) AS resident_menu
|
||||
),
|
||||
menu_name = '指定礼物周榜',
|
||||
menu_name = '周星',
|
||||
path = 'resident-activity/week-star/index',
|
||||
menu_type = 2,
|
||||
icon = 'form',
|
||||
@ -482,7 +482,7 @@ SET menu_name = CONVERT(0xE98280E8AFB7E6B4BBE58AA8E58897E8A1A8 USING utf8mb4)
|
||||
WHERE alias = 'ResidentInviteList';
|
||||
|
||||
UPDATE sys_menu
|
||||
SET menu_name = CONVERT(0xE68C87E5AE9AE7A4BCE789A9E591A8E6A69C USING utf8mb4)
|
||||
SET menu_name = CONVERT(0xE591A8E6989F USING utf8mb4)
|
||||
WHERE alias = 'ResidentSpecifiedGiftWeeklyRank';
|
||||
|
||||
UPDATE sys_menu
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user