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

5.7 KiB
Raw Blame History


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::resolveRechargeGroupNoRegisterService::resolveRegisterGroupNodeposit<=0 || bonus<=0 返回空串)。
  • 纯发奖 Bonus 永远未分组:GrantBonusService::insertDirectRewardBonusLotinsertFundLot 不带 group_no)。
  • Cash 投注归属:BetService::accumulateGroupWagerwithdrawValidBet 计入 lockEarliestActiveGroup无 Active 组时直接丢弃(缺陷根因)。
  • 结算双路径:WinService::execute 同时跑 finalizeActiveGroups + finalizeUngroupedLots
  • 展示双路径:PlayerTaskQueryService::queryTaskProgress 返回 groups + 未分组 bonus_tasks/deposit_tasks

设计决定

  • 单成员组:group_no 复用来源键(order_no / 注册 biz_id / grant wallet_request_iddeposit_amount/bonus_amount 一侧为该 Lot 金额、另一侧 0required_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.phpfee>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 最后扣」——默认不在本次范围