5.6 KiB
todos:
- id: "unify-pending-query" content: "WagerTaskModel:getUncompletedTasksVersion2 / 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 == 0且status仍为 ON/PROGRESS 时,调用markTaskCompletedVersion2()收尾(避免required_wager=0的脏任务永远占着status=1)。 - 当
needed > 0且is_completed=1(脏数据)时,累加打码时顺带把is_completed纠正为 0(或在incrementWagerVersion2内一并更新),避免下次再被旧逻辑挡住。
3. 单测补充
在 tests/Unit/UpdateWagerTaskContributionTest.php 或新增 Model 单测,覆盖:
is_completed=1但current_wager < required_wager的任务应被纳入待打码列表;required_wager=0且current_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=1 且 is_completed=1,修复 getActiveCountVersion2 后也不再挡提现。
不纳入本次范围
- 不判断
withdraw_back业务倍数应为多少;任务2required_wager=0在修复后的查询里自然不会参与打码分配。 - 不追溯任务1为何
is_completed=1且completed_at=0(数据脏写来源),代码修复以 自愈脏数据 为主。
验收
- uid 1876592 下注后,任务1
current_wager递增。 calculateLeftWithdrawNeedBet显示的剩余打码与current_wager同步下降。- 任务1 打满后
status=12、is_completed=1,getActiveCountVersion2为 0,可提现。 - 跑
slot-backend-completion-report门禁通过。