4.1 KiB
4.1 KiB
name, overview, todos, isProject
| name | overview | todos | isProject | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| is_end派奖结算改造 | 基于现有 BetFunding/WinService 实现,新增 is_end 分支:中间派奖仅累计不入账,结束派奖统一按 Round Final Settlement 入账;并对中间派奖增加 biz_id 严格幂等。 |
|
false |
is_end 驱动的派奖结算改造计划
目标
让 win 接口支持第三方 is_end 语义:
is_end=0:仅记录/累计本局派奖,不做钱包入账、不做 Lot 终态收敛is_end=1:将本次派奖 + 已累计派奖合并后,执行一次 Final Settlement(现有WinService::execute)
现状结论(基于代码)
- 入口路由在 app/api/logic/WalletLogic.php 的
type=win -> win()。 - Final Settlement 主流程在 app/service/wallet/WinService.php。
- 当前
win默认即 Final Settlement,不区分中间派奖事件。 - 下注资金事实表在 app/model/multi/WalletBetFundingModel.php。
实现方案(按你选择)
1) 入参扩展与校验
- 在 app/api/dto/request/wallet/WalletUpdateRequestDTO.php 增加字段:
is_end(默认1,仅允许0|1)。 - 在 app/validator/Wallet2Validator.php:
- 增加
is_end校验规则(整数且取值0/1)。 - 将
win也纳入round_id必传校验(当前仅 bet 必传)。
- 增加
2) Redis Key 设计
- 在 app/service/RedisKeyManagerService.php 新增两个 key 生成器:
wallet:win:pending:{uid}:{currency}:{round_id}:累计未结算派奖金额wallet:win:dedupe:{uid}:{currency}:{round_id}:{biz_id}:中间派奖幂等标记
- 过期策略建议:
pending48h,dedupe72h(与重放窗口对齐)。
3) win 主流程分支
- 修改 app/api/logic/WalletLogic.php 的
win():is_end=0:- 命中 dedupe key 则直接返回当前钱包(幂等)
- 未命中则将
fee累加到 pending key,写 dedupe key,返回当前钱包(不写BIZ_TYPE_WIN流水)
is_end=1:- 读取 pending 累计并与本次
fee合并为finalWinAmount - 用
finalWinAmount调用现有WinService::execute - 事务提交后清理 pending key(失败不清)
- 读取 pending 累计并与本次
4) 幂等与一致性
is_end=1继续沿用现有wallet_log(uid,biz_id,biz_type=win)幂等。is_end=0使用 Redis dedupe key 防重,避免重复累计。- 若
is_end=1无待分配 funding,保持当前行为(报错),便于暴露上游时序问题。
5) 兼容与回归
- 默认
is_end=1,兼容未传该字段的旧调用。 - 回归场景:
- 单次结算(只发
is_end=1) - 多次派奖(多条
is_end=0+ 一条is_end=1) is_end=0重放同 biz_id 不重复累计is_end=1重放同 biz_id 不重复入账is_end=1失败后 pending 不丢失
- 单次结算(只发
关键改动文件
- app/api/dto/request/wallet/WalletUpdateRequestDTO.php
- app/validator/Wallet2Validator.php
- app/service/RedisKeyManagerService.php
- app/api/logic/WalletLogic.php
风险与边界
- 该方案不新增
wallet_game_round/wallet_game_round_event持久化表;中间派奖仅 Redis 暂存,审计粒度弱于 DB 事件流。 - 若某局长期无
is_end=1,pending 依赖 TTL 过期清理。后续可升级为 DB 事件表方案。