Files
cursor/plans/移除_pending_popup_表_8fea9a4d.plan.md
ray zhou 2dd9f17da9 ok
2026-06-29 14:51:55 +08:00

168 lines
8.0 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.

---
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` 的断言(约 6178、9699 行)
- 新增用例:`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) §5Claim 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