Files
cursor/plans/Trial MQ PWA-b36a4d72.plan.md
ray zhou 2dd9f17da9 ok
2026-06-29 14:51:55 +08:00

137 lines
6.5 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.

<!-- b36a4d72-3fa9-424d-8f16-d5d3a861c06d -->
---
todos:
- id: "wallet-strip-mq"
content: "wallet bet/win/FreeSpinBetService 移除 trial MQ 发布bet 响应增加 is_fs_paid_bet"
status: pending
- id: "pwa-mq-publisher"
content: "PWA 新增 TrialRewardMqPublisher + MQKeyManager 常量(对齐 TrialRewardMQ"
status: pending
- id: "pwa-notify-service"
content: "PWA 新增 TrialRewardNotifyServicevalid_bet / fs_consume / task_completed + 共享配置与 Redis 去重)"
status: pending
- id: "pwa-hook-wallet"
content: "WalletService::bet/win 成功后调用 NotifyServiceWalletEntity 补充 is_fs_paid_bet / wallet_created_at"
status: pending
- id: "verify-flow"
content: "docker 内验证四条验收场景;跑 slot-backend 门禁"
status: pending
isProject: false
---
# Trial MQ 从 wallet 迁到 PWA
## 你的三点反馈(代码核对结论)
### 1. 下注金额 PWA 知道,代付留 wallet —— 同意
- PWA 所有厂商下注均经 [`WalletService::bet`](slot-pwa/app/service/WalletService.php),请求里已有 `fee``biz_id``round_id``game_category``vendor_game_id`
- FS 代付判定([`TrialFreeSpinRedisService`](slot-wallet/app/service/trial/TrialFreeSpinRedisService.php))和 `executeFreeSpinPaidBet` **继续留 wallet**
- PWA 只需 wallet 在 bet 响应里多回一个**是否 FS 代付**标记(如 `is_fs_paid_bet: true`),即可决定:
- FS 代付 → `valid_bet_amount = fee` 发 MQ
- 常规下注且非试玩期 → `valid_bet_amount = fee` 发 MQPWA 侧用 fee不再依赖 wallet 内部 withdraw/deposit 拆分)
- 试玩期纯体验金下注 → 不发 MQ
> 说明wallet 内部 `valid_bet` 原口径是 `withdraw + deposit`(不含 bonus 部分)。若业务接受「充值后用 fee 计入解锁流水」PWA 可直接用 fee**无需** wallet 扩展拆分字段。若以后要精确排除 bonus 扣款,再让 wallet 回 `valid_bet_amount` 即可。
### 2. grantTrial 的 task_completed 留 wallet —— 可接受,但当前无调用
全仓库 **没有任何服务**`type=trial_grant` / `grantTrial()`
`TrialTaskCompletedMqService` 在 wallet 里实际只有 **一条活路径**
- [`WalletLogic::win()`](slot-wallet/app/api/logic/WalletLogic.php) 试玩期派奖成功后 → `notifyIfBalanceReached`
`grantTrial()` 里的 MQ 是**预留死代码**(需求文档里的绑手机/绑邮箱补发体验金,尚未接入)。
### 3. 注册流程不走 grantTrial —— 你说得对
注册实际路径:
```mermaid
sequenceDiagram
participant Console as slot_console
participant Wallet as slot_wallet
Console->>Wallet: POST /api/wallet/update type=register
Wallet->>Wallet: WalletLogic.register + RegisterService
Note over Wallet: 写 frozen_bonus不发 trial MQ
```
[`UserRegisterEventService::reward()`](slot-console/app/service/user/UserRegisterEventService.php) 只发 `type=register`**不**调 `grantTrial`
`register()` 也**不**发 `task_completed` MQ。
因此:**充值前 $50 门槛任务**,目前是靠 **试玩期 win 派奖** 后 wallet 发 MQ 触发的,不是注册时触发。
---
## 目标架构
```mermaid
flowchart LR
Provider --> PWA
PWA -->|"HTTP bet/win fee+game_context"| Wallet
Wallet -->|"余额 + is_fs_paid_bet"| PWA
PWA -->|"trial_valid_bet / fs_consume / task_completed"| ActivityMQ
ActivityMQ --> Activity
```
**wallet 移除(游戏路径)**
- [`TrialValidBetNotifyService`](slot-wallet/app/service/trial/TrialValidBetNotifyService.php) 在 `bet()` 的调用
- [`TrialFreeSpinBetService`](slot-wallet/app/service/trial/TrialFreeSpinBetService.php) 内的 `TYPE_FS_CONSUME` MQ 发布
- [`TrialTaskCompletedMqService`](slot-wallet/app/service/trial/TrialTaskCompletedMqService.php) 在 `win()` 试玩期的调用
**wallet 保留**
- FS Redis 代付判定与 `executeFreeSpinPaidBet`
- `grantTrial()` 内 MQ死代码待绑手机/绑邮箱接入时生效)
**PWA 新增**
- `TrialRewardMqPublisher`exchange/queue 对齐 [`slot\foundation\Constants\MQ\TrialRewardMQ`](slot-foundation/src/Constants/MQ/TrialRewardMQ.php)
- `TrialRewardNotifyService`:在 [`WalletService::bet/win`](slot-pwa/app/service/WalletService.php) 钱包调用成功后投递 MQ
- bet + `!isTrialPhase`PWA 用 [`UserRechargeStatusService`](slot-pwa/app/service/user/UserRechargeStatusService.php) 判断)→ `trial_valid_bet_accumulate`
- bet + `is_fs_paid_bet`wallet 响应)→ `trial_valid_bet_accumulate`(全额 fee+ `trial_fs_consume`
- win + 试玩期 + 余额达标 → `trial_task_completed`Redis 48h 去重逻辑从 wallet 迁过来,读共享 Redis 配置)
**activity 不变**
- [`TrialRewardEventRouter`](slot-activity/app/service/mq/TrialRewardEventRouter.php) 消费格式不变
---
## 关键改动文件
| 仓库 | 文件 | 动作 |
|------|------|------|
| slot-wallet | `app/api/logic/WalletLogic.php` | bet/win 删 MQbet 响应加 `is_fs_paid_bet` |
| slot-wallet | `app/service/trial/TrialFreeSpinBetService.php` | 删 fs_consume MQ保留 Redis consume |
| slot-wallet | `app/entity/WalletEntity.php` | 可选加 `is_fs_paid_bet` 字段 |
| slot-pwa | `app/service/MQKeyManagerService.php` | 加 `EXCHANGE_TRIAL_REWARD` / `QUEUE_TRIAL_REWARD` |
| slot-pwa | `app/service/mq/TrialRewardMqPublisher.php` | 新建 |
| slot-pwa | `app/service/trial/TrialRewardNotifyService.php` | 新建valid_bet / fs_consume / task_completed |
| slot-pwa | `app/service/trial/TrialRewardShareConfigService.php` | 从 wallet 迁共享 Redis 配置读取 |
| slot-pwa | `app/service/WalletService.php` | bet/win 成功后调 NotifyService |
---
## 试玩期判定PWA 侧)
与 wallet 对齐,不依赖 `isTrialPhase` HTTP 字段:
- `!UserRechargeStatusService::hasRecharged(uid)`
- 且 wallet 返回的 `wallet_created_at``validity_hours` 内(需 PWA `WalletEntity` 增加该字段或 bet/win 时顺带读 wallet 接口)
---
## 本阶段明确不做
- 不改 `grantTrial` / 绑手机绑邮箱(无调用方)
- 不改 `slot-pay``first_deposit` / `deposit_accumulate` MQ
- 不迁 FS Redis 逻辑到 PWA
- 不在 wallet 侧继续发游戏相关 trial MQ
---
## 验收
1. 试玩期下注wallet 扣 frozen_bonus**无** trial MQ
2. 充值后常规下注PWA 发 `trial_valid_bet_accumulate`activity `valid_bet_amount` 累加
3. FS 代付下注wallet 不扣余额PWA 发 `fs_consume` + `valid_bet_accumulate`
4. 试玩期 win 余额达 $50PWA 发 `trial_task_completed`48h 去重)
5. 注册 `type=register`:行为不变,仍无 trial MQ