# Claude Code 提示词:实现抽奖系统 ## 项目概述 这是一个年会抽奖系统,当前已有"抽人"功能(从88人中抽取中奖者)。现在需要新增一个"抽奖"页面,为88个人每人抽取一个奖品。 ## 核心需求 为88个人(LN-001 到 LN-088)抽取奖品,每人抽一次,共88次。奖品配置如下: 1. 快乐通勤奖(25个)- 可提前1小时下班或晚到1小时 2. 跑马场自由日(18个)- 可选在家或其他场所办公 3. 前途光明奖(2个)- 获得boss 1对1畅聊1小时 4. 现金红包500元(3个) 5. 现金红包300元(8个) 6. 现金红包200元(15个) 7. 现金红包100元(17个) ## 技术栈 - Vue 3 + TypeScript + Vite - Pinia (状态管理) - 复用现有组件和样式 ## 实现步骤 ### Step 1: 创建 Pinia Store 创建 `src/store/prizeDrawConfig.ts`,包含: - 奖品配置(7种奖品,共88个) - 人员列表(从 `defaultPersonList` 获取88个人) - 抽奖结果数组 - 抽奖逻辑: - `executeDraw()`: 随机从剩余人员中选一个,随机从剩余奖品中选一个,记录结果 - `reset()`: 重置所有数据 - `canDraw`: 计算属性,判断是否还能继续抽奖 - 使用 IndexedDB 持久化数据 ### Step 2: 创建页面组件 创建 `src/views/PrizeDraw/index.vue`,布局包含: 1. **顶部区域**:标题 + 进度(已抽 X/88) 2. **左侧/顶部**:奖品池展示(7个奖品卡片,显示剩余数量) 3. **中央区域**: - 大按钮:"开始抽奖" / "继续抽奖" / "抽奖完成" - 抽奖动画区域(可复用现有卡片动画) - 结果展示:人员编号 + 奖品名称 4. **右侧/底部**:已抽奖记录列表(可滚动) ### Step 3: 实现抽奖逻辑 ```typescript // 核心算法 function executeDraw() { // 1. 从剩余人员中随机选一个 const randomPersonIndex = Math.floor(Math.random() * remainingPersons.length) const person = remainingPersons.splice(randomPersonIndex, 1)[0] // 2. 从剩余奖品中随机选一个 const randomPrizeIndex = Math.floor(Math.random() * remainingPrizes.length) const prize = remainingPrizes.splice(randomPrizeIndex, 1)[0] // 3. 记录结果 drawResults.push({ drawIndex: drawResults.length + 1, personId: person.uid, personName: person.name, prizeId: prize.id, prizeName: prize.name, drawTime: new Date().toISOString() }) // 4. 更新奖品剩余数量 updatePrizeRemaining(prize.id) } ``` ### Step 4: 添加动画效果 - 点击按钮后,显示1-2秒的滚动/加载动画 - 可以复用 `src/views/Home` 中的卡片动画效果 - 结果展示时添加庆祝动画(可选) ### Step 5: 添加路由 在 `src/router/index.ts` 中添加: ```typescript { path: '/prize-draw', name: 'PrizeDraw', component: () => import('@/views/PrizeDraw/index.vue'), meta: { title: '抽奖系统' } } ``` ### Step 6: 添加导航入口 在主页或顶部菜单添加"抽奖"按钮,跳转到 `/prize-draw` ### Step 7: 实现额外功能 1. **导出功能**:将抽奖结果导出为 CSV/Excel 2. **重置功能**:清空所有数据,重新开始 3. **撤销功能**:撤销最后一次抽奖(可选) ## 数据结构参考 ```typescript // 奖品配置 interface Prize { id: string name: string description: string total: number // 总数量 remaining: number // 剩余数量 color: string // 显示颜色 } // 抽奖结果 interface DrawResult { drawIndex: number // 第几次抽奖 personId: string // LN-001 personName: string // LN-001 prizeId: string prizeName: string drawTime: string } ``` ## UI 要求 - 复用现有主题配置(绿色系:#4cb050, #05a045, #a5d6a7) - 响应式布局,支持移动端 - 动画流畅自然 - 进度清晰可见 ## 注意事项 1. 确保随机算法公平(使用 `Math.random()`) 2. 处理边界情况(最后一个人、最后一个奖品) 3. 数据持久化到 IndexedDB(刷新页面不丢失) 4. 代码结构清晰,遵循现有项目规范 ## 验收标准 - [ ] 可以完整执行88次抽奖 - [ ] 每个人只抽一次,每个奖品数量准确 - [ ] 动画效果流畅 - [ ] 数据可以持久化 - [ ] 可以导出结果 - [ ] 移动端可用 ## 开始实现 请按照上述步骤实现抽奖系统。如果有任何疑问,请先查看现有代码结构(特别是 `src/store/personConfig.ts` 和 `src/views/Home/index.vue`)作为参考。