168 lines
8.0 KiB
Markdown
168 lines
8.0 KiB
Markdown
---
|
||
name: 移除 pending popup 表
|
||
overview: 移除 Lucky Rewards 转盘邀请人 Claim Now 弹窗对 `user_pending_popup` 的依赖,改为在 HomeEvent 中根据 `lucky_reward_player.pending_spin_count > 0` 动态构建弹窗;未领取前每次回大厅重复展示,直至 `claim-inviter-spin` 清零。
|
||
todos:
|
||
- id: build-inviter-popup
|
||
content: LuckyRewardInviteLogic 新增 buildInviterClaimNowPopup(),删除 notifyInviterInviteSuccess/enqueue
|
||
status: completed
|
||
- id: home-event-simplify
|
||
content: HomeEvent 改用 buildInviterClaimNowPopup,移除 PendingPopupService
|
||
status: completed
|
||
- id: remove-pending-popup-infra
|
||
content: 删除 PendingPopupService/Model/DTO/Entity 及 deploy DDL 引用
|
||
status: completed
|
||
- id: update-tests-docs
|
||
content: 更新集成测、需求文档与 lucky_reward_deploy 冒烟说明
|
||
status: completed
|
||
isProject: false
|
||
---
|
||
|
||
# 移除 user_pending_popup,改用 pending_spin_count 驱动转盘弹窗
|
||
|
||
## 背景与结论
|
||
|
||
当前邀请人「Claim Now」弹窗存在**双源**:
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant InviteBind as invite_bind
|
||
participant Player as lucky_reward_player
|
||
participant Grant as lucky_reward_spin_grant
|
||
participant Popup as user_pending_popup
|
||
participant Home as HomeEvent
|
||
|
||
InviteBind->>Grant: 写 invite_inviter grant
|
||
InviteBind->>Player: pending_spin_count += N
|
||
InviteBind->>Popup: enqueue lr_invite:{cycle}:{invitee}
|
||
Home->>Popup: fetchPending + consume
|
||
Home->>Player: resolvePendingSpinCount 注入 payload
|
||
```
|
||
|
||
- [`LuckyRewardInviteLogic::notifyInviterInviteSuccess()`](slot_console/app/api/logic/LuckyRewardInviteLogic.php) 入队 `user_pending_popup`
|
||
- [`HomeEvent::appendLuckyRewardHomePopups()`](slot_console/app/command/event/HomeEvent.php) 再读 `pending_spin_count` 注入 payload
|
||
|
||
**全仓库检索结果**:`PendingPopupService` / `user_pending_popup` **仅被 Lucky Rewards 使用**,无其它业务消费者。可以按你的要求移除该表及相关代码,改以 player 表为唯一触发源。
|
||
|
||
你已确认弹窗行为:**`pending_spin_count > 0` 时每次回大厅都弹,直到 `claim-inviter-spin` 领完**(比旧「consume 后不再弹」更符合待领语义)。
|
||
|
||
---
|
||
|
||
## 目标行为
|
||
|
||
| 场景 | 是否弹 Claim Now | 数据来源 |
|
||
| --- | --- | --- |
|
||
| `pending_spin_count > 0` | 是,每次 HomeEvent flush | [`resolvePendingSpinCount()`](slot_console/app/api/logic/LuckyRewardInviteLogic.php) |
|
||
| 领取后 `pending_spin_count = 0` | 否 | claim 流程已有扣减 |
|
||
| `inviter_spin_reward = 0` | 否(无待领 Spin) | 与 grant 逻辑一致 |
|
||
| 多次邀请、多笔待领 | **一条**弹窗,`pending_spin_count` 为累计值;被邀请人信息取**最早未领** grant | [`findUnclaimedInviterGrant()`](slot_console/app/model/common/LuckyRewardSpinGrantModel.php) + 解析 `biz_id` `invite_inviter:{cycle_id}:{invitee_uid}` |
|
||
|
||
弹窗 payload 保持与现网客户端兼容(`type: lucky_reward_invite_success`):
|
||
|
||
```json
|
||
{
|
||
"type": "lucky_reward_invite_success",
|
||
"data": {
|
||
"invitee_uid": 200001,
|
||
"invitee_nickname": "Alice",
|
||
"invitee_avatar": "3",
|
||
"spin_reward": 1,
|
||
"cycle_id": 34,
|
||
"pending_spin_count": 2,
|
||
"title": "LUCKY YOU!",
|
||
"content": "You've received 1 Free Spin",
|
||
"button_text": "Claim Now",
|
||
"priority": 50
|
||
}
|
||
}
|
||
```
|
||
|
||
- `spin_reward`:当前最早未领 grant 的 `spin_count`(通常 1)
|
||
- `pending_spin_count`:player 累计待领总数(已有 [`resolvePendingSpinCount()`](slot_console/app/api/logic/LuckyRewardInviteLogic.php))
|
||
|
||
Support Invite(被邀请人)弹窗**不变**,仍走 [`buildSupportInvitePopup()`](slot_console/app/api/logic/LuckyRewardInviteLogic.php) + `ensureInviteeAutoOpenBox()`。
|
||
|
||
---
|
||
|
||
## 代码改动
|
||
|
||
### 1. 新增邀请人弹窗构建方法
|
||
|
||
在 [`LuckyRewardInviteLogic`](slot_console/app/api/logic/LuckyRewardInviteLogic.php) 增加 public 方法,例如 `buildInviterClaimNowPopup(int $uid, string $source): array|false`:
|
||
|
||
- 活动关闭 / 无有效轮次 → `false`
|
||
- `resolvePendingSpinCount($uid, $source) <= 0` → `false`
|
||
- 取 `findUnclaimedInviterGrant($uid, $cycleId)`;若 grant 为空但 count>0(脏数据)→ 打 error 日志并 `false`
|
||
- 从 grant `biz_id` 解析 `invitee_uid`,`fetchUserProfile()` 取昵称/头像
|
||
- 返回与现网一致的 `type` + `data` 结构
|
||
|
||
### 2. 简化 HomeEvent
|
||
|
||
[`HomeEvent::appendLuckyRewardHomePopups()`](slot_console/app/command/event/HomeEvent.php):
|
||
|
||
- 删除 `PendingPopupService` 引用及 `fetchPending` / `consume` 循环
|
||
- 在 Support Invite 之后调用 `buildInviterClaimNowPopup()`,有则 `$luckyRewardPopups[]` 追加
|
||
- `pending_spin_count` 已在 popup data 内组装,无需二次注入
|
||
|
||
### 3. 删除 invite_bind 入队逻辑
|
||
|
||
[`LuckyRewardInviteLogic`](slot_console/app/api/logic/LuckyRewardInviteLogic.php):
|
||
|
||
- 删除 `notifyInviterInviteSuccess()` 及对 `PendingPopupService::enqueue` 的调用(`handleInviteBind` 第 108 行)
|
||
- 移除 `PendingPopupService` / `PendingPopupEnqueueDTO` 依赖
|
||
- `InviteBindProcessContextDTO::$popupBizId` 若仅用于 popup,可一并删除(保留 `inviterBizId` 供 grant 幂等)
|
||
|
||
### 4. 移除 pending popup 基础设施(无其它引用)
|
||
|
||
删除 slot_console 内:
|
||
|
||
- [`app/service/PendingPopupService.php`](slot_console/app/service/PendingPopupService.php)
|
||
- [`app/model/common/UserPendingPopupModel.php`](slot_console/app/model/common/UserPendingPopupModel.php)
|
||
- [`app/dto/pendingPopup/PendingPopupEnqueueDTO.php`](slot_console/app/dto/pendingPopup/PendingPopupEnqueueDTO.php)
|
||
- [`app/entity/pendingPopup/*`](slot_console/app/entity/pendingPopup/)
|
||
|
||
DDL / 部署文档:
|
||
|
||
- [`backend/slot_admin/db/user_pending_popup.sql`](backend/slot_admin/db/user_pending_popup.sql) 标记废弃或删除
|
||
- 可选新增 `backend/slot_admin/db/user_pending_popup_drop.sql`(`DROP TABLE IF EXISTS user_pending_popup`)供已部署环境执行
|
||
- 更新 [`slot_console/doc/lucky_reward_deploy.md`](slot_console/doc/lucky_reward_deploy.md) 部署步骤(去掉第 2 步建表)
|
||
|
||
### 5. 测试
|
||
|
||
更新 [`LuckyRewardInviteBindIntegrationTest`](slot_console/tests/Integration/LuckyRewardInviteBindIntegrationTest.php):
|
||
|
||
- 删除对 `UserPendingPopupModel` 的断言(约 61–78、96–99 行)
|
||
- 新增用例:`buildInviterClaimNowPopup` 在 bind 后返回非 false,且含 `pending_spin_count`;`claimInviterSpin` 后返回 false
|
||
|
||
更新 [`LuckyRewardDbTestCase`](slot_console/tests/Integration/LuckyRewardDbTestCase.php):
|
||
|
||
- 去掉 `user_pending_popup` 表存在性检查与 cleanup
|
||
|
||
可选:新增单元测覆盖 `buildInviterClaimNowPopup` 的 grant biz_id 解析(mock 较少时可放集成测)。
|
||
|
||
### 6. 文档
|
||
|
||
- [`docs/requirements/lucky_rewards/05_slot_console_邀请助力与弹窗方案.md`](docs/requirements/lucky_rewards/05_slot_console_邀请助力与弹窗方案.md) §5:Claim Now 改为 `pending_spin_count > 0` + `buildInviterClaimNowPopup`
|
||
- [`docs/requirements/lucky_rewards/07_用户定向弹窗通知机制方案.md`](docs/requirements/lucky_rewards/07_用户定向弹窗通知机制方案.md):标注 Lucky Rewards 已不再使用通用表;若整表无其它用途则机制废弃
|
||
- [`lucky_reward_deploy.md`](slot_console/doc/lucky_reward_deploy.md) 冒烟:邀请人回大厅见 Claim Now(可重复至领取)
|
||
|
||
---
|
||
|
||
## 行为差异说明(验收时注意)
|
||
|
||
| 项 | 旧(user_pending_popup) | 新(pending_spin_count) |
|
||
| --- | --- | --- |
|
||
| 未点 Claim 再次回大厅 | 不再弹(已 consume) | **继续弹**(你已确认) |
|
||
| 多笔邀请 | 可能多条 popup 队列 | **一条**,count 累计 |
|
||
| inviter_spin_reward=0 | 仍入队通知 | **不弹**(count 为 0) |
|
||
|
||
---
|
||
|
||
## 验收清单
|
||
|
||
1. invite_bind success → `pending_spin_count` 增加,**不写** `user_pending_popup`
|
||
2. 邀请人 HomeEvent → popList 含 `lucky_reward_invite_success`,`pending_spin_count` 正确
|
||
3. 未 claim 前多次回大厅 → 弹窗仍出现
|
||
4. `POST claim-inviter-spin` 后 → `pending_spin_count=0`,弹窗不再出现
|
||
5. 被邀请人 Support Invite + auto openBox 不受影响
|
||
6. `RUN_DB_TESTS=1` 集成测通过;verify + php -l PASS
|