feat: align gift challenge editing rules
This commit is contained in:
parent
8cc2614fb3
commit
8e2e3feaca
@ -97,7 +97,21 @@
|
||||
type="warning"
|
||||
:closable="false"
|
||||
show-icon
|
||||
title="活动已经开始:仅名称和说明可修改;时间、榜单容量、结算窗口、任务和奖励均被服务端锁定。"
|
||||
title="总榜已进入结算:仅名称和说明可修改;时间、榜单容量、结算窗口、任务和奖励均已冻结。"
|
||||
/>
|
||||
<el-alert
|
||||
v-else-if="activeEditable"
|
||||
type="info"
|
||||
:closable="false"
|
||||
show-icon
|
||||
title="活动已进入或经过时间窗,但总榜尚未结算,全部配置仍可编辑。新配置只影响后续事件和尚未物化或冻结的任务、榜奖;历史积分、已生成任务、已冻结榜单和发奖记录不回算。历史数据已引用的同一奖励资源组继续使用旧快照,如需修改奖励内容请更换为新资源组。"
|
||||
/>
|
||||
<el-alert
|
||||
v-else-if="expiredDisabledDraft"
|
||||
type="info"
|
||||
:closable="false"
|
||||
show-icon
|
||||
title="该活动未启用且尚未结算,虽然原开始时间已过,仍可编辑全部配置;启用前请把活动时间调整到未来。"
|
||||
/>
|
||||
|
||||
<div class="section-title">基础活动配置</div>
|
||||
@ -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
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user