--- name: 注册活动列表 game_id overview: 在 C 端活动列表(type=7 注册活动)透出 `game_id` 供前端展示/进游戏;同时从领取接口 `POST /api/gift/receive` 移除 `game_id` 字段,复用现有 `RegisterRewardLogic` 与 `ext_config.game_ids` 配置。 todos: - id: list-game-id content: ActivityConfigEntity::getGiftItemsByActivity type=7 分支调用 RegisterRewardLogic 写入 game_id status: completed - id: remove-receive-game-id content: ActivityConfigEntity::receive 移除注册活动 game_id 逻辑 status: completed - id: logic-stable-pick content: RegisterRewardLogic 增加 pickGameIdForUser(稳定随机)并更新注释 status: completed - id: phpdoc-tests content: GiftController PHPDoc 调整 + RegisterRewardLogicTest 补充用例 status: completed isProject: false --- # 注册活动列表透出 game_id,领取不再返回 ## 需求变更(相对初版) | 接口 | 原行为 | 目标行为 | |------|--------|----------| | `POST /api/gift/getActivityList` | 注册活动无 `game_id` | type=7 项增加可选 `game_id` | | `POST /api/gift/receive`(type=7) | 成功时随机返回 `game_id` | **仅** `gift_coin`、`gift_bonus` | 后台 `ext_config.game_ids` 配置与 [`RegisterRewardLogic`](slot_console/app/api/logic/RegisterRewardLogic.php) 过滤已上架游戏逻辑**保持不变**,仅调整调用位置。 ## 数据流 ```mermaid sequenceDiagram Client->>GiftController: getActivityList GiftController->>GiftService: getUserActivityList GiftService->>ActivityConfigEntity: getGiftItemsByActivity type=7 ActivityConfigEntity->>RegisterRewardLogic: pickGameId from ext_config.game_ids ActivityConfigEntity-->>Client: activity item with optional game_id Client->>GiftController: receive id=activityId GiftController->>ActivityConfigEntity: receive ACTIVITY_TYPE_REG ActivityConfigEntity-->>Client: gift_coin, gift_bonus only ``` ## 实现(仅 slot_console) ### 1. 活动列表组装:增加 `game_id` 文件:[`slot_console/app/entity/activity/ActivityConfigEntity.php`](slot_console/app/entity/activity/ActivityConfigEntity.php) 在 `getGiftItemsByActivity()` 的 `switch ($activityType)` 中新增 `ACTIVITY_TYPE_REG` 分支(与首充/兑换码同级,约在 340 行附近): - 用已有 `normalizeExtConfig($activity['ext_config'])` 读取 `game_ids` - 调用 `RegisterRewardLogic` 得到 `game_id` - 仅当非 `null` 时写入 `$activityInfo['game_id']`(与领取侧旧约定一致:**省略字段**而非 `0`) `$activity` 来自 `getActiveList()` 的 DB 模型,已含 `ext_config`;`ActivityConfigEntity` 在 `GiftService::getUserActivityList()` 中已通过 `setUid` / `setSource` 设置 `_modelId`。 **列表随机策略(建议默认)**:同一用户、同一活动多次拉列表应看到同一款游戏,避免卡片闪烁。在 `RegisterRewardLogic` 增加例如 `pickGameIdForUser(?array $extConfig, int $gameModelId, int $uid, int $activityId): ?int`: - 复用 `parseGameIds` + `GameApiModel::publishedGameIds` - 对 `published` **排序**后,用 `crc32("{$uid}:{$activityId}") % count` 取下标(非 `array_rand`) 列表与领取不再需要对齐,但稳定随机对仅列表展示更友好。若产品希望每次刷新换游戏,可继续用现有 `pickRandomGameId`。 ### 2. 领取分支:移除 `game_id` 同一文件 `receive()`: - 删除 `ACTIVITY_TYPE_REG` 内读取 `ext_config`、`RegisterRewardLogic::pickRandomGameId` 及 `$registerRewardGameId` 变量 - 删除返回数组末尾对 `game_id` 的合并(约 763–765 行) 注册发奖、`sendRegisterGiftWagerTask`、`setActivityFinishById` **不动**。 ### 3. Controller PHPDoc [`GiftController.php`](slot_console/app/api/controller/GiftController.php): - `receive()`:去掉 `game_id` 说明,仅 `gift_coin` / `gift_bonus` - 可选:为 `getActivityList()` 补充一行说明——type=7 且配置了有效 `game_ids` 时,对应项含 `game_id`(int) ### 4. Logic 注释与单测 [`RegisterRewardLogic.php`](slot_console/app/api/logic/RegisterRewardLogic.php):类注释改为「活动列表推荐进游戏」;保留 `pickRandomGameId` 或改为对外暴露 `pickGameIdForUser`(二选一,避免死代码)。 [`RegisterRewardLogicTest.php`](slot_console/tests/Unit/RegisterRewardLogicTest.php):为 `pickGameIdForUser` 增加确定性用例(相同 uid+activityId 同结果;无候选返回 null)。 ## 响应示例 **活动列表**(type=7 片段): ```json { "gift_id": 123, "type": 7, "title": "注册奖励", "gift_coin": "10.00", "gift_bonus": "0.00", "game_id": 205, "data": [{ "goods_id": -1, "gift_coin": "10.00", ... }] } ``` 无有效 `game_ids` / 无上架游戏:与现网其它活动项一致,**无 `game_id` 字段**。 **领取**: ```json { "gift_coin": "10.00", "gift_bonus": "0.00" } ``` ## 验证 1. 后台 type=7 活动配置 `ext_config.game_ids`(已有 admin 能力)。 2. `getActivityList`:未领取用户可见注册活动且含 `game_id`(在候选有效时)。 3. `receive`:成功响应**不含** `game_id`。 4. `game_ids` 为空或均未上架:列表无 `game_id`,领取正常。 5. Docker 内跑单测:`RegisterRewardLogicTest.php`。 ## 不涉及 - slot_admin / admin_vue(配置已具备) - 前端仓库(由 C 端自行改列表消费、去掉领取后对 `game_id` 的依赖)