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
}