活动互斥策略 / Campaign Mutex Strategy · PRD v1.11

活动互斥策略 · PRD

作者 Luke 版本 v1.11 日期 2026-09-14 状态 进行中 平台 BRAND_A & BRAND_B 类 K

版本记录
版本 日期 变更说明
v1.11 2026-09-14 §1.4 明订创建时间只在首次新增成功时写入;编辑、启用、关闭、删除与自动到期均不得改写。
v1.10 2026-09-11 L0 明写策略2在同一主周期凭证内重复领取同一活动也阻挡;§1.4 把到期日写成含生效日的自然日公式;§1.2 重申策略2在添加与提交两处校验相同模板及相同主周期。
v1.9 2026-09-11 §4.2 补齐后台中英文提示语,供中英并列原型与英文 PRD 网页共用;业务规则不变。
v1.8 2026-09-11 §2.2 扩展手动领取与自动派发的互斥顺序;§1.3 改为带入完整 AID 清单后增删并刷新明细;收短全文,并补资讯图表。
v1.7 2026-09-02 §4.2 补齐备注未填提示语。
v1.6 2026-09-01 §4.2 后台提示语定稿。
v1.5 2026-08-17 §5 补策略唯一键待确认项,并重整验收标准。
v1.0 2026-08-10 §1 新增策略2、平台渠道前置校验与活动过滤。
目录

L0 · 快速掌握

活动互斥策略 · 一页式资讯图表

① 一句话需求

在「活动管理 > 活动互斥策略」配置互斥活动组。玩家通过手动领取或自动派发取得组内任一活动奖金后,策略1阻挡同组其他活动;策略2在同一主周期凭证内连同本活动的再次领取也阻挡。

② 术语写死表

词 本文唯一含义
AID/活动ID 活动主数据的唯一编号;同一编号跨 BRAND 不重复
领取成功 奖金已成功入账;达标未领、派发失败与撤销记录都不算
派发入口 手动领取=玩家点击领取;自动派发=排程或脚本代替玩家触发派奖
凭证 当前活动主周期实例;只用于策略2
互斥周期 本条策略的生效时长,不是活动本身的运行周期

③ 全局红线表

# 不变量 破了会怎样 验证
G1 只认成功入账记录 达标未领或失败记录会误挡后续活动 AC1
G2 同一用户、同一命中策略内,手动与自动共用同一套互斥判定;先成功入账者保留,后到者不得派发 同组活动可能重复派发 AC2 AC3 AC4
G3 自动脚本必须在派发前判定;命中互斥时跳过该用户 脚本会绕过手动领取的互斥结果 AC2 AC5
G4 判定与入账必须在同一事务与并发保护内 两个同时到达的请求可能都成功 AC4 AC16
G5 每条命中策略独立判定,任一条拦截即整体拦截 重叠策略会漏拦 AC11
G6 策略只作用于同 BRAND 用户与活动 跨 BRAND 数据会互相影响 AC12
G7 配置读取失败时不得派发,也不得留下永久互斥记录 系统异常会造成超发或永久误挡 AC15

④ 范围

本期做

  1. 互斥策略的新增、编辑、查询、启用、关闭、删除与导出(§1)。
  2. 手动领取与自动派发前的互斥判定(§2)。
  3. 策略1按用户全局互斥;策略2按单次凭证互斥(§2.4–2.5)。
  4. 平台渠道前置校验、AID 过滤与编辑态完整清单操作(§1.1–1.3)。

明确不做

  1. 不改活动达标、算奖与入账规则(§2.1)。
  2. 不新增活动主数据或批量导入(§1)。
  3. 不新增玩家端页面,也不隐藏组内活动的领取按钮(§2.1)。
  4. 策略1再次领取锁定活动时,互斥层放行并交由既有幂等规则处理;策略2同凭证重复领取本活动仍由本需求阻挡(§2.4–2.5)。
  5. 不替自动派发脚本定义排程;只规定脚本处理到某用户时的互斥结果(§2.2)。
  6. 客服补发与后台人工补发不纳入本期(§2.1)。

1. 配置与编辑

1.1 表单字段

字段 规则
平台渠道 BRAND_A/BRAND_B,必填;编辑后不可改
策略方案 策略1/策略2,必填;编辑后不可改
策略名称 1–30 个常规字符;trim 首尾空格;拒绝零宽字符、emoji 与控制字符
互斥周期 1/3/5/10/11 天,或自定义 1–999 正整数;拒绝前导零、全角数字、小数、负数与空值
互斥活动ID 英文逗号分隔;至少 2 个;同一策略内重复 AID 静默去重
备注 1–200 个字符;写入管理员操作日志,不在列表展示

1.1.1 校验时机:只有「平台渠道」显示红色星号。未选平台渠道时点「添加」立即硬阻断;其余字段在提交时硬阻断。

1.1.2 并发编辑:两个运营同时编辑同一条策略时,后保存者覆盖先保存者,不做冲突提示。

1.2 AID 添加与过滤

1.2.1 过滤规则:点「添加」后,系统逐一查询输入框里的 AID,并将有效结果写入明细表。

输入 处理
对应当前平台且查得到 加入明细
非当前平台、无权限或查无 静默剔除
同一 AID 重复 静默去重,只留 1 笔
已过期或关闭的活动 可加入,显示实际状态

1.2.2 策略2前提:策略2另需满足「相同 template_id 且相同主周期」。添加时检查,提交时由后端再校验;策略1不做此限制。

1.3 新增与编辑操作

场景 输入框与「添加」行为
新增 运营输入 AID 清单;点「添加」后逐一校验,并以通过校验的完整清单刷新明细
编辑 进入页面时,输入框带入该策略当前全部 AID;明细同时显示当前活动
编辑时增加 在既有 AID 后追加新 AID,再点「添加」;系统逐一校验,并以输入框的完整清单刷新明细
编辑时删除 从输入框删除目标 AID,再点「添加」;明细移除该 AID

1.3.1 完整清单:「添加」不是只追加单笔。每次点击都以输入框当下的完整 AID 清单为准,校验后重建明细。点击后输入框保留已通过校验的完整清单,不自动清空。

1.3.2 编辑字段:平台渠道与策略方案在编辑态锁定。策略名称、互斥周期、AID 清单可修改。备注每次操作重新填写,不带入上次内容。

1.4 列表、状态与时间

列表栏位:ID|策略名称|活动ID|策略方案|用户渠道|状态|到期日|创建时间|修改时间|操作人|操作|查看

明细栏位:序号|活动ID|模板名称|活动名称|用户渠道|活动状态|开始时间|结束时间

事件 结果
新增策略 状态为「互斥中」;生效起点为提交成功时刻
到期 状态自动转为「已过期」
关闭/删除 立即停止互斥;到期日不变
启用 依原有效期,从启用时刻重起一轮;只更新到期日与修改时间,创建时间不变
修改有效期 从修改成功时刻重算到期日;只更新到期日与修改时间,创建时间不变
删除 软删留档;列表、筛选与导出均不可见;不可恢复

1.4.1 到期日:到期日覆盖含生效当日在内的 N 个自然日。计算式为「生效日期 +(N − 1)个日历日」的 23:59:59;不得以生效时刻直接加 N × 24 小时。

1.4.2 创建时间:只在首次新增成功时写入。编辑、启用、关闭、删除与自动到期均不得改写创建时间;这些操作只更新修改时间。启用或修改有效期时,另以该次操作成功时刻作为到期日的计算起点,不得借用或覆写创建时间栏位。

1.4.3 释放口径:策略关闭、删除或到期后,下一次判定立即不再命中。


2. 互斥判定

2.1 生效入口

2.1.1 判定入口:下列入口必须在入账前调用同一套互斥判定:

  1. 玩家点击领取。
  2. 自动派奖脚本处理该用户。

2.1.2 不判入口:活动达标、活动列表与详情展示不做判定。自动脚本不得因不是玩家点击而绕过互斥。

2.2 手动与自动的先后规则

组合 规则
手动 vs 自动 哪一笔先成功入账,就保留哪一笔。手动先成功时,自动脚本跳过该用户;自动先成功时,玩家手动领取被拦截
自动 vs 自动 依脚本实际执行顺序。先执行并成功入账的活动优先;后执行的脚本判定命中后跳过该用户
同时到达 由同一事务与并发锁决定唯一成功者;另一笔重新判定后被拦截或跳过

2.2.1 自动顺序:自动 vs 自动不另设「AID 较小者优先」规则。执行先后以脚本实际处理并成功提交的顺序为准。

2.3 命中策略

2.3.1 命中条件:一条策略同时满足下列条件才参与判定:

  1. 活动集包含本次 AID。
  2. 策略 BRAND 等于用户 BRAND。
  3. 策略未关闭、未软删。
  4. 当前时间在策略生效窗口内。

2.3.2 空集合:该活动未配置任何策略,或所有策略均不满足条件时,互斥判定放行。

2.3.3 重叠策略:允许同一活动出现在多条策略。每条命中策略分别判定,任一条拦截即整体拦截;共享活动不会自动把多条策略合成一个大组。

2.4 策略1 按用户全局互斥

2.4.1 锁定活动:锁定活动为该策略活动集内、符合回溯范围且 claim_at 最早的成功入账记录所对应活动。

记录 本次结果
组内没有成功记录 放行
本次 AID 等于锁定活动 互斥判定放行;重复入账仍由既有幂等规则处理
本次 AID 不等于锁定活动 拦截/跳过

2.4.2 同秒决胜:claim_at 同秒时,以成功事务提交顺序或唯一入账流水序号决定锁定活动,不按 AID 大小决定。

2.4.3 回溯下界:回溯下界按活动当前状态决定:进行中活动从策略生效起点查;已过期、关闭或状态读取失败的活动从该活动运行起点查。状态读取失败时记录系统运行日志。

2.5 策略2 按单次凭证互斥

2.5.1 凭证范围:策略2只看当前主周期实例,不回溯其他实例。

当前凭证内记录 本次结果
未领过组内任一活动 放行
已领过组内其他活动 拦截/跳过
已领过本活动自己 拦截/跳过
只在上一凭证领过 放行

2.5.2 读取失败:取不到凭证实例标识时不得派发,并按系统异常处理。

2.6 判定记录

2.6.1 记录来源:手动请求与自动任务使用相同的服务端身份、活动与成功记录口径。

项 规则
身份 user_id 与 brand 从 Token 或服务端任务上下文取得,不接受前端自报
活动 activity_id 由当前手动请求或自动任务的服务端对象取得
成功记录 只包含已到账记录;同时记录来源为手动或自动
claim_at 该次派发请求被受理的时刻;不是最终落账完成时刻
互斥拒绝 手动返回 E_MUTEX_BLOCKED;自动跳过该用户并记录原因

2.6.2 自动拒绝:自动任务命中互斥时跳过该用户并记录原因,不把这次跳过当成系统失败重试。


3. 异常与并发

失败点 处理
无效 Token 手动返回 E_UNAUTHORIZED
Token 过期 手动返回 E_TOKEN_EXPIRED
配置、成功记录或并发锁读取失败 不派发;手动返回 E_SYS_BUSY,自动任务记录失败并依既有重试机制处理
活动状态读取失败 按非进行中活动从严回溯,并记录系统运行日志
凭证实例读取失败 不派发;按 E_SYS_BUSY 处理
命中互斥 手动返回 E_MUTEX_BLOCKED;自动任务跳过该用户

系统异常不得写入永久互斥拒绝记录。自动任务因系统异常未派发时,不得误记为「已命中互斥」。

并发保护粒度:策略1为「用户+策略」;策略2为「用户+策略+凭证」。判定与成功入账必须在同一事务内完成。


4. 文案、权限与留痕

4.1 玩家端文案

场景 错误码 文案
互斥拦截 E_MUTEX_BLOCKED ↪ 平台通用
您已参与了互斥的优惠活动
You've already joined a conflicting promotion.
未登录 E_UNAUTHORIZED ↪ 平台通用
请先登录后继续
Please log in first to proceed.
登录过期 E_TOKEN_EXPIRED ↪ 平台通用
登录已过期,请重新登录
Session expired. Please log in again.
系统异常 E_SYS_BUSY ↪ 平台通用
系统繁忙,请稍后再试
Something went wrong. Please try again later.

4.1.1 自动任务:自动派发被互斥拦截时没有玩家端即时提示;任务记录跳过原因即可。响应与任务日志不得暴露策略ID、活动集、锁定活动、到期日或回溯下界。

4.2 后台文案

场景 中文 English
未选平台渠道点添加 Error:请先选择平台渠道! Error: Please select a platform first.
活动数不足 Error:互斥活动至少需要 2 个! Error: At least 2 mutually exclusive campaigns are required.
策略2前提不符 Error:互斥活动须为相同活动模板且相同主周期! Error: Mutually exclusive campaigns must use the same campaign template and primary cycle.
策略名称非法 Error:策略名称仅支持 1-30 个常规字符! Error: Strategy Name supports 1–30 standard characters only.
自定义天数非法 Error:请填入 1-999 正整数! Error: Enter a positive integer from 1–999.
修改锁定字段 Error:该字段建立后不可修改! Error: This field cannot be changed after creation.
备注未填 Error:备注为必填,请填写 1-200 个字符! Error: Remarks are required. Enter 1–200 characters.
备注超过上限 Error:备注最多 200 个字符! Error: Remarks must not exceed 200 characters.
无权限 Error:无操作权限! Error: You do not have permission to perform this action.
启用、关闭或删除 确认{操作}此策略?此操作将写入操作日志。,并要求填写备注 Confirm {action} this strategy? This action will be recorded in the Admin Action Log. Remarks are required.

4.2.1 呈现方式:后台错误均使用弹窗。

4.3 权限与日志

权限 能力
活动互斥策略 查看列表、查询与展开明细
活动互斥策略-操作 新增、修改、启用、关闭与删除
活动互斥策略-导出 导出全部筛选结果

4.3.1 BRAND 隔离:无权 BRAND 的资料行、平台选项与导出内容全部隐藏,后端仍需二次校验。

4.3.2 日志:新增、修改、启用、关闭、删除与导出均写管理员操作日志,记录对象ID、变更前后值、操作人和备注。自动到期写操作人 system。


5. 待确认项

# 问题 决策者 期限
OP-1 策略1回溯查询是否需要时间跨度上限 开发 开发评审
OP-8 策略2凭证实例标识使用哪个既有字段或接口 开发 开发评审
OP-9 策略名称能否重复;两条策略能否使用完全相同的活动集 开发+运营 开发前

自动派发的先后规则已定:不按 AID 排序,以脚本实际执行并成功提交的顺序为准。


附录 A:验收标准
# P 验收点
AC1 P0 达标未领、派发失败或撤销记录存在时,均不占用互斥名额(G1)。
AC2 P0 用户先手动领取 A 成功,自动脚本随后派 B 时,B 跳过且不入账(G2 G3)。
AC3 P0 自动脚本先派 A 成功,用户随后手动领 B 时,手动领取被拦截(G2)。
AC4 P0 手动 A 与自动 B 同时到达时,只有 1 笔成功,另一笔重新判定后被拦截或跳过(G2 G4)。
AC5 P0 自动脚本 A 先成功、脚本 B 后执行时,B 跳过,且系统不按 AID 大小重排(G3)。
AC6 P0 进入策略编辑页时,输入框与明细均带入当前全部 AID。
AC7 P0 在既有 AID 后追加新 AID 并点「添加」时,逐一校验后,明细显示完整新清单。
AC8 P0 从输入框移除 1 个既有 AID 并点「添加」时,明细同步移除该 AID。
AC9 P1 输入跨 BRAND、查无与重复 AID 时,跨 BRAND 与查无被剔除,重复只留 1 笔,且输入框保留通过校验的完整清单。
AC10 P0 策略2加入不同模板或不同主周期活动时,添加或提交被硬阻断;策略1不受此限制。
AC11 P0 同一 AID 命中多条重叠策略时,每条独立判定,任一条拦截即整体拦截(G5)。
AC12 P0 策略 BRAND 与用户 BRAND 不同时,该策略不参与判定(G6)。
AC13 P0 策略1已有最早成功记录 A、再领 B 时,B 被拦;再领 A 仅由既有幂等规则决定。
AC14 P0 策略2本凭证已领 A、再领 A 或 B 时,两者均被拦;新凭证重新放行。
AC15 P0 配置或成功记录读取失败时,不派发且不写永久互斥记录(G7)。
AC16 P0 两个自动任务并发处理同一用户同组活动时,只有 1 笔成功,另一笔跳过(G4)。
AC17 P0 策略关闭、删除或已过期时立即释放;关闭与删除不改原到期日。
AC18 P0 自动任务命中互斥时,跳过用户并记录 E_MUTEX_BLOCKED,不发送玩家端即时提示。

原型视觉清单

原型视觉清单

视觉 ID 载体 用途 证据
VIS-BO-NONE BO 后台列表与配置表单不使用图片或图片占位。 §1
VIS-CLIENT-NONE Client 本需求不新增玩家端原型或内容图片。 L0 ④

清单只约束内容图片与图片占位;表格、图标、载入骨架与标注符号不属于视觉素材槽位。


文档版本:v1.11 | 日期: 2026-09-14 | 作者: Luke | 文档状态:进行中