Files
log-lottery/CLAUDE_CODE_PROMPT.md
kkfluous 25d0c95dc3 feat: 🎁 新增破冰抽奖功能及 82 人名单
- 新增 src/views/PrizeDraw 抽奖视图及抽奖配置 store
- 更新 defaultPersonList 为 82 位真实参与者名单
- 调整主页、路由、i18n 及音乐播放以支持抽奖入口
- 附抽奖需求及实现报告文档

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:29:52 +08:00

141 lines
4.4 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.
# 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`)作为参考。