## 目标 - 在管理端实时查看某一期每个 `slot_index` 对应的奖品与当前状态(名称、图片、等级、原始数量/剩余数量、是否已占用),支持分页与筛选。 ## 数据来源与算法 - 奖励配置:`activity_reward_settings`(name/level/product_id/original_qty/quantity/sort) - 奖品图片:`products.image`(如为实物奖关联商品) - 位置占用:`issue_position_claims`(唯一记录已占用 slot) - 承诺种子:`activities.commitment_seed_master`(HMAC-SHA256 确定性洗牌,活动级) - 映射生成: 1. 构造长度 N 的 `slots` 列表:按各奖励 `original_qty` 重复填入 `reward_id` 2. Fisher–Yates + `HMAC-SHA256(seed, "shuffle:"+i+"|issue:"+issueId)` 前 8 字节取模生成交换索引 3. 得到稳定映射 `slot_index → reward_id`;该映射在期内不变 ## 后端接口(只读) - 组:`/api/admin`(需登录与 RBAC:`ichiban:slots:view`) - `GET /api/admin/ichiban/activities/:activity_id/issues/:issue_id/slots` - 入参:`page`、`page_size`(默认 1/50),`claimed`(可选 true/false 过滤已占用状态) - 返回: - `total_slots`:N - `list[]`:{`slot_index`,`reward_id`,`reward_name`,`level`,`product_image`,`original_qty`,`remaining_qty`,`claimed`} - `seed_version`:活动承诺版本号,`rule`:`level_desc_sort_asc_id_asc` - 实现:按上述算法生成映射,联表/查询实时数量与占用状态;服务端分页 - `GET /api/admin/ichiban/issues/:issue_id/slot/:slot_index` - 返回单个位置详情与计算证明(HMAC 输入与结果),用于抽样核验 ## 服务与性能 - Service:`internal/service/activity/ichiban_slots_service.go` - `BuildMapping(issueID)`:读取奖励配置与种子,生成映射(1000+ 在 2s 内);可引入本地 LRU 缓存(TTL 60s) - `QuerySlots(issueID, page,size, claimed?)`:分页拼装响应,`remaining_qty` 直接读 `activity_reward_settings.quantity` - 性能优化: - 映射缓存 + 仅在奖励配置或种子变更时失效;可选将完整映射预生成入表以应对更大规模(保留扩展) - `issue_position_claims(issue_id,slot_index)` 与 `reward_id` 索引保障查询速度 ## 前端管理页面 - 路由:`/operations/ichiban/slots` - 组件:表格布局(分页、排序标签、序号列),筛选(活动/期、占用状态),图片懒加载 - 列:序号、奖品图、名称、等级标签、原始数量/剩余数量、占用状态;顶部显示 `seed_version` 与排序规则说明 ## 权限与审计 - 仅管理员可访问(`RequireAdminRole` + `RequireAdminAction("ichiban:slots:view")`) - 查询操作写入操作日志(模块/期次/分页参数) ## 验收标准 - 1000+ 奖品分页加载 ≤2s;映射稳定一致;显示字段完整;占用状态实时;筛选与分页正常 ## 交付内容 - 管理端两条 GET 接口与 Service - 管理页面与 API 封装 - 单元测试:映射稳定性、分页正确性、占用过滤 - 文档:算法与接口说明