- 新增 src/views/PrizeDraw 抽奖视图及抽奖配置 store - 更新 defaultPersonList 为 82 位真实参与者名单 - 调整主页、路由、i18n 及音乐播放以支持抽奖入口 - 附抽奖需求及实现报告文档 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.4 KiB
4.4 KiB
Claude Code 提示词:实现抽奖系统
项目概述
这是一个年会抽奖系统,当前已有"抽人"功能(从88人中抽取中奖者)。现在需要新增一个"抽奖"页面,为88个人每人抽取一个奖品。
核心需求
为88个人(LN-001 到 LN-088)抽取奖品,每人抽一次,共88次。奖品配置如下:
- 快乐通勤奖(25个)- 可提前1小时下班或晚到1小时
- 跑马场自由日(18个)- 可选在家或其他场所办公
- 前途光明奖(2个)- 获得boss 1对1畅聊1小时
- 现金红包500元(3个)
- 现金红包300元(8个)
- 现金红包200元(15个)
- 现金红包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,布局包含:
- 顶部区域:标题 + 进度(已抽 X/88)
- 左侧/顶部:奖品池展示(7个奖品卡片,显示剩余数量)
- 中央区域:
- 大按钮:"开始抽奖" / "继续抽奖" / "抽奖完成"
- 抽奖动画区域(可复用现有卡片动画)
- 结果展示:人员编号 + 奖品名称
- 右侧/底部:已抽奖记录列表(可滚动)
Step 3: 实现抽奖逻辑
// 核心算法
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 中添加:
{
path: '/prize-draw',
name: 'PrizeDraw',
component: () => import('@/views/PrizeDraw/index.vue'),
meta: { title: '抽奖系统' }
}
Step 6: 添加导航入口
在主页或顶部菜单添加"抽奖"按钮,跳转到 /prize-draw
Step 7: 实现额外功能
- 导出功能:将抽奖结果导出为 CSV/Excel
- 重置功能:清空所有数据,重新开始
- 撤销功能:撤销最后一次抽奖(可选)
数据结构参考
// 奖品配置
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)
- 响应式布局,支持移动端
- 动画流畅自然
- 进度清晰可见
注意事项
- 确保随机算法公平(使用
Math.random()) - 处理边界情况(最后一个人、最后一个奖品)
- 数据持久化到 IndexedDB(刷新页面不丢失)
- 代码结构清晰,遵循现有项目规范
验收标准
- 可以完整执行88次抽奖
- 每个人只抽一次,每个奖品数量准确
- 动画效果流畅
- 数据可以持久化
- 可以导出结果
- 移动端可用
开始实现
请按照上述步骤实现抽奖系统。如果有任何疑问,请先查看现有代码结构(特别是 src/store/personConfig.ts 和 src/views/Home/index.vue)作为参考。