123 lines
5.6 KiB
Markdown
123 lines
5.6 KiB
Markdown
<!-- 6b933c7f-da14-42c8-8223-1fd4068c9b61 -->
|
||
---
|
||
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()`](slot_wallet/app/command/UpdateWagerTask.php) 调用 [`getUncompletedTasksVersion2()`](slot_wallet/app/model/multi/WagerTaskModel.php),查询条件是:
|
||
|
||
```php
|
||
is_completed = 0 AND status IN (1, 11)
|
||
```
|
||
|
||
两条记录 **`is_completed` 都是 1**,查询结果 **为空** → `empty($tasks)` → **直接 return**,下注额不会分配。
|
||
|
||
任务1 明明 `current_wager(0) < required_wager(1000)`,本应吃打码,但因 `is_completed=1` 被排除。
|
||
|
||
```mermaid
|
||
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()`](slot_wallet/app/service/WalletService.php):
|
||
|
||
```php
|
||
$num = $wagerTaskModel->getActiveCountVersion2($uid); // 只按 status IN (1,11) 计数
|
||
if ($num > 0) return 0;
|
||
```
|
||
|
||
[`getActiveCountVersion2()`](slot_wallet/app/model/multi/WagerTaskModel.php) **不看 `is_completed`**,两条 `status=1` 都会计入 → 提现被挡。
|
||
|
||
但打码更新 **看 `is_completed=0`** → 不累加。
|
||
|
||
这是典型的 **卡死状态**:有任务、不能提现、打码也不前进。
|
||
|
||
## 代码修复方案(推荐)
|
||
|
||
### 1. 统一 version2「待打码任务」定义
|
||
|
||
在 [`WagerTaskModel`](slot_wallet/app/model/multi/WagerTaskModel.php) 中,将 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()`](slot_wallet/app/service/WalletService.php) 中 version2 分支(已用 `lockedTasksV2`,改 Model 后自动对齐)。
|
||
|
||
### 2. 加强 `UpdateWagerTask::version2()` 循环
|
||
|
||
在 [`UpdateWagerTask::version2()`](slot_wallet/app/command/UpdateWagerTask.php) 的 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`](slot_wallet/tests/Unit/UpdateWagerTaskContributionTest.php) 或新增 Model 单测,覆盖:
|
||
|
||
- `is_completed=1` 但 `current_wager < required_wager` 的任务应被纳入待打码列表;
|
||
- `required_wager=0` 且 `current_wager=0` 的任务不应纳入(对应你的任务2);
|
||
- `getActiveCountVersion2` 与打码查询计数一致。
|
||
|
||
## 该用户即时数据修复(可选,上线代码前可先救火)
|
||
|
||
对 uid `1876592`、任务 `7733765055921637`:
|
||
|
||
```sql
|
||
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` 业务倍数应为多少;任务2 `required_wager=0` 在修复后的查询里自然不会参与打码分配。
|
||
- 不追溯任务1为何 `is_completed=1` 且 `completed_at=0`(数据脏写来源),代码修复以 **自愈脏数据** 为主。
|
||
|
||
## 验收
|
||
|
||
1. uid 1876592 下注后,任务1 `current_wager` 递增。
|
||
2. `calculateLeftWithdrawNeedBet` 显示的剩余打码与 `current_wager` 同步下降。
|
||
3. 任务1 打满后 `status=12`、`is_completed=1`,`getActiveCountVersion2` 为 0,可提现。
|
||
4. 跑 `slot-backend-completion-report` 门禁通过。
|