Appearance
10 · 任务打码系统
0. 文档说明
| 项 | 内容 |
|---|---|
| 版本 | V1.0 |
一体两面:任务中心(每日/新手任务,奖励中心第一个 tab)+ 打码引擎(全平台唯一的有效流水推进器,服务 02 彩金解锁 / 06·07 保级 / 04 提现门槛 / 本系统任务进度)。
一租户 = 一「本位币站」,站内单币种(→ 00 架构总纲)。义务额、目标、奖励、有效打码量口径恒为本位币
wallet.baseCurrency;打码引擎按注单统一推进,义务为账号级本位币口径,一笔注单的有效打码同步推进该用户全部在途义务。
一、定位与职责
- 打码引擎:订阅
BetSettled,按游戏类型权重折算有效打码量,统一推进所有在途「打码义务」; - 任务中心:任务模板/周期实例/领取(单个「可领取」+「一键领取」)、红点;
- 定义义务模型(四种来源)、并行计入规则、过期与结算。
边界:注单与 validTurnover 归 12;彩金状态机归 02(本系统只推进并回调解锁);降级裁决归 06。
二、核心概念与数据模型
2.1 打码义务 WageringObligation(统一模型,四种来源)
| 字段 | 说明 |
|---|---|
obligationId / tenantId / userId | 归属(站内单币种,义务额恒本位币) |
source | BONUS_UNLOCK(02 彩金解锁)/ RETENTION(07 保级)/ WITHDRAW_GATE(04 提现门槛)/ TASK(任务型进度) |
ref | 来源单据(grantId / 保级周期号 / 充值订单号 / 任务实例) |
required / progress | 目标额 / 已完成额(本位币);required 支持累加 upsert(RETENTION 同周期多次领取俸禄累加,→ §3.3) |
state | ACTIVE → FULFILLED / EXPIRED / VOID(来源撤销);FULFILLED 为终态,遇 BetCancelled 不回退(→ §3.1) |
expireAt | 到期(保级=周期末;彩金=grant 过期;门槛=长期) |
version | 乐观锁版本号(并行推进防丢更新,→ §3.1 并发策略) |
BetSettled(12) ─► 有效打码 = validTurnover × weight(gameType) ─► 该用户全部 ACTIVE 义务并行推进(本位币)
│
达标 ─► FULFILLED ─► 回调来源:02 BONUS_UNLOCK / 06 保级达标 / 04 放行提现并行计入:同一笔注单的有效打码同时计入该用户所有 ACTIVE 义务(各义务独立记账,互不瓜分)——站内单币种,并行范围覆盖该用户全部在途义务。逐义务串行(FIFO)模式列开放问题。
2.2 任务 TaskDef / UserTask
| TaskDef(配置) | 说明 |
|---|---|
taskId / group | 任务与分组(每日 / 新手 / 长期) |
type | BET_TURNOVER(投注额)/ BET_COUNT(局数)/ DEPOSIT(充值)/ LOGIN(登录)/ PLAY_GAME(试玩指定游戏/类型) |
target / reward | 目标值 / 奖励(本位币单值)+ rewardTarget |
cycle | DAILY(租户时区日切重置)/ ONCE(新手)/ WEEKLY |
UserTask 状态机:
● ─► IN_PROGRESS(进行中) ─达标─► CLAIMABLE(可领取) ─领取─► CLAIMED
│期末未达标/未领 (REWARD_CREDIT/BONUS_GRANT)
▼
EXPIRED(随周期作废,次周期重新生成)三、业务规则
3.1 权重折算(打码引擎核心参数)
有效打码 = validTurnover × weights[gameType](如 电子 100% / 捕鱼 100% / 棋牌 50% / 真人 50% / 体育 50% / 原创 100%);权重仅作用于打码义务,返水不加权(→ 08 §一)。validTurnover 恒为本位币值(场馆 CNY 映射链路的注单由通道适配层 1:1 重标本位币入库,→ 02),打码计算零特判。
冲正(BetCancelled,幂等键 betId+cancelSeq):注单取消按原权重冲正回退 progress,冲正写一条 obligation_progress_log(kind=REVERSE, weighted_amount<0),与结算行(kind=ACCRUE)共享 bet_id 但靠 kind+cancelSeq 区分,支持同注单多次/部分取消(与 08 §五 口径一致)。
已 FULFILLED 义务遇 BetCancelled 不回退:
- FULFILLED 是终态,资金已放(彩金已解锁 bonus→available、提现已放行、保级已计达标),达标一旦触发不因后续冲正而回退;冲正只作用于仍
ACTIVE的义务progress。 - 防「大额投注瞬间打满→解锁/提现→撤单」套利闭环,靠
validTurnover取整下限 + 14 风控「结算后大量取消」画像拦截,不在资金已出后追回(与 08 §三.3 返水池不足挂负债不追讨、02 §2.4 彩金 UNLOCKED 终态无回退口径一致)。 - 兜底口径:对「结算后可被取消」的注型,
validTurnover的产生已由 12 在不可撤销窗口后确认,故进入打码推进的多为已终局流水,套利窗口在源头收窄。
并行推进的事务与并发:一笔 BetSettled 需对该用户 N 条 ACTIVE 义务(彩金解锁 + 多条保级 + 提现门槛 + 任务)各写一条 progress_log 并各自 UPDATE progress,N 可达十数条。落地约束:
- 写入量/顺序:逐义务独立记账(互不瓜分),同一事务内遍历该用户全部 ACTIVE 义务、每义务一条 log + 一次进度 UPDATE;
progress_log幂等 UK(tenant_id,obligation_id,bet_id,kind,cancel_seq) 兜底重放,失败整批回滚后按betId重入(幂等,不重复累计)。 - 并发:义务进度 UPDATE 用
version乐观锁(高频注单对同批义务行并发,防丢更新;CAS 失败重读重试),避免 02 钱包有 version、义务表无 version 的不对称。 - 达标回调编排:一笔注单可同时令多条义务达标(如同时解锁彩金 + 放行提现),逐义务独立触发回调、各自幂等(BONUS_UNLOCK 回调 02 入账、WITHDRAW_GATE 置放行、RETENTION 记达标);回调顺序无依赖,任一失败不阻断其余义务的进度落库(回调走各自幂等键补偿)。
3.2 任务领取
- 单任务:CLAIMABLE 卡片出「可领取」按钮,单独领;
- 一键领取:面板级按钮,批量领取所有 CLAIMABLE(逐任务生成
claimId,各自幂等); - 领取后:红点数(
/me.badges.task= CLAIMABLE 数)即时递减,奖励 tab 顶部红点随之变化;奖励入本位币钱包; - 发
RewardClaimed(source=TASK)。
3.3 义务结算
BONUS_UNLOCK达标 → 10 判定达标后通知 02 执行 bonus→available,由 02 入账成功后发BonusUnlocked(幂等键 grantId);bonus_grants.wagering_progress(02)为冗余展示,以grantId关联本表进度,本表wagering_obligations为打码进度唯一权威(→ 02 §八)。RETENTION保级义务:领取俸禄时 07 调addObligationRequired(RETENTION, 周期键, delta)累加 upsert(同周期单条、required累加,不新建,→ 07 §2.3);周期末结算 → 达标/未达标结论交 06(降级裁决)。WITHDRAW_GATE:充值成功时(DepositSucceeded)生成(required = amount × withdraw.wageringCheck.multiple,applyScope决定对全部充值还是仅带活动充值生效,本位币;配置见 04 §四withdraw.wageringCheck,由本系统消费)。展示口径统一:门槛缺口折入「可提现金额」,不单列缺口提示——即getObligations(WITHDRAW_GATE)的未达标额由 04 折入可提现金额口径核减(与 04 §3.1④ 一致),提现页不出现「还需完成有效投注 ¥X」独立文案。
四、★ 租户可配置项(task 命名空间)
jsonc
"task": {
"enabled": true,
"weights": { "slots": 1.0, "fish": 1.0, "original": 1.0, "card": 0.5,
"live": 0.5, "sport": 0.5, "esport": 0.5, "lottery": 0 }, // 打码权重(义务通用;示例值,键=12 类型目录)
"resetTz": "tenant", // 日切时区
"groups": [ { "key": "daily", "name": "每日任务" }, { "key": "newbie", "name": "新手任务" } ],
"tasks": [
{ "taskId": "daily-bet-500", "group": "daily", "type": "BET_TURNOVER", "cycle": "DAILY",
"target": "500", // 本位币单值(站内单币种,单一口径)
"reward": "8", "rewardTarget": "available" }
/* … */
]
}Schema 校验:weights 键 ⊆ 12 游戏类型目录,值 ∈ [0,1];任务 target/reward 为本位币单值(单位 wallet.baseCurrency,校验其存在)。
五、与其他系统的关系 / 接口
| 接口 | 调用方 | 幂等键 | 说明 |
|---|---|---|---|
createObligation(source, ref, userId, required, expireAt) | 02/04 | source+ref | 建义务(required 本位币);UK(tenant_id,source,ref) 存在即幂等返回,不重复建 |
addObligationRequired(source, ref, deltaRequired) | 07(保级累加) | source+ref | 累加 upsert:同 (source,ref) 存在则 required += delta,不存在则以 delta 建;RETENTION 同周期多次领取俸禄累加进单条(→ 07 §2.3) |
getObligations(userId, source?) | 04(缺口折入)/ 展示层 | — | 在途义务与进度(本位币);WITHDRAW_GATE 缺口由 04 折入可提现口径、不单列(→ §3.3) |
getTaskPanel(userId) | 展示层 | — | 分组任务列表 + 状态 + 红点数 |
claimTask(userId, taskId, cycleNo) / claimAll(userId) | 展示层 | claimId(逐任务) | 单领 / 一键领取(入本位币钱包) |
消费 BetSettled / BetCancelled | ← 12 | betId / betId+cancelSeq | 推进 / 冲正(仅 ACTIVE 义务;FULFILLED 不回退,→ §3.1) |
产 RewardClaimed / 回调 02·06·04 | → | claimId / obligationId | 领取与义务结算 |
六、运营后台能力(→ 15)
| 侧 | 能力 |
|---|---|
| 平台控制台 | 任务类型库(新 type=引擎扩展) |
| 商户控制台 | 任务配置(目标/奖励本位币/周期/分组);打码权重表;用户义务查询(客诉:为何彩金未解锁/提现被拦);任务成本统计(→17) |
七、展示契约(→ 原型映射)
| UI 元素 | 数据 | 原型载体 | 系统契约 |
|---|---|---|---|
| 任务 tab | 分组任务卡:进度条/目标/奖励/按钮态 | 奖励中心「任务」tab:进行中(进度)/可领取(绿)/已领取(灰) | getTaskPanel;目标与奖励恒本位币 |
| 一键领取 | 所有 CLAIMABLE | 面板顶部「一键领取」按钮 | claimAll;领取动效逐卡变灰 |
| 红点 | CLAIMABLE 数 | 奖励 tab 顶部红点,领取后状态即时变 | /me.badges.task |
| 打码进度(彩金) | BONUS_UNLOCK 义务 | 钱包彩金区「解锁进度」 | getObligations(source=BONUS_UNLOCK):progress/required 进度条(本位币);本表为进度唯一权威(→ §3.3) |
| 提现门槛(WITHDRAW_GATE) | 义务缺口 | — | 不单列缺口提示:缺口折入 04「可提现金额」口径,提现页无独立「还需打码 ¥X」文案(→ §3.3、04 §3.1④) |
八、数据库设计(全表含 tenant_id;金额 DECIMAL(32,8))
| 表 | 关键字段 | 约束/索引 |
|---|---|---|
wagering_obligations | obligation_id PK, tenant_id, user_id, source, ref, required(本位币,RETENTION 累加 upsert), progress, state, version(乐观锁,→ §3.1 并发), expire_at, created_at, fulfilled_at | UK(tenant_id,source,ref)——同 (source,ref) 单条,required 累加更新;IDX(tenant_id,user_id,state) |
obligation_progress_log | id PK, tenant_id, obligation_id, bet_id, kind(ACCRUE/REVERSE:结算累计 / 取消冲正), cancel_seq(结算行=0,冲正行=取消序号), weighted_amount(本位币,冲正为负), created_at | UK(tenant_id,obligation_id,bet_id,kind,cancel_seq)——结算与多次冲正各一行,靠 kind+cancel_seq 区分;IDX(tenant_id,obligation_id,created_at) |
user_tasks | id PK, tenant_id, user_id, task_id, cycle_no, progress, state, claimed_at | UK(tenant_id,user_id,task_id,cycle_no) |
(义务/进度表金额列恒为本位币口径——站内单币种,键内无 currency 分量。)高频推进可批量写(实现优化);progress_log 供客诉追溯「哪些注单计了码」。
九、扩展点与开放问题
- 并行 vs 串行:V1 并行计入(实现简单、用户友好);若运营认为「一笔流水多处生效」过于宽松,可切 FIFO 串行(义务按创建序独占消耗),引擎预留策略位。
- 打码闯关玩法:09 游戏类型活动用到「打码闯关」,即 TASK 义务的多级 target 链,模板化时在任务类型库扩展。
十、验收要点
- [ ] 同一注单按权重同事务同时推进该用户全部 ACTIVE 义务,各义务一条
progress_log(kind=ACCRUE)+ 一次 version 乐观锁进度 UPDATE,可追溯;义务额与进度全程本位币,无 currency 维度; - [ ] 权重=0 的游戏类型投注不推进任何义务;返水不受权重影响;
- [ ] 彩金义务达标 → 10 通知 02 入账、由 02 发
BonusUnlocked(幂等 grantId)+ bonus→available 一致发生;wagering_obligations为进度唯一权威,bonus_grants冗余不双推; - [ ]
BetCancelled(幂等键 betId+cancelSeq)冲正写progress_log(kind=REVERSE),与结算行 kind=ACCRUE 靠 kind+cancel_seq 共存不撞 UK;已 FULFILLED 义务不回退(资金已放),仅 ACTIVE 义务 progress 回退; - [ ] 保级义务同周期多次领取单条累加(
addObligationRequiredupsert,UK 不冲突),周期末结论与 06 降级动作一致; - [ ] 一键领取 = N 次幂等单领:重复点击不重复入账,红点归零;奖励入本位币钱包;
- [ ] 日切后每日任务重置、EXPIRED 留痕;
- [ ] WITHDRAW_GATE 缺口折入 04 可提现金额口径,提现页不单列「还需打码 ¥X」独立文案。