Files
cursor/plans/邀请回调改mq_de5dd9d4.plan.md
ray zhou 2dd9f17da9 ok
2026-06-29 14:51:55 +08:00

180 lines
7.5 KiB
Markdown
Raw 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.

---
name: 邀请回调改MQ
overview: 将 agent → console 的 Lucky Rewards 邀请助力从 HTTP innerapi 改为经 `console_bus` MQ 投递;删除 innerapi 与 slot_sdk 对应方法console EventBus 消费后复用现有 `LuckyRewardInviteLogic::handleInviteBind()`
todos:
- id: agent-mq-producer
content: "slot_agent: Gateway 改发 console_bus MQ + MQBusEntity 常量"
status: completed
- id: console-consumer
content: "slot_console: EventBus 消费 TYPE_LUCKY_REWARD_INVITE_BIND + 删 innerapi Controller"
status: completed
- id: sdk-cleanup
content: "slot_sdk: 删除 luckyRewardInviteBindCallback 及 Entity"
status: completed
- id: tests-docs-mq
content: 单测 + 需求/deploy 文档更新
status: completed
isProject: false
---
# Agent 邀请回调改走 console_bus MQ
## 目标
- **删除**`POST /innerapi/lucky-reward/invite-bind-callback`、slot_sdk `luckyRewardInviteBindCallback`
- **新增**agent 发 MQ → console `event:bus` 消费 → 发 Spin / helper
- **复用**[`LuckyRewardInviteLogic::handleInviteBind()`](slot_console/app/api/logic/LuckyRewardInviteLogic.php) 业务不变;仍仅 `share_origin=wheel` 计转盘助力
```mermaid
sequenceDiagram
participant User as slot_user
participant AgentBus as agent_bus
participant Agent as slot_agent
participant ConsoleBus as console_bus
participant Console as slot_console
User->>AgentBus: TYPE_INVITE_BIND
Agent->>AgentBus: 建关系/绑码奖励
Agent->>ConsoleBus: TYPE_LUCKY_REWARD_INVITE_BIND
Console->>Console: handleInviteBind
```
对照现网邮件:[`EventBus::notifyRewardEmail()`](slot_agent/app/command/EventBus.php) 已用 `EXCHANGE_CONSOLE` + `QUEUE_CONSOLE_BUS`
---
## 1. MQ 契约
**Exchange / Queue**(与现网一致):
- Exchange: `slot_console``MQKeyManagerService::EXCHANGE_CONSOLE`
- Queue: `console_bus``MQKeyManagerService::QUEUE_CONSOLE_BUS`
**新事件类型**agent、console 两侧常量字符串一致):
```php
const TYPE_LUCKY_REWARD_INVITE_BIND = 'lucky_reward_invite_bind';
```
**消息体**(与现 HTTP body 同形,便于 DTO 复用):
```json
{
"uid": 2001,
"type": "lucky_reward_invite_bind",
"data": {
"event_id": "invite_bind:2001",
"inviter_uid": 100,
"invitee_uid": 2001,
"invite_code": "ABC123",
"channel_code": "default",
"bind_time": 1710000000,
"share_origin": "wheel",
"is_new_register": 1,
"landing_scene": "",
"landing_token": ""
}
}
```
- `uid` = **被邀请人** `invitee_uid`(对齐其它 console_bus 消息)
- `event_id` 仍用 `invite_bind:{invitee_uid}` 幂等
---
## 2. slot_agent生产者
**重构** [`LuckyRewardInviteCallbackGatewayService`](slot_agent/app/service/LuckyRewardInviteCallbackGatewayService.php)
| 变更 | 说明 |
| --- | --- |
| 删除 | `ConsoleClient`、slot_sdk Entity、`consoleApiHost`、HTTP 重试 |
| 保留 | `isEnabled` 开关、`share_origin=wheel` 粗筛、参数校验 |
| 新增 | `RabbitMqService::getInstance(EXCHANGE_CONSOLE, QUEUE_CONSOLE_BUS)->sendMessageByBusEntity(...)` |
[`MQBusEntity`](slot_agent/app/entity/mq/MQBusEntity.php) 增加 `TYPE_LUCKY_REWARD_INVITE_BIND`
[`LuckyRewardInviteCallbackResultEntity`](slot_agent/app/entity/lucky_reward/LuckyRewardInviteCallbackResultEntity.php)
- `dispatched=true` 表示 **MQ 发送成功**
- `reason``mq_failed` 替代 `http_failed`;去掉 `console_api_host_empty`
**触发点不变**
- [`EventBus::inviteBindEvent()`](slot_agent/app/command/EventBus.php)(新建关系)
- [`AgentLogic::bindInviteCode()`](slot_agent/app/innerapi/logic/AgentLogic.php)(手工绑码补偿)
**配置**[`LuckyRewardInviteCallbackConfigService`](slot_agent/app/service/LuckyRewardInviteCallbackConfigService.php) 可移除 `timeout`/`retrySleep`HTTP 专用);保留 `lucky_reward_callback_enabled`
---
## 3. slot_console消费者
**[`MQBusEntity`](slot_console/app/entity/mq/MQBusEntity.php)**:增加 `TYPE_LUCKY_REWARD_INVITE_BIND`
**[`EventBus::deal()`](slot_console/app/command/EventBus.php)**:新增 `case`,调用 private `luckyRewardInviteBindEvent(int $uid, array $data)`
```php
$callbackDto = InviteBindCallbackDTO::fromRequest($busEntity->data);
$result = (new LuckyRewardInviteLogic())->handleInviteBind($callbackDto);
LoggerService::info('lucky_reward_invite_bind', $result->activeData());
```
**[`InviteBindCallbackDTO`](slot_console/app/dto/luckyReward/InviteBindCallbackDTO.php)**`fromRequest()` 已可读 MQ `data` 数组无需改签名PHPDoc 注明 HTTP/MQ 共用。
**ack 策略**(对齐业务语义,非 5xx 不重试):
- `handleInviteBind` 正常返回(含 `skipped_*``already_processed`)→ **ack**
- 未捕获 `Throwable`DB 异常等)→ **log + ack**(与多数 console_bus 分支一致;避免无限 requeue。若需失败重试可后续单独加 dead-letter本期不扩 scope。
**删除** [`app/innerapi/controller/LuckyRewardController.php`](slot_console/app/innerapi/controller/LuckyRewardController.php)(仅此一个 action
---
## 4. slot_sdk清理
删除或不再使用:
- [`ConsoleService::luckyRewardInviteBindCallback()`](slot_sdk/src/service/console/ConsoleService.php)
- [`LuckyRewardInviteBindCallbackRequestEntity`](slot_sdk/src/service/console/entity/LuckyRewardInviteBindCallbackRequestEntity.php)
- [`LuckyRewardInviteBindCallbackResultEntity`](slot_sdk/src/service/console/entity/LuckyRewardInviteBindCallbackResultEntity.php)
保留 `freeCreditsStatistics/list`admin 仍用)。
agent `composer.json` 若仅为该回调依赖 console SDK 路径无需改依赖agent 仍可能间接用 slot_sdk 其它能力)。
---
## 5. 测试
| 仓库 | 用例 |
| --- | --- |
| slot_console | 新增 `EventBusLuckyRewardInviteBindTest`mock AMQPMessage`type=lucky_reward_invite_bind`,断言调用 Logic / ack参考 [`EventBusFreeCreditInitTest`](slot_console/tests/Unit/EventBusFreeCreditInitTest.php) |
| slot_console | 现有 [`LuckyRewardInviteBindIntegrationTest`](slot_console/tests/Integration/LuckyRewardInviteBindIntegrationTest.php) 继续直调 Logic不受影响 |
| slot_agent | 单测 Gatewaywheel 发 MQ、user_agent skip、disabled 不发(可 mock RabbitMqService 或测 payload 组装 private 方法) |
---
## 6. 文档
- [01_slot_agent邀请回调对接方案.md](docs/requirements/lucky_rewards/01_slot_agent邀请回调对接方案.md)HTTP 改 MQ 时序图、删除 §6.1 innerapi
- [05](docs/requirements/lucky_rewards/05_slot_console_邀请助力与弹窗方案.md) §3接收方式改为 console_bus
- [00](docs/requirements/lucky_rewards/00_整体技术方案.md) §3.5 时序图Agent→Console 改为 MQ
- [lucky_reward_deploy.md](slot_console/doc/lucky_reward_deploy.md):去掉 `consoleApiHost`agent 调 console与 innerapi 冒烟项;补充 console `event:bus` 需运行
---
## 7. 部署注意
- **无需** agent 配置 `consoleApiHost`(仅此回调)
- **必须** slot_console `php webman event:bus` 消费 `console_bus`(与邮件、注册等共用进程)
- 发版顺序建议:**console 先上消费** → **agent 再切 MQ 生产**,避免短暂消息无人消费(旧 agent HTTP + 新 console 无 innerapi 窗口)
---
## 涉及文件摘要
**改**`slot_agent` Gateway + MQBusEntity + Config`slot_console` EventBus + MQBusEntity
**删**`slot_console/app/innerapi/controller/LuckyRewardController.php`slot_sdk 3 个 invite callback 文件
**不动**`LuckyRewardInviteLogic` 核心判定、C 端 `/api/*`