Files
cursor/plans/Plan-214f69a5.plan.md
ray zhou 2dd9f17da9 ok
2026-06-29 14:51:55 +08:00

77 lines
5.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 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 最后扣」——**默认不在本次范围**。