feat: configure dual game king rankings
This commit is contained in:
parent
36999097d8
commit
cc455ccfb8
@ -38,7 +38,8 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="抽奖门槛" min-width="125" align="right">
|
||||
<template slot-scope="scope">
|
||||
每 {{ formatNumber(scope.row.coinPerDraw) }} 金币
|
||||
<div>每 {{ formatNumber(scope.row.coinPerDraw) }} 金币</div>
|
||||
<div class="secondary-text">每日最多 {{ scope.row.dailyChanceLimit }} 次</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" min-width="130" align="center">
|
||||
@ -157,6 +158,20 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="每日最多获次数" prop="dailyChanceLimit">
|
||||
<el-input-number
|
||||
v-model="form.dailyChanceLimit"
|
||||
:min="1"
|
||||
:max="10000"
|
||||
:precision="0"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
:disabled="startedLocked"
|
||||
/>
|
||||
<div class="form-help">按活动时区自然日封顶;超出部分仍计入两个榜单,但不再增加抽奖次数。</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="结算等待(分钟)" prop="settlementDelayMinutes">
|
||||
<el-input-number
|
||||
@ -172,8 +187,8 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="排行口径">
|
||||
<el-input value="消费金币榜(TYCOON)" disabled />
|
||||
<el-form-item label="榜单配置">
|
||||
<el-input value="消耗榜(TYCOON)+ 中奖入账榜(VICTORIOUS)" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
@ -245,14 +260,21 @@
|
||||
</el-table>
|
||||
<div class="weight-summary">当前总权重:{{ totalPrizeWeight }}</div>
|
||||
|
||||
<div class="section-title">排行榜结算奖励(固定六档)</div>
|
||||
<div class="section-title">排行榜结算奖励(每个榜单固定六档)</div>
|
||||
<el-alert
|
||||
type="warning"
|
||||
:closable="false"
|
||||
show-icon
|
||||
title="名次范围不可增删或修改;活动结束后按最终消费榜快照结算,失败记录可在结算记录中单独重试。"
|
||||
title="消费榜和中奖榜分别配置六档奖励;名次范围不可增删或修改,失败记录可在结算记录中单独重试。"
|
||||
/>
|
||||
<el-table :data="form.rankRewards" border class="config-table">
|
||||
<el-table-column label="榜单" width="110" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.rankingType === 'VICTORIOUS' ? 'warning' : 'primary'">
|
||||
{{ rankingTypeText(scope.row.rankingType) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="名次范围" width="130" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag type="success">{{ rankRangeText(scope.row) }}</el-tag>
|
||||
@ -346,10 +368,17 @@
|
||||
</el-table>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="榜单" width="110" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="scope.row.rankingType === 'VICTORIOUS' ? 'warning' : 'primary'">
|
||||
{{ rankingTypeText(scope.row.rankingType) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="名次" width="70" align="center" prop="rank" />
|
||||
<el-table-column label="用户 ID" min-width="160" prop="userId" />
|
||||
<el-table-column label="消费金币" min-width="120" align="right">
|
||||
<template slot-scope="scope">{{ formatNumber(scope.row.totalConsumed) }}</template>
|
||||
<el-table-column label="榜单数值" min-width="120" align="right">
|
||||
<template slot-scope="scope">{{ formatNumber(scope.row.score === undefined ? scope.row.totalConsumed : scope.row.score) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="资源组" min-width="145" prop="resourceGroupId" />
|
||||
<el-table-column label="发放状态" width="110" align="center">
|
||||
@ -543,6 +572,7 @@ const REQUIRED_RANK_RANGES = [
|
||||
[8, 10],
|
||||
[11, 30]
|
||||
]
|
||||
const RANKING_TYPES = ['TYCOON', 'VICTORIOUS']
|
||||
|
||||
export default {
|
||||
name: 'ActivityGameKing',
|
||||
@ -619,6 +649,7 @@ export default {
|
||||
timeZone: 'Asia/Riyadh',
|
||||
timeRange: [],
|
||||
coinPerDraw: 1,
|
||||
dailyChanceLimit: 10,
|
||||
settlementDelayMinutes: 30,
|
||||
rankingType: 'TYCOON',
|
||||
rankingPeriod: 'OVERALL',
|
||||
@ -642,15 +673,18 @@ export default {
|
||||
}))
|
||||
},
|
||||
emptyRankRewards() {
|
||||
return REQUIRED_RANK_RANGES.map((range, index) => ({
|
||||
id: '',
|
||||
activityId: '',
|
||||
startRank: range[0],
|
||||
endRank: range[1],
|
||||
resourceGroupId: '',
|
||||
rewardName: index < 3 ? `Top ${index + 1} 奖励` : `Top ${range[0]}-${range[1]} 奖励`,
|
||||
rewards: []
|
||||
}))
|
||||
return RANKING_TYPES.reduce((result, rankingType) => result.concat(
|
||||
REQUIRED_RANK_RANGES.map((range, index) => ({
|
||||
id: '',
|
||||
activityId: '',
|
||||
rankingType,
|
||||
startRank: range[0],
|
||||
endRank: range[1],
|
||||
resourceGroupId: '',
|
||||
rewardName: index < 3 ? `Top ${index + 1} 奖励` : `Top ${range[0]}-${range[1]} 奖励`,
|
||||
rewards: []
|
||||
}))
|
||||
), [])
|
||||
},
|
||||
loadActivities() {
|
||||
this.listLoading = true
|
||||
@ -681,6 +715,8 @@ export default {
|
||||
timeZone: activity.timeZone || 'Asia/Riyadh',
|
||||
settlementDelayMinutes: activity.settlementDelayMinutes === null || activity.settlementDelayMinutes === undefined
|
||||
? 30 : Number(activity.settlementDelayMinutes),
|
||||
dailyChanceLimit: activity.dailyChanceLimit === null || activity.dailyChanceLimit === undefined
|
||||
? 10 : Number(activity.dailyChanceLimit),
|
||||
timeRange: [activity.startTime, activity.endTime],
|
||||
prizes,
|
||||
rankRewards
|
||||
@ -708,7 +744,13 @@ export default {
|
||||
mergeRankRewards(rankRewards) {
|
||||
const result = this.emptyRankRewards()
|
||||
rankRewards.forEach(item => {
|
||||
const index = REQUIRED_RANK_RANGES.findIndex(range => range[0] === Number(item.startRank) && range[1] === Number(item.endRank))
|
||||
// 榜单类型和名次区间共同定位配置,避免两个榜单的同一名次奖励相互覆盖。
|
||||
const rankingType = item.rankingType || 'TYCOON'
|
||||
const index = result.findIndex(target =>
|
||||
target.rankingType === rankingType &&
|
||||
target.startRank === Number(item.startRank) &&
|
||||
target.endRank === Number(item.endRank)
|
||||
)
|
||||
if (index >= 0) {
|
||||
result.splice(index, 1, Object.assign({}, result[index], item, {
|
||||
rewards: item.rewardItems || item.rewards || []
|
||||
@ -735,7 +777,7 @@ export default {
|
||||
}
|
||||
const payload = this.buildSavePayload()
|
||||
this.saveLoading = true
|
||||
// 基础配置、七个奖项与六档排行奖励一次提交,由后端事务保证不会保存出半套配置。
|
||||
// 基础配置、七个奖项与两个榜单各六档奖励一次提交,由后端事务保证不会保存出半套配置。
|
||||
saveAslanGameKingActivity(payload).then(() => {
|
||||
this.$message.success('活动配置已保存')
|
||||
this.editorVisible = false
|
||||
@ -755,6 +797,10 @@ export default {
|
||||
this.$message.error('每次抽奖金币数必须是大于 0 的安全整数')
|
||||
return false
|
||||
}
|
||||
if (!Number.isSafeInteger(Number(this.form.dailyChanceLimit)) || Number(this.form.dailyChanceLimit) < 1 || Number(this.form.dailyChanceLimit) > 10000) {
|
||||
this.$message.error('每日最多获得次数必须是 1 到 10000 的整数')
|
||||
return false
|
||||
}
|
||||
if (!Number.isInteger(Number(this.form.settlementDelayMinutes)) ||
|
||||
Number(this.form.settlementDelayMinutes) < 0 || Number(this.form.settlementDelayMinutes) > 1440) {
|
||||
this.$message.error('结算等待必须是 0 到 1440 的整数分钟')
|
||||
@ -777,14 +823,15 @@ export default {
|
||||
this.$message.error('请补全 7 个奖项的名称、图片、正整数权重、合法库存和奖励资源组')
|
||||
return false
|
||||
}
|
||||
const rangesValid = this.form.rankRewards.length === REQUIRED_RANK_RANGES.length &&
|
||||
const rangesValid = this.form.rankRewards.length === REQUIRED_RANK_RANGES.length * RANKING_TYPES.length &&
|
||||
this.form.rankRewards.every((item, index) =>
|
||||
Number(item.startRank) === REQUIRED_RANK_RANGES[index][0] &&
|
||||
Number(item.endRank) === REQUIRED_RANK_RANGES[index][1] &&
|
||||
item.rankingType === RANKING_TYPES[Math.floor(index / REQUIRED_RANK_RANGES.length)] &&
|
||||
Number(item.startRank) === REQUIRED_RANK_RANGES[index % REQUIRED_RANK_RANGES.length][0] &&
|
||||
Number(item.endRank) === REQUIRED_RANK_RANGES[index % REQUIRED_RANK_RANGES.length][1] &&
|
||||
Boolean(item.resourceGroupId)
|
||||
)
|
||||
if (!rangesValid) {
|
||||
this.$message.error('六档名次范围必须保持固定,并为每档选择奖励资源组')
|
||||
this.$message.error('两个榜单的六档名次范围必须保持固定,并为每档选择奖励资源组')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@ -802,6 +849,7 @@ export default {
|
||||
endTime: Number(this.form.timeRange[1]),
|
||||
settlementDelayMinutes: Number(this.form.settlementDelayMinutes),
|
||||
coinPerDraw: Number(this.form.coinPerDraw),
|
||||
dailyChanceLimit: Number(this.form.dailyChanceLimit),
|
||||
rankingType: 'TYCOON',
|
||||
rankingPeriod: 'OVERALL',
|
||||
enabled: Boolean(this.form.enabled)
|
||||
@ -821,6 +869,7 @@ export default {
|
||||
payload.rankRewards = this.form.rankRewards.map(item => ({
|
||||
id: item.id || null,
|
||||
activityId: this.form.id || null,
|
||||
rankingType: item.rankingType,
|
||||
startRank: Number(item.startRank),
|
||||
endRank: Number(item.endRank),
|
||||
resourceGroupId: String(item.resourceGroupId),
|
||||
@ -1051,6 +1100,9 @@ export default {
|
||||
rankRangeText(row) {
|
||||
return row.startRank === row.endRank ? `Top ${row.startRank}` : `Top ${row.startRank}-${row.endRank}`
|
||||
},
|
||||
rankingTypeText(rankingType) {
|
||||
return rankingType === 'VICTORIOUS' ? '中奖榜' : '消耗榜'
|
||||
},
|
||||
formatTime(value) {
|
||||
if (!value) {
|
||||
return '-'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user