6.5 KiB
name, overview, todos, isProject
| name | overview | todos | isProject | |||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 第一档提现统计入账 | 第一档免打码提现成功后,Pay 的 `EventWithdrawal` 在发 Console 总线之外,需经 slot_lib 调用 wallet 新增「仅累加 total_withdraw」接口,把提现金额记入分片 `wallet_stat_xx`,与普通提现 `withdrawSuccess` 的统计口径对齐。 |
|
false |
第一档提现成功:wallet_stat 累计提现额补齐
背景与缺口
首充定格第一档(free_credit_first_cashout)在 EventWithdrawal.php 打款成功时已按设计 跳过 withdrawSuccess / withdrawFail,只发 Console 总线:
if (WithdrawalOrderEntity::isFreeCreditFirstCashoutOrder($order)) {
ConsoleMqService::getInstance()->sendConsoleBusEvent($order->uid, MQBusEntity::TYPE_FREE_CREDITS_FIRST_CASHOUT_SUCCESS, [
'order_id' => $order->order_id,
]);
} else {
$walletService->withdrawSuccess($withdrawalAmount, $order->order_id);
普通提现的 total_withdraw 仅在 WalletLogic::withdraw()(type=withdraw)里 WalletStatModel::inc(..., 'total_withdraw', fee),且会 finishWithdraw 扣减 withdraw_lock。
第一档 不冻结 普通钱包(WithdrawalOrderEntity::apply 已跳过 withdrawFrozen),因此 不能 直接调 withdrawSuccess——会动 withdraw_lock 并可能失败。
遗留问题:wallet_stat_{xx}.total_withdraw 未累加,后台用户列表/盈亏等读 tw/total_withdraw 会偏小。
sequenceDiagram
participant Pay as slot_pay EventWithdrawal
participant Console as slot_console EventBus
participant Wallet as slot_wallet WalletLogic
Note over Pay: 现状(成功)
Pay->>Console: FreeCreditsFirstCashoutSuccess
Note over Wallet: total_withdraw 未更新
Note over Pay: 目标(成功)
Pay->>Console: FreeCreditsFirstCashoutSuccess
Pay->>Wallet: freeCreditsFirstCashoutStat(order_id, amount)
Wallet->>Wallet: inc total_withdraw + wallet_log
推荐方案:wallet 新增「仅统计」类型
与现有 freeCreditsFreeze / freeCreditsFirstCashKeep 一致:走 POST api/wallet/update,WalletLogic::run() 按 type 分发,不改 wallet_account 余额与 withdraw_lock。
1. slot_wallet
| 文件 | 改动 |
|---|---|
| WalletLogModel.php | 新增 BIZ_TYPE_FREE_CREDITS_FIRST_CASHOUT_STAT = 'freeCreditsFirstCashoutStat' |
| WalletLogic.php | 新增 freeCreditsFirstCashoutStat():fee>0 时事务内 WalletStatModel::inc(currency, 'total_withdraw', fee) + addLog(0, balance, 新 biz_type, WALLET_TYPE_GIFT)(流水 amount=0 或记负向备注,与 first_keep 风格一致) |
| 幂等 | biz_id 使用 提现订单号 order_id(与 withdrawSuccess 一致);wallet_log 表已有 uniq_uid_bizid_type (uid, biz_id, biz_type)。重复 MQ 消费时 addLog 唯一键冲突应 视为成功(查已有流水则直接返回当前 wallet 快照,不二次 inc)——可参考项目内其它 Free Credits 写法的异常处理,若无统一模式则在方法开头 findOne(['biz_id','biz_type']) 短路 |
刻意不做:
- 不调
finishWithdraw/doneWithdraw - 不
sendConsoleBus('Withdrawal')(避免与普通提现总线混淆) - 失败/拒绝路径 不 dec
total_withdraw(申请时未 inc,与manualRefund对称性无关)
2. slot_lib
| 文件 | 改动 |
|---|---|
| WalletService.php | 常量 WALLET_TYPE_FREE_CREDITS_FIRST_CASHOUT_STAT = 'freeCreditsFirstCashoutStat' + 方法 freeCreditsFirstCashoutStat($amount, $bizId = '') |
Pay 继续用现有 slotLib\services\WalletService(与 withdrawSuccess 同路径),不在本需求引入 slot_sdk(与当前 pay→wallet 一致)。
3. slot_pay
| 文件 | 改动 |
|---|---|
| EventWithdrawal.php | 第一档成功分支:在发 Console 总线 之后(或之前,顺序无关)调用 $walletService->freeCreditsFirstCashoutStat($withdrawalAmount, $order->order_id) |
| 可选对齐 | 普通成功会 UserTagService::incSuccessWithdrawalInfo;若产品希望第一档也计入「成功提现次数/金额」标签,可同分支补上;若仅关心 wallet_stat,可不加(需你确认时可单独加) |
失败/拒绝分支 保持现状(只发 Fail/Rejected 总线,不调 wallet)。
4. 测试
| 仓库 | 内容 |
|---|---|
slot_wallet |
单测:freeCreditsFirstCashoutStat 累加 total_withdraw、相同 biz_id 幂等 |
slot_pay |
扩展 WithdrawalOrderFreeCreditsTest.php 或 mock EventWithdrawal::updateOrder:第一档成功应调用新方法、不调 withdrawSuccess |
历史数据
已打款成功、但 total_withdraw 未记的第一档订单:可写一次性运维脚本(按 free_credits_package.withdraw_order_id + pay 订单金额)批量调新接口或 SQL inc,biz_id 用原 order_id 保证幂等。
涉及文件小结
- slot_wallet/app/api/logic/WalletLogic.php
- slot_wallet/app/model/multi/WalletLogModel.php
- slot_lib/src/services/WalletService.php
- slot_pay/app/command/EventWithdrawal.php
- 测试:
slot_wallet/tests/Unit/...、slot_pay/tests/Unit/WithdrawalOrderFreeCreditsTest.php
不改: FreeCreditsLogic::handleFirstCashoutResult(档位状态已覆盖)、Console EventBus 消费端。