Skip to content

10 · 任务打码系统

0. 文档说明

内容
版本V1.0

一体两面:任务中心(每日/新手任务,奖励中心第一个 tab)+ 打码引擎(全平台唯一的有效流水推进器,服务 02 彩金解锁 / 06·07 保级 / 04 提现门槛 / 本系统任务进度)。

一租户 = 一「本位币站」,站内单币种(→ 00 架构总纲)。义务额、目标、奖励、有效打码量口径恒为本位币 wallet.baseCurrency;打码引擎按注单统一推进,义务为账号级本位币口径,一笔注单的有效打码同步推进该用户全部在途义务。


一、定位与职责

  • 打码引擎:订阅 BetSettled,按游戏类型权重折算有效打码量,统一推进所有在途「打码义务」;
  • 任务中心:任务模板/周期实例/领取(单个「可领取」+「一键领取」)、红点;
  • 定义义务模型(四种来源)、并行计入规则、过期与结算。

边界:注单与 validTurnover 归 12;彩金状态机归 02(本系统只推进并回调解锁);降级裁决归 06。


二、核心概念与数据模型

2.1 打码义务 WageringObligation(统一模型,四种来源)

字段说明
obligationId / tenantId / userId归属(站内单币种,义务额恒本位币)
sourceBONUS_UNLOCK(02 彩金解锁)/ RETENTION(07 保级)/ WITHDRAW_GATE(04 提现门槛)/ TASK(任务型进度)
ref来源单据(grantId / 保级周期号 / 充值订单号 / 任务实例)
required / progress目标额 / 已完成额(本位币);required 支持累加 upsert(RETENTION 同周期多次领取俸禄累加,→ §3.3)
stateACTIVE → 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任务与分组(每日 / 新手 / 长期)
typeBET_TURNOVER(投注额)/ BET_COUNT(局数)/ DEPOSIT(充值)/ LOGIN(登录)/ PLAY_GAME(试玩指定游戏/类型)
target / reward目标值 / 奖励(本位币单值)+ rewardTarget
cycleDAILY(租户时区日切重置)/ 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/04source+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← 12betId / betId+cancelSeq推进 / 冲正(仅 ACTIVE 义务;FULFILLED 不回退,→ §3.1)
RewardClaimed / 回调 02·06·04claimId / 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_obligationsobligation_id PK, tenant_id, user_id, source, ref, required(本位币,RETENTION 累加 upsert), progress, state, version(乐观锁,→ §3.1 并发), expire_at, created_at, fulfilled_atUK(tenant_id,source,ref)——同 (source,ref) 单条,required 累加更新;IDX(tenant_id,user_id,state)
obligation_progress_logid PK, tenant_id, obligation_id, bet_id, kind(ACCRUE/REVERSE:结算累计 / 取消冲正), cancel_seq(结算行=0,冲正行=取消序号), weighted_amount(本位币,冲正为负), created_atUK(tenant_id,obligation_id,bet_id,kind,cancel_seq)——结算与多次冲正各一行,靠 kind+cancel_seq 区分;IDX(tenant_id,obligation_id,created_at)
user_tasksid PK, tenant_id, user_id, task_id, cycle_no, progress, state, claimed_atUK(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 回退;
  • [ ] 保级义务同周期多次领取单条累加(addObligationRequired upsert,UK 不冲突),周期末结论与 06 降级动作一致;
  • [ ] 一键领取 = N 次幂等单领:重复点击不重复入账,红点归零;奖励入本位币钱包;
  • [ ] 日切后每日任务重置、EXPIRED 留痕;
  • [ ] WITHDRAW_GATE 缺口折入 04 可提现金额口径,提现页不单列「还需打码 ¥X」独立文案。