Files
cursor/plans/移除被邀请人spin配置_a6751847.plan.md
ray zhou 2dd9f17da9 ok
2026-06-29 14:51:55 +08:00

141 lines
6.7 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: 移除被邀请人Spin配置
overview: 去掉错误的「被邀请人 invite_bind 发 Spin / invitee_spin_reward」能力保留 PRD 4.3 Support Invite在轮次有效期内按 helper 关系为被邀请人自动开宝箱一次(复用现有 openBox 自动 Spin过期轮次不建 helper、不开箱、不弹窗。
todos:
- id: remove-invitee-spin-grant
content: 删除 grantInviteeSpin/claim-invitee-spin/ProcessContext invitee 字段及 Controller 路由
status: completed
- id: support-invite-auto-openbox
content: 实现 ensureInviteeAutoOpenBox + 重构 buildSupportInvitePopupHomeEvent 接入
status: completed
- id: admin-remove-invitee-config
content: Admin/API/Model 去掉 invitee_spin_reward 配置项
status: completed
- id: docs-tests-invitee-removal
content: 更新 05/API 文档;调整集成测并跑 verify
status: completed
isProject: false
---
# 移除被邀请人 Spin 配置,改为 helper + 自动开宝箱
## 背景澄清
- **错误理解**`invitee_spin_reward` + `invite_bind` 给被邀请人预发 Spingrant_type=3 / `claim-invitee-spin`)。
- **产品本意**:被邀请人 Spin 来自**开宝箱**既有流程([`LuckyRewardLogic::openBox`](slot_console/app/api/logic/LuckyRewardLogic.php) 内 `createOpenBoxAutoFirstSpinRecord` + `grantDailySpinIfNeeded`**不**单独配置「被邀请人 Spin 次数」。
- **Support InvitePRD 4.3)保留**:有效期内按 **helper 关系**处理;**自动开宝箱一次**;轮次过期则**无 helper、不自动开箱、不弹 Support Invite**(与已有 `skipped_expired_cycle` 一致)。
```mermaid
sequenceDiagram
participant User as slot_user_register
participant Logic as LuckyRewardInviteLogic
participant Home as HomeEvent
participant Box as LuckyRewardLogic_openBox
User->>Logic: invite_bind wheel有效短码
alt cycle有效
Logic->>Logic: helper+邀请人pending_spin
Note over Logic: 不再 grantInviteeSpin
else cycle过期
Logic-->>User: skipped_expired_cycle
end
User->>Home: 被邀请人回大厅
alt helper存在且cycle有效且未开箱
Home->>Logic: ensureInviteeAutoOpenBox
Logic->>Box: openBox一次
Home->>User: SupportInvite弹窗my_amount
else 过期或无helper
Home-->>User: 无SupportInvite
end
```
---
## 1. 删除「被邀请人发 Spin」链路
### slot_console Logic / API
| 删除/停用 | 文件 |
|-----------|------|
| `grantInviteeSpinForHelper()` 及事务内调用 | [`LuckyRewardInviteLogic.php`](slot_console/app/api/logic/LuckyRewardInviteLogic.php) |
| `claimInviteeSpin()` / `claimPendingSpinByGrantType(... INVITEE)` | 同上 |
| `POST claim-invitee-spin` | [`LuckyRewardController.php`](slot_console/app/api/logic/LuckyRewardController.php) + 路由 |
| `InviteBindProcessContextDTO``inviteeSpinReward``inviteeBizId` | [`InviteBindProcessContextDTO.php`](slot_console/app/dto/luckyReward/InviteBindProcessContextDTO.php) |
保留 `LuckyRewardSpinGrantModel::GRANT_TYPE_INVITEE` / 历史 grant 只读兼容(不在新流程写入)。
### 配置与后台
| 项 | 处理 |
|----|------|
| [`lucky_reward_config.invitee_spin_reward`](backend/slot_admin/db/lucky_reward.sql) | **停止读写**;可选后续 DDL 删列(本次可留列默认 0避免强迁移 |
| Admin 列表/编辑「被邀请人Spin」 | [`backend/slot_admin_vue/.../luckyReward/config/*.vue`](backend/slot_admin_vue/src/views/game/luckyReward/config/) 移除字段 |
| slot_console 保存配置 API | 若 DTO/Validator 含该字段,一并移除 |
| [`LuckyRewardConfigModel`](slot_console/app/model/common/LuckyRewardConfigModel.php) `@property` | 标注废弃或删除 |
### 文档
- 更新 [`05_slot_console_邀请助力与弹窗方案.md`](docs/requirements/lucky_rewards/05_slot_console_邀请助力与弹窗方案.md):删除被邀请人 grant/claim 描述;改为「被邀请人 Spin = 开宝箱流程」。
- 更新 [`lucky_reward_api.md`](slot_console/doc/lucky_reward_api.md):移除 `claim-invitee-spin`
- 在 PRD 侧注记:`invitee_spin_reward` 配置项作废(可选改 [`转盘活动-功能需求文档.md`](docs/requirements/转盘活动-功能需求文档.md) 配置表一行)。
---
## 2. Support Invite + 自动开宝箱(有效期内)
### 新增编排(`LuckyRewardInviteLogic`
**`ensureInviteeAutoOpenBox(int $uid, string $source): void`**
1. 解析 active cycle`resolveActiveCycle`);无进行中轮次 → return。
2. `LuckyRewardHelperModel::findByInviteeAndCycle($uid, $cycleId)` 无记录 → return无 helper 不开箱)。
3. `LuckyRewardPlayerModel``box_opened_at > 0` → return幂等
4. 调用 [`LuckyRewardLogic::openBox($uid, $source)`](slot_console/app/api/logic/LuckyRewardLogic.php)(吞「已开箱」类 BusinessException打 info 日志)。
**重构 `buildSupportInvitePopup()`**
- **删除**对 `findUnclaimedInviteeGrant` / `pending_spin_count` 的依赖。
- **条件**helper 存在 + active cycle 有效(`end_at > now`+ 已开箱(可先调 `ensureInviteeAutoOpenBox` 再读 player
- **payload**:邀请人头像/昵称、`my_amount_qf``target_amount_qf`(去掉 spin 待领字段)。
### HomeEvent 接入
[`HomeEvent::appendLuckyRewardHomePopups`](slot_console/app/command/event/HomeEvent.php) 顺序调整为:
```php
$inviteLogic->ensureInviteeAutoOpenBox($uid, $source);
$supportInvitePop = $inviteLogic->buildSupportInvitePopup($uid, $source);
// 再 merge pendingPopup...
```
过期 wheel 短码:`invite_bind``skipped_expired_cycle`**无 helper** → 上述两步自然 no-op。
---
## 3. 邀请人侧不变
- 邀请人仍:`pending_spin_count` + Claim Now 弹窗 + `claim-inviter-spin`
- wheel 分享 cycle 绑定方案**不改动**。
---
## 4. 测试
| 用例 | 预期 |
|------|------|
| invite_bind 成功 | 仅 inviter grant/helper**无** invitee grantinvitee `spin_available` 仍为 0 |
| invitee HomeEventhelper + 有效 cycle | 自动 `openBox` 一次;`spin_available` 来自 daily/openBox 逻辑Support Invite 有 `my_amount_qf` |
| 过期短码 invite_bind | `skipped_expired_cycle`;无 helperHomeEvent 无开箱、无 Support Invite |
| 删除 claim-invitee-spin 相关集成测 | 改为 auto openBox + Support Invite 断言 |
更新 [`LuckyRewardInviteBindIntegrationTest`](slot_console/tests/Integration/LuckyRewardInviteBindIntegrationTest.php)、[`LuckyRewardDbTestCase`](slot_console/tests/Integration/LuckyRewardDbTestCase.php)(去掉 `invitee_spin_reward` seed
---
## 5. 不在本次范围
- 修改开宝箱 / 每日 Spin 核心算法(仅**复用** `openBox`)。
- 删除 DB 列 `invitee_spin_reward`(可后续单独 migration
- 清理历史 `grant_type=3` 数据。