This commit is contained in:
ray zhou
2026-06-29 14:51:55 +08:00
parent 225fb2bd28
commit 2dd9f17da9
319 changed files with 29461 additions and 9412 deletions

View File

@@ -0,0 +1,77 @@
<!-- 214f69a5-3175-4601-b838-a7982eb9d190 -->
---
todos:
- id: "group-model"
content: "WalletFundLotGroupModel 扩展 SOURCE_TYPE_* 覆盖券/会员/活动/直接发奖,并加 createSingleMemberGroup 便捷封装(中文常量注释)"
status: pending
- id: "recharge-group"
content: "RechargeFundLotService纯 Deposit / 纯 Bonus 也建单成员组并写 group_norequired_wager=该 Lot 所需)"
status: pending
- id: "register-group"
content: "RegisterServicefee>0 且 bonus=0 时建单成员 Deposit 组Trial(fee=0) 保持不建"
status: pending
- id: "grant-group"
content: "GrantBonusService注入组模型直接发奖 Bonus 建单成员组并写 group_no"
status: pending
- id: "win-unify"
content: "WinService去掉未分组结算路径统一 finalizeGroup补全 deposit-only/bonus-only 退化组的 Completed/PlayedOut 语义"
status: pending
- id: "bet-cash"
content: "BetService确认/清理 Cash→FIFO progress_group 计入逻辑,移除未分组丢弃相关死分支与注释"
status: pending
- id: "task-display"
content: "PlayerTaskQueryService以组为唯一任务结构未分组分支降为历史兜底或移除"
status: pending
- id: "migration"
content: "新增回填 command将存量进行中未分组 Lot 迁为单成员组(按 uid 分片、幂等)"
status: pending
- id: "doc-update"
content: "更新 docs/requirements/钱包系统V2.md §7/§10/§11人人有组 + Cash 计入 progress_group"
status: pending
- id: "tests"
content: "WalletGroupWageringTest 补单成员组与 Cash 计入打码进度用例"
status: pending
- id: "verify"
content: "收尾跑 verify-slot-backend.sh 门禁 + docker php -l输出检测报告"
status: pending
isProject: false
---
# 钱包打码组统一(路线 A人人有组
## 目标与硬约束
- 真金每笔 `wallet_fund_lot` 都归入一个 `wallet_fund_lot_group`**不再有 `group_no=''` 的真金 Lot**(单 Lot = 单成员退化组)。
- **Cashwithdraw有效投注必须计入当前 FIFO `progress_group`**(修掉「只有未分组 Lot 时 Cash 白打」的缺陷)。
- **Trial 体验金永远独立**:不建 Lot、不建组、不进 `BetService/WinService`(已天然满足,仅需保证不破坏)。
- 复用现有三表,**不改表结构**;仅做数据回填迁移。
## 现状关键事实(已核对)
- 建组只在「Deposit+Bonus 同时存在」时发生:`RechargeFundLotService::resolveRechargeGroupNo``RegisterService::resolveRegisterGroupNo``deposit<=0 || bonus<=0` 返回空串)。
- 纯发奖 Bonus 永远未分组:`GrantBonusService::insertDirectRewardBonusLot``insertFundLot` 不带 `group_no`)。
- Cash 投注归属:`BetService::accumulateGroupWager``withdrawValidBet` 计入 `lockEarliestActiveGroup`**无 Active 组时直接丢弃**(缺陷根因)。
- 结算双路径:`WinService::execute` 同时跑 `finalizeActiveGroups` + `finalizeUngroupedLots`
- 展示双路径:`PlayerTaskQueryService::queryTaskProgress` 返回 `groups` + 未分组 `bonus_tasks/deposit_tasks`
## 设计决定
- 单成员组:`group_no` 复用来源键(`order_no` / 注册 `biz_id` / grant `wallet_request_id``deposit_amount`/`bonus_amount` 一侧为该 Lot 金额、另一侧 0`required_wager = lot.required_wager`
- `WalletFundLotGroupModel` 扩展 `SOURCE_TYPE_*`,覆盖券/会员/活动/直接发奖(现仅 REGISTER=1、RECHARGE=4
- `BetService`:成员投注计入自身 `group_no`、Cash 计入 FIFO 最早 Active 组——逻辑不变但因「人人有组」Cash 不再丢失;`consumeForBet` 仍累加 Lot 级 `current_wager` 供明细展示。
- `WinService`:去掉未分组结算路径,统一走 `finalizeGroup`;补全**单边退化组**deposit-only / bonus-only的 Completed / PlayedOut 语义。
- 迁移期可保留 `finalizeUngroupedLots` 作为历史兜底,回填完成后再删。
## 影响文件
- `slot-wallet/app/model/multi/WalletFundLotGroupModel.php`:加 `SOURCE_TYPE_*`;可加 `createSingleMemberGroup()` 便捷封装。
- `slot-wallet/app/service/wallet/RechargeFundLotService.php`:纯 Deposit、纯 Bonus 也建单成员组并写 `group_no`
- `slot-wallet/app/service/wallet/RegisterService.php``fee>0 & bonus=0` 建单成员 Deposit 组。
- `slot-wallet/app/service/wallet/GrantBonusService.php`:注入组模型,直接发奖 Bonus 建单成员组并写 `group_no`
- `slot-wallet/app/service/wallet/WinService.php`:统一结算路径,处理退化组终态。
- `slot-wallet/app/service/wallet/BetService.php`:清理「未分组 Cash 丢弃」相关分支与注释,确认 Cash→FIFO 组生效。
- `slot-wallet/app/service/wallet/PlayerTaskQueryService.php`:以组为唯一任务结构;未分组分支降为历史兜底或移除。
- 迁移:新增 command参照 `app/command/InitDB.php`)回填存量「进行中」未分组 Lot 为单成员组。
- 文档:`docs/requirements/钱包系统V2.md` §7 / §10 / §11 改为「人人有组 + Cash 计入 progress_group」。
- 测试:`slot-wallet/tests/Feature/WalletGroupWageringTest.php` 补单成员组与 Cash 计入用例。
## 风险 / 待确认
- 退化组 PlayedOutdeposit-only 组资金耗尽未达标时 Deposit 成员状态如何置(现 `markGroupBonusPlayedOut` 只处理 Bonus
- 存量回填在分表上的批量与幂等(按 `uid` 分片,`createGroupIfAbsent` 幂等)。
- 是否一并采纳 V2「整笔只计 progress_group」成员投注也归 FIFO 组而非自身组)——本方案默认**不改**,保留现有「成员计自身组 + Cash 计 FIFO 组」,单组场景下二者等价。
- 是否同时调整扣款顺序为 V2 的「Cash 最后扣」——**默认不在本次范围**。