diff --git a/src/views/activity/game-king/index.vue b/src/views/activity/game-king/index.vue index 3bbe0ff..f4ef1b4 100644 --- a/src/views/activity/game-king/index.vue +++ b/src/views/activity/game-king/index.vue @@ -38,7 +38,8 @@ @@ -157,6 +158,20 @@ /> + + + +
按活动时区自然日封顶;超出部分仍计入两个榜单,但不再增加抽奖次数。
+
+
- - + + @@ -245,14 +260,21 @@
当前总权重:{{ totalPrizeWeight }}
-
排行榜结算奖励(固定六档)
+
排行榜结算奖励(每个榜单固定六档)
+ + + + + + - - + + @@ -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 '-'