[积分商城]PlayX对接中心
This commit is contained in:
8
web/src/lang/backend/en/mall/playxCenter.ts
Normal file
8
web/src/lang/backend/en/mall/playxCenter.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export default {
|
||||
title: 'PlayX Integration Center',
|
||||
desc: 'Manage orders, daily push, claim logs and user assets in one place.',
|
||||
orders: 'Orders',
|
||||
dailyPush: 'Daily Push',
|
||||
claimLog: 'Claim Log',
|
||||
userAsset: 'User Asset',
|
||||
}
|
||||
9
web/src/lang/backend/zh-cn/mall/playxCenter.ts
Normal file
9
web/src/lang/backend/zh-cn/mall/playxCenter.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export default {
|
||||
title: 'PlayX 对接中心',
|
||||
desc: '集中管理积分商城与 PlayX 的订单、推送、领取与资产数据。建议优先处理“发放子状态=失败可重试”的订单。',
|
||||
orders: '统一订单',
|
||||
dailyPush: '每日推送',
|
||||
claimLog: '领取记录',
|
||||
userAsset: '用户资产',
|
||||
}
|
||||
|
||||
102
web/src/views/backend/mall/playxCenter/index.vue
Normal file
102
web/src/views/backend/mall/playxCenter/index.vue
Normal file
@@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<!-- 语言包注入是异步的:把 t() 调用和子组件渲染都延后到注入完成后,避免 intlify Not found -->
|
||||
<template v-if="langReady">
|
||||
<el-card shadow="never" class="mb-4">
|
||||
<template #header>
|
||||
<div class="card-header">{{ t('mall.playxCenter.title') }}</div>
|
||||
</template>
|
||||
<div class="desc">{{ t('mall.playxCenter.desc') }}</div>
|
||||
</el-card>
|
||||
|
||||
<el-tabs v-model="activeName" type="border-card">
|
||||
<el-tab-pane :label="t('mall.playxCenter.orders')" name="orders">
|
||||
<PlayxOrderIndex />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="t('mall.playxCenter.dailyPush')" name="dailyPush">
|
||||
<PlayxDailyPushIndex />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="t('mall.playxCenter.claimLog')" name="claimLog">
|
||||
<PlayxClaimLogIndex />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="t('mall.playxCenter.userAsset')" name="userAsset">
|
||||
<PlayxUserAssetIndex />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import PlayxOrderIndex from '/@/views/backend/mall/playxOrder/index.vue'
|
||||
import PlayxDailyPushIndex from '/@/views/backend/mall/playxDailyPush/index.vue'
|
||||
import PlayxClaimLogIndex from '/@/views/backend/mall/playxClaimLog/index.vue'
|
||||
import PlayxUserAssetIndex from '/@/views/backend/mall/playxUserAsset/index.vue'
|
||||
import { useConfig } from '/@/stores/config'
|
||||
import { mergeMessage } from '/@/lang/index'
|
||||
|
||||
defineOptions({
|
||||
name: 'mall/playxCenter',
|
||||
})
|
||||
|
||||
const { t } = useI18n()
|
||||
const activeName = ref('orders')
|
||||
const langReady = ref(false)
|
||||
|
||||
/**
|
||||
* 由于语言包是按“路由”懒加载的:
|
||||
* playxCenter 内部直接渲染了多个子页面组件(订单/推送/领取/资产),
|
||||
* 如果对应菜单被禁用,子页面路由可能不会触发语言包加载,导致 t('mall.playx*') 显示为 key。
|
||||
* 关键点:子页面组件在首次渲染阶段就会执行 t()。
|
||||
* 因此语言包需要在首次渲染前(而不是 onMounted)完成 merge。
|
||||
*/
|
||||
async function ensurePlayxCenterLang() {
|
||||
const config = useConfig()
|
||||
const locale = config.lang.defaultLang
|
||||
const prefix = `./backend/${locale}`
|
||||
|
||||
const loadPaths = [
|
||||
`${prefix}/mall/playxCenter.ts`,
|
||||
`${prefix}/mall/playxOrder.ts`,
|
||||
`${prefix}/mall/playxDailyPush.ts`,
|
||||
`${prefix}/mall/playxClaimLog.ts`,
|
||||
`${prefix}/mall/playxUserAsset.ts`,
|
||||
]
|
||||
|
||||
// 某些场景下 i18n 初始化可能晚于组件创建,这里做一次最小等待。
|
||||
// 不会阻塞很久:通常 window.loadLangHandle 会在应用启动阶段就准备好。
|
||||
while (!window.loadLangHandle) {
|
||||
await new Promise((r) => setTimeout(r, 0))
|
||||
}
|
||||
|
||||
const handleMap = window.loadLangHandle
|
||||
for (const p of loadPaths) {
|
||||
const loader = handleMap[p]
|
||||
if (!loader) continue
|
||||
const mod = await loader()
|
||||
// 与 getLangFileMessage 的命名规则一致:namespace 应为 `mall/playxOrder` 这类路径
|
||||
const pathName = p.slice(p.lastIndexOf(prefix) + (prefix.length + 1), p.lastIndexOf('.'))
|
||||
mergeMessage(mod?.default ?? {}, pathName)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await ensurePlayxCenterLang()
|
||||
langReady.value = true
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mb-4 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.card-header {
|
||||
font-weight: 600;
|
||||
}
|
||||
.desc {
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user