diff --git a/src/views/activity/gift-challenge/index.vue b/src/views/activity/gift-challenge/index.vue index d9c2d8c..a5d9b42 100644 --- a/src/views/activity/gift-challenge/index.vue +++ b/src/views/activity/gift-challenge/index.vue @@ -97,7 +97,21 @@ type="warning" :closable="false" show-icon - title="活动已经开始:仅名称和说明可修改;时间、榜单容量、结算窗口、任务和奖励均被服务端锁定。" + title="总榜已进入结算:仅名称和说明可修改;时间、榜单容量、结算窗口、任务和奖励均已冻结。" + /> + +
基础活动配置
@@ -622,9 +636,27 @@ export default { if (!this.form.id) { return false } - // 后端返回的活动状态和 serverTime 是锁定判断基准,不能依赖运营电脑的本地时间绕开规则冻结。 + // 活动时间只决定事件是否计分,不再决定配置能否修改。只有总榜结算开始后, + // 历史快照和发奖批次才成为不可变事实,此时才锁住核心配置。 + return this.form.overallSettlementStatus !== 'NOT_STARTED' + }, + activeEditable() { + if (!this.form.id || !this.form.enabled || this.startedLocked) { + return false + } + // 优先使用服务端活动状态;serverTime 只作为旧接口未返回状态时的兼容判断, + // 避免运营电脑时钟偏差导致活动提示与服务端实际时间窗不一致。 return ['ACTIVE', 'ENDED'].indexOf(this.backendActivityStatus) >= 0 || - (this.serverTime > 0 && this.originalStartTime > 0 && this.serverTime >= this.originalStartTime) + (!this.backendActivityStatus && this.serverTime > 0 && this.originalStartTime > 0 && + this.serverTime >= this.originalStartTime) + }, + editableDisabledDraft() { + return Boolean(this.form.id) && !this.form.enabled && + this.form.overallSettlementStatus === 'NOT_STARTED' + }, + expiredDisabledDraft() { + return this.editableDisabledDraft && this.serverTime > 0 && this.originalStartTime > 0 && + this.serverTime >= this.originalStartTime }, editorReadOnly() { return !this.canEdit || this.startedLocked @@ -647,6 +679,7 @@ export default { overallSettlementDelayMinutes: 30, displayTopN: 100, enabled: false, + overallSettlementStatus: 'NOT_STARTED', version: null, tasks: this.emptyTasks(), dailyRankRewards: [this.emptyRankReward(PERIOD_DAILY, 1)], @@ -781,7 +814,8 @@ export default { } const payload = this.buildSavePayload() this.saveLoading = true - // 新建或开始前编辑采用聚合保存,基础配置、三个任务和两类排行奖励由后端事务一次提交,避免半套配置被启用。 + // 总榜结算前始终聚合保存基础配置、三个任务和两类排行奖励;服务端会保留已经 + // 物化或冻结的历史事实,仅让新配置作用于后续事件,避免活动中编辑造成半套配置。 saveAslanGiftChallengeActivity(payload).then(() => { this.$message.success('礼物挑战配置已保存') this.editorVisible = false @@ -810,7 +844,7 @@ export default { this.$message.error('日榜和总榜晚到窗口必须是 0 到 1440 的整数分钟') return false } - // 统计开始后后端要求 tasks/rankRewards 完全不出现在请求中;这里只校验仍允许修改的基础字段。 + // 总榜开始结算后服务端要求 tasks/rankRewards 不再出现在请求中;名称和说明仍可单独维护。 if (this.startedLocked) { return true }