--- name: is_end结算回退方案 overview: 取消“中间派奖实时余额可见化”调整,回退到严格 Final Settlement 方案:is_end=0 仅累计,is_end=1 才入账与状态收敛。 todos: - id: dto-validator-is-end content: 增加 is_end 字段及 win round_id 强校验 status: completed - id: pending-dedupe-keys content: 新增 pending 与 dedupe Redis key 并接入 is_end=0 累计 status: completed - id: win-final-merge content: is_end=1 合并 pending 后调用现有 WinService 结算并清理缓存 status: completed - id: regression-check content: 回归验证多次派奖累计、最终结算与幂等行为 status: completed isProject: false --- # is_end 结算回退方案(不做中间余额更新) ## 变更决策 取消这部分: - 多次派奖期间(`is_end=0`)对第三方返回余额进行实时更新 - 对 `wallet` 查询叠加 pending 金额 保留并执行: - `is_end=0`:仅做中间派奖累计,不改钱包余额、不做 Lot 收敛 - `is_end=1`:合并累计派奖后一次 Final Settlement(调用现有 win 主流程) ## 实现边界 - 严格遵循 [doc/win.md](doc/win.md) 的“Final Settlement 才做真实入账”原则 - 不引入展示层余额叠加逻辑,避免展示余额与真实可下注余额不一致 ## 具体改造 1. DTO / 校验 - [app/api/dto/request/wallet/WalletUpdateRequestDTO.php](app/api/dto/request/wallet/WalletUpdateRequestDTO.php) 增加 `is_end`(默认 `1`) - [app/validator/Wallet2Validator.php](app/validator/Wallet2Validator.php) - 增加 `is_end` 仅允许 `0/1` - `win` 场景强制 `round_id` 必传 2. Redis 累计与幂等(仅中间派奖) - [app/service/RedisKeyManagerService.php](app/service/RedisKeyManagerService.php) 增加 key: - `wallet:win:pending:{uid}:{currency}:{round_id}` - `wallet:win:dedupe:{uid}:{currency}:{round_id}:{biz_id}` - `is_end=0` 命中 dedupe 则忽略,未命中则累计 pending 3. win 结算分支 - [app/api/logic/WalletLogic.php](app/api/logic/WalletLogic.php) - `is_end=0`:只累计并返回当前真实钱包余额 - `is_end=1`:读取 pending 并与本次 `fee` 合并后走现有 `WinService::execute`,成功后清理 pending ## 验收 - 多条 `is_end=0` 不触发真实入账 - 一条 `is_end=1` 触发一次最终结算,金额=中间累计+末笔 - 中间派奖重复 `biz_id` 不重复累计 - Final 失败时 pending 不丢失,可重试