fix: 充值核账按绑定账号和角色整组

This commit is contained in:
yml2213
2026-10-19 17:22:51 +08:00
parent 3a6649a054
commit c299f63537
4 changed files with 103 additions and 38 deletions
+12 -8
View File
@@ -242,8 +242,8 @@ incomplete ─资料齐全且 CK 有效─▶ to_recharge ─充值核账─▶
审计 `reason=data_missing`。**CK 失效本身不触发退回**:业务上可能只是凭据过期,
充值核账会强制重验并阻止误判。
4. **换 CK 不回退业务状态**:`set_ck()` 只把 `ck_status` 打回 `unverified`;等用户点
「充值核账」时强制重验。若探针读到的 `bind_game_account` 变了,整组核账报错,
不会把订单误落到旧账号组。
「充值核账」时强制重验。若探针读到的 `bind_game_account` / `bind_game_role` 变了,
整组核账报错,不会把订单误落到旧买家组。
5. **人工切换允许往前跳步**:目标阶段序号 ≥ 当前即放行(`is_forward_status()`)。
跳步会把沿途的 `*_at` 时间戳**补齐**(`_sync_stage_timestamps()`)。
6. **回退必须显式声明**:目标阶段序号 < 当前时必须 `rollback=true`(界面勾「回退」),
@@ -262,7 +262,9 @@ incomplete ─资料齐全且 CK 有效─▶ to_recharge ─充值核账─▶
**充值核账(整组,`check_recharge_groups()`)**:
- 分组键 = **精确的 `bind_game_account`**;组内只统计 `to_recharge / recharged /
- 分组键 = **`bind_game_account` + `bind_game_role`**(和「同一买家」软识别一致)。
探针读到的账号经常只是「微信用户 / QQ用户」这种通用昵称,**只按账号会把不同买家并成一组**
(2026-10-19 生产上 8 单被合成 48000 分);组内只统计 `to_recharge / recharged /
points_error`,`incomplete / scripted / done / failed / void` 不参与;
- 同一 uid 只验一次 CK、只查一次积分;组内多个 uid 的积分**合计**;
- `必充积分 = Σ required_points`;`结余 = 账号积分合计 - 必充积分`;
@@ -572,7 +574,7 @@ unverified ──探针成功──▶ valid ──探针失败──▶ invalid
| POST | `/api/huya/external-orders/ck/preview` | `huya:collab:edit` | 粘贴 CK 后的即时预览(探针 + 拉活动礼包,**只读不写库**) |
| POST | `/api/huya/external-orders/ck/verify` | `huya:collab:edit` | 批量验证 CK(探针,body `{ids: [...]}`,最多 50 条) |
| POST | `/api/huya/external-orders/status/batch` | `huya:collab:edit` | 勾选多行切成同一个状态(逐行 SAVEPOINT 隔离,最多 50 条;**不接受** `recharged` / `points_error`;§4.1) |
| POST | `/api/huya/external-orders/recharge` | `huya:collab:edit` | **充值核账**:`{ids, threshold}`,按 `bind_game_account` 整组验证 CK + 积分,整组落 `recharged` / `points_error`(§4.1) |
| POST | `/api/huya/external-orders/recharge` | `huya:collab:edit` | **充值核账**:`{ids, threshold}`,按「绑定账号 + 绑定角色」整组验证 CK + 积分,整组落 `recharged` / `points_error`(§4.1) |
| POST | `/api/huya/external-orders/archive` | `huya:collab:edit` | 归档抢购成功订单:`ids` 单条/勾选,或 `archive_filtered=true` + 筛选条件按当前筛选批量;可带 `reason`,`expected_count` 校验数量(§4.4) |
| POST | `/api/huya/external-orders/unarchive` | `huya:collab:edit` | 取消归档(`{ids: [...]}`),恢复回活跃台账 |
| POST | `/api/huya/external-orders/activity/query` | `huya:collab:edit` | 勾选多行查积分 + 兑换记录(串行带间隔,每行写一条生命周期快照;§5.7) |
@@ -1032,20 +1034,22 @@ unverified ──探针成功──▶ valid ──探针失败──▶ invalid
| 状态 | 删除 `pending` / `bound`;新增 `to_recharge`(待充值)、`points_error`(积分异常);`incomplete` 成为唯一入口 |
| 自动推进 | `_maybe_advance_to_recharge()`:CK 有效 + 绑定账号 + 绑定角色 + 礼包名 + ≥1 张主页截图 → 自动 `incomplete → to_recharge`;创建/编辑/补图/验证 CK 都触发 |
| 自动退回 | `_maybe_demote_missing_data()`:`to_recharge` / `points_error` 关键资料被清空 → 自动退回 `incomplete`;CK 失效不触发 |
| 核账 | `check_recharge_groups()` + `POST /external-orders/recharge`:按精确 `bind_game_account` 分组;只统计 `to_recharge/recharged/points_error`;同 uid 只验一次 CK、只查一次积分;多 uid 积分合计 |
| 核账 | `check_recharge_groups()` + `POST /external-orders/recharge`:按「`bind_game_account` + `bind_game_role`」分组;只统计 `to_recharge/recharged/points_error`;同 uid 只验一次 CK、只查一次积分;多 uid 积分合计 |
| 判定 | `结余 = 积分合计 - Σ required_points`;`<0` → `points_error/shortage`;`>阈值` → `points_error/excess`;其余 → `recharged`;CK 失效/积分失败/积分缺失整组保持原状态 |
| 字段 | 新增 `required_points` + `points_checked_at/points_balance/points_required_total/points_surplus/points_threshold/points_check_reason/points_check_message/points_check_detail` |
| 迁移 | `20261019_0061`:加列、`status` 默认改 `incomplete`、旧 `pending/bound` 按资料是否齐全转 `to_recharge` 或 `incomplete`;降级把 `to_recharge → bound`、`points_error → recharged` |
| 礼包来源 | 改用 `PlayMallUI.queryAllocation`(`tag75.tag0.tag2` 取积分,`tag13` 库存),不再依赖活动 SID;旧 `webActUI.getActPrizeList` 仅保留给精英宝典工作台 |
| 前端 | 统计卡改为 全部/待补资料/待充值/已充值/已上脚本/抢购成功/抢购失败/积分异常/CK 失效,**可点击筛选并高亮**;工具栏新增「充值核账」;新建/补资料/详情增加「礼包所需积分」,选礼包自动带出;核账弹窗阈值默认 100 |
| 审计 | 核账逐单写 `huya:collab:recharge_check`;自动推进/退回写 `huya:collab:status_auto`;主操作(create/update/image)先落审计,再追加自动状态,时间线因果顺序不再倒置 |
| 生产修正 | 首版只按 `bind_game_account` 分组,生产发现「微信用户 / QQ用户」是通用昵称,8 个不同角色被合成一组(required_total=48000)。现改为「账号 + 角色」;`points_check_detail` 同时保留 `bind_game_account` 与 `bind_game_role` |
**三条边界**:
1. **不要用 uid 当分组键**:同一买家可能用多份 CK。分组只认探针读到的 `bind_game_account`;
`bind_game_account` 为空的行保持/退回 `incomplete`,绝不回落到 uid。
1. **不要只拿 `bind_game_account` 当分组键**:它经常是「微信用户 / QQ用户」这种通用昵称;
同一买家必须靠「账号 + 角色」识别。账号或角色为空的行保持/退回 `incomplete`,
绝不回落到 uid。
2. **不要让人工直写 `recharged` / `points_error`**:这两个状态必须由核账产生,否则积分快照与状态会各说各话。
3. **换 CK 不等于资料缺失**:`set_ck()` 只重置 `ck_status`;核账会强制重验,若绑定账号变了整组报错,不会误落旧组。
3. **换 CK 不等于资料缺失**:`set_ck()` 只重置 `ck_status`;核账会强制重验,若绑定账号/角色变了整组报错,不会误落旧组。
---