This commit is contained in:
ray zhou
2026-06-29 14:51:55 +08:00
parent 225fb2bd28
commit 2dd9f17da9
319 changed files with 29461 additions and 9412 deletions

View File

@@ -0,0 +1,167 @@
---
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