--- name: 定格冻结用户流水 overview: 在 slot_wallet 的 `freeCreditsFreeze` 成功扣款后,补充 `addTransactionRecord` 写入 C 端可见的 `user_transaction_log`;并在 slot_pwa 注册新 `transaction_type` 与列表筛选映射。 todos: - id: wallet-add-transaction content: WalletLogic::freeCreditsFreeze 增加 addTransactionRecord(type=65,负金额) status: pending - id: pwa-type-map content: slot_pwa UserTransactionLogService 注册 type 65 与展示名 status: pending - id: wallet-unit-test content: wallet 单测断言 freeCreditsFreeze 写入用户流水 status: pending - id: run-phpunit content: php82 跑 wallet 相关单测验证 status: pending isProject: false --- # freeCreditsFreeze 补充用户可见流水 ## 问题 [`WalletLogic::freeCreditsFreeze()`](slot_wallet/app/api/logic/WalletLogic.php) 当前仅: 1. `minus()` 扣减 deposit/withdraw 2. [`addLog()`](slot_wallet/app/api/logic/WalletLogic.php) 写入分表 **wallet_log**(`biz_type=freeCreditsFreeze`) **未**调用 [`addTransactionRecord()`](slot_wallet/app/api/logic/WalletLogic.php),因此 MQ 不会投递到 PWA,用户在 **Transaction / 流水页** 看不到定格扣款记录。 对比:普通提现冻结在同文件内已有: ```402:402:slot_wallet/app/api/logic/WalletLogic.php $this->addTransactionRecord('withdraw frozen', $this->requestDTO->fee * -1, $balance, 7); ``` 需求文档 §15.2 要求「必须写钱包流水」——`wallet_log` 已满足后台审计;本需求补齐 **C 端展示流水**。 ```mermaid flowchart LR freeze[freeCreditsFreeze] addLog[addLog wallet_log] addTx[addTransactionRecord] mq[PWA MQ] ui[用户流水列表] freeze --> addLog freeze --> addTx --> mq --> ui ``` 说明:`freeCreditsFreeze` 是**扣款**(金额为负),不是入账;用户列表里应显示为负向变动(与 type 7「Withdraw」冻结类似)。 ## 实现方案(slot_wallet + slot_pwa) ### 1. slot_wallet — `freeCreditsFreeze` 增加用户流水 文件:[`WalletLogic.php`](slot_wallet/app/api/logic/WalletLogic.php) 在事务内、`addLog` 成功之后、`commit` 之前增加(与 `withdrawFrozen` 一致,失败仅记日志不回滚主事务): ```php $this->addTransactionRecord( 'Free Credits Freeze', $this->requestDTO->fee * -1, $balance, self::TRANSACTION_TYPE_FREE_CREDITS_FREEZE // 新常量,建议 65 ); ``` 在 `WalletLogic` 类内新增常量(或集中放在与 PWA 对齐的注释块): ```php /** 用户流水类型:首充定格冻结扣款,对应 freeCreditsFreeze */ private const TRANSACTION_TYPE_FREE_CREDITS_FREEZE = 65; ``` 字段约定(与现有 `addTransactionRecord` 一致): | 字段 | 值 | | --- | --- | | `subject` | `Free Credits Freeze`(C 端 `name` 映射用) | | `amount` | `-fee`(千分位,负数为扣款) | | `balance_after` | 扣款后 `deposit + withdraw` 总余额 | | `transaction_id` | 已有规则:`substr(uid,0,3) + biz_id`(幂等键 `free_credits_freeze:{orderId}`) | | `transaction_type` | `65` | **不**改 `addLog` / 余额扣减逻辑;**不**改 slot_console / slot_lib。 ### 2. slot_pwa — 注册 transaction_type=65 文件:[`UserTransactionLogService.php`](slot_pwa/app/service/UserTransactionLogService.php) - `$typeMaps[-1]`(All)增加 `65` - `$typeMaps[1]`(Withdraw 分类,已含 7/8)增加 `65`(定格扣款与提现类支出归同一 tab,可按产品再调) - `$typeToClient[65] = 'Free Credits Freeze'`(或简短文案 `Free Credits`) 可选:在 [`UserTransactionLogShardModel.php`](slot_pwa/app/model/shard/UserTransactionLogShardModel.php) 增加 `TRANSACTION_TYPE_FREE_CREDITS_FREEZE = 65` 常量与注释,wallet 侧用相同数字(wallet 不依赖 pwa 类,注释对齐即可)。 ### 3. 单测 | 仓库 | 文件 | 内容 | | --- | --- | --- | | slot_wallet | 扩展 [`WalletLogicHarness`](slot_wallet/tests/Support/WalletLogicHarness.php) 或新建用例 | 覆写/桩 `addTransactionRecord`,断言 `freeCreditsFreeze` 成功后调用一次,且 `amount < 0`、`type=65` | | slot_wallet | 现有 freeze 相关测 | 回归通过 | 运行: ```bash docker exec -w /app/www/slot/slot_wallet php82 ./vendor/bin/phpunit tests/Unit/WalletFreeCreditsFirstKeepTest.php tests/Unit/WalletFreeCreditInitBusTest.php # 若有新增 FreezeTransactionTest 则一并跑 ``` ## 不在本次范围 - `freeCreditsClaim` / `freeCreditsFirstCashKeep` 的用户流水(若也要在流水页展示入账,可另开任务,同样走 `addTransactionRecord` + 新 type) - 修改 `wallet_log` 表结构 - C 端 UI 文案多语言(仅后端 `name` 英文字段) ## 验收 1. 首充定格成功后,用户流水列表(All / Withdraw)出现一条 **负金额** 记录,`name` 为 Free Credits Freeze 2. `transaction_id` 与 `biz_id`(`free_credits_freeze:{orderId}`)可追溯 3. 幂等重试 freeze:wallet_log 幂等不变;若 MQ 重复需依赖现有消费端去重(与 type 7 行为一致,本次不单独改 MQ) 4. wallet 单测通过