137 lines
6.5 KiB
Markdown
137 lines
6.5 KiB
Markdown
<!-- 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 新增 TrialRewardNotifyService(valid_bet / fs_consume / task_completed + 共享配置与 Redis 去重)"
|
||
status: pending
|
||
- id: "pwa-hook-wallet"
|
||
content: "WalletService::bet/win 成功后调用 NotifyService;WalletEntity 补充 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` 发 MQ(PWA 侧用 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 删 MQ;bet 响应加 `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 余额达 $50:PWA 发 `trial_task_completed`(48h 去重)
|
||
5. 注册 `type=register`:行为不变,仍无 trial MQ
|