Files
cursor/plans/Fix version2 wager skip-6b933c7f.plan.md
ray zhou 2dd9f17da9 ok
2026-06-29 14:51:55 +08:00

5.6 KiB
Raw Blame History


todos:

  • id: "unify-pending-query" content: "WagerTaskModelgetUncompletedTasksVersion2 / getActiveCountVersion2 / lockedTasksV2 统一为 status IN (1,11) AND current_wager < required_wager" status: pending
  • id: "version2-loop-repair" content: "UpdateWagerTask::version2()needed=0 自动完成;脏 is_completed=1 时纠正并累加打码" status: pending
  • id: "add-unit-tests" content: "补充单测覆盖 is_completed 脏数据与 required_wager=0 边界" status: pending
  • id: "data-hotfix-optional" content: "可选uid 1876592 任务1 将 is_completed 改回 0 作为上线前救火" status: pending isProject: false

修复 version2 有待打码任务却不扣除的问题

根因(对应你这两条数据)

解析你贴的数据(按表字段顺序):

字段 任务1 7733765055921637 任务2 7745776340511881
required_wager 1000 0
current_wager 0 0
is_completed 1 1
status 1等待中 1等待中
brief 恢复提现额数据 提现退回

下注不累加的直接原因UpdateWagerTask::version2() 调用 getUncompletedTasksVersion2(),查询条件是:

is_completed = 0 AND status IN (1, 11)

两条记录 is_completed 都是 1,查询结果 为空empty($tasks)直接 return,下注额不会分配。

任务1 明明 current_wager(0) < required_wager(1000),本应吃打码,但因 is_completed=1 被排除。

flowchart TD
    betMQ[下注MQ updateWagerTask] --> version2[version2]
    version2 --> query[getUncompletedTasksVersion2]
    query --> filter{"is_completed=0 AND status IN 1,11"}
    filter -->|任务1 is_completed=1| empty[tasks 为空]
    empty --> returnEarly[return 不扣除]
    filter -->|正常任务| loop[按 id FIFO 累加 current_wager]

附带不一致(同一用户会「不能提现」但「也不扣打码」)

version2 提现判断走 WalletService::calculateWithdrawAmount()

$num = $wagerTaskModel->getActiveCountVersion2($uid); // 只按 status IN (1,11) 计数
if ($num > 0) return 0;

getActiveCountVersion2() 不看 is_completed,两条 status=1 都会计入 → 提现被挡。

但打码更新 is_completed=0 → 不累加。

这是典型的 卡死状态:有任务、不能提现、打码也不前进。

代码修复方案(推荐)

1. 统一 version2「待打码任务」定义

WagerTaskModel 中,将 version2 待处理任务定义为:

status IN (STATUS_ON, STATUS_PROGRESS) current_wager < required_wager

理由:真正决定是否还需打码的是进度,而不是可能脏写的 is_completed

改动点

  • 重写或替换 getUncompletedTasksVersion2():用 where + whereExp('current_wager', '< required_wager')(或等价 ThinkPHP 写法),去掉对 is_completed=0 的硬依赖。
  • 同步 getActiveCountVersion2()lockedTasksV2():使用同一套「待打码」条件(目前 lockedTasksV2 也不过滤 is_completed,与打码查询语义不一致)。
  • 同步 WalletService::calculateLeftWithdrawNeedBet() 中 version2 分支(已用 lockedTasksV2,改 Model 后自动对齐)。

2. 加强 UpdateWagerTask::version2() 循环

UpdateWagerTask::version2() 的 foreach 内补充:

  • needed == 0status 仍为 ON/PROGRESS 时,调用 markTaskCompletedVersion2() 收尾(避免 required_wager=0 的脏任务永远占着 status=1)。
  • needed > 0is_completed=1(脏数据)时,累加打码时顺带把 is_completed 纠正为 0或在 incrementWagerVersion2 内一并更新),避免下次再被旧逻辑挡住。

3. 单测补充

tests/Unit/UpdateWagerTaskContributionTest.php 或新增 Model 单测,覆盖:

  • is_completed=1current_wager < required_wager 的任务应被纳入待打码列表;
  • required_wager=0current_wager=0 的任务不应纳入对应你的任务2
  • getActiveCountVersion2 与打码查询计数一致。

该用户即时数据修复(可选,上线代码前可先救火)

对 uid 1876592、任务 7733765055921637

UPDATE wager_task_{shard}
SET is_completed = 0
WHERE id = 7733765055921637 AND uid = 1876592;

(分表名按 uid 取模规则确定。)

任务2 required_wager=0 在代码修复后不会再挡打码;若仍 status=1is_completed=1,修复 getActiveCountVersion2 后也不再挡提现。

不纳入本次范围

  • 不判断 withdraw_back 业务倍数应为多少任务2 required_wager=0 在修复后的查询里自然不会参与打码分配。
  • 不追溯任务1为何 is_completed=1completed_at=0(数据脏写来源),代码修复以 自愈脏数据 为主。

验收

  1. uid 1876592 下注后任务1 current_wager 递增。
  2. calculateLeftWithdrawNeedBet 显示的剩余打码与 current_wager 同步下降。
  3. 任务1 打满后 status=12is_completed=1getActiveCountVersion2 为 0可提现。
  4. slot-backend-completion-report 门禁通过。