--- 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 + 重构 buildSupportInvitePopup;HomeEvent 接入 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` 给被邀请人预发 Spin(grant_type=3 / `claim-invitee-spin`)。 - **产品本意**:被邀请人 Spin 来自**开宝箱**既有流程([`LuckyRewardLogic::openBox`](slot_console/app/api/logic/LuckyRewardLogic.php) 内 `createOpenBoxAutoFirstSpinRecord` + `grantDailySpinIfNeeded`),**不**单独配置「被邀请人 Spin 次数」。 - **Support Invite(PRD 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 grant;invitee `spin_available` 仍为 0 | | invitee HomeEvent(helper + 有效 cycle) | 自动 `openBox` 一次;`spin_available` 来自 daily/openBox 逻辑;Support Invite 有 `my_amount_qf` | | 过期短码 invite_bind | `skipped_expired_cycle`;无 helper;HomeEvent 无开箱、无 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` 数据。