77 lines
5.7 KiB
Markdown
77 lines
5.7 KiB
Markdown
<!-- 214f69a5-3175-4601-b838-a7982eb9d190 -->
|
||
---
|
||
todos:
|
||
- id: "group-model"
|
||
content: "WalletFundLotGroupModel 扩展 SOURCE_TYPE_* 覆盖券/会员/活动/直接发奖,并加 createSingleMemberGroup 便捷封装(中文常量注释)"
|
||
status: pending
|
||
- id: "recharge-group"
|
||
content: "RechargeFundLotService:纯 Deposit / 纯 Bonus 也建单成员组并写 group_no(required_wager=该 Lot 所需)"
|
||
status: pending
|
||
- id: "register-group"
|
||
content: "RegisterService:fee>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 = 单成员退化组)。
|
||
- **Cash(withdraw)有效投注必须计入当前 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 计入用例。
|
||
|
||
## 风险 / 待确认
|
||
- 退化组 PlayedOut:deposit-only 组资金耗尽未达标时 Deposit 成员状态如何置(现 `markGroupBonusPlayedOut` 只处理 Bonus)。
|
||
- 存量回填在分表上的批量与幂等(按 `uid` 分片,`createGroupIfAbsent` 幂等)。
|
||
- 是否一并采纳 V2「整笔只计 progress_group」(成员投注也归 FIFO 组而非自身组)——本方案默认**不改**,保留现有「成员计自身组 + Cash 计 FIFO 组」,单组场景下二者等价。
|
||
- 是否同时调整扣款顺序为 V2 的「Cash 最后扣」——**默认不在本次范围**。 |