# 奖品抽取程序 **Repository Path**: joshua_er/prize-extraction-program ## Basic Information - **Project Name**: 奖品抽取程序 - **Description**: 用户需要输入用户名才能抽奖(用户名预先配置在数据表中),否则无法进入。奖品号表中可以配置奖品。一人对应一份奖品。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-27 - **Last Updated**: 2026-03-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 抽奖系统 API 基于 Node.js Koa2 和 MongoDB 的抽奖系统后端服务,配合 Vue 3 前端实现完整的抽奖功能。 ## 环境要求 - Node.js >= 14.0.0 - MongoDB >= 4.0 ## 项目结构 ``` drawlots-api/ ├── backend/ # 后端服务 │ ├── config/ │ │ └── database.js # 数据库配置 │ ├── models/ │ │ ├── User.js # 用户模型 │ │ ├── Prize.js # 奖品模型 │ │ └── UserPrize.js # 用户奖品关联模型 │ ├── controllers/ │ │ ├── userController.js # 用户控制器 │ │ ├── prizeController.js # 奖品控制器 │ │ └── drawController.js # 抽奖控制器 │ ├── routes/ │ │ ├── userRoutes.js # 用户路由 │ │ ├── prizeRoutes.js # 奖品路由 │ │ └── drawRoutes.js # 抽奖路由 │ ├── .env # 环境变量配置 │ ├── .env.example # 环境变量示例 │ ├── .gitignore # Git忽略文件 │ ├── app.js # Koa应用配置 │ ├── index.js # 入口文件 │ └── package.json # 项目依赖 └── frontend/ # 前端应用 ├── src/ │ ├── App.vue # 主应用组件 │ ├── main.js # 入口文件 │ └── style.css # 全局样式 ├── .env # 前端环境变量 ├── index.html # HTML模板 ├── package.json # 前端依赖 └── vite.config.js # Vite配置 ``` ## 快速开始 ### 1. 安装后端依赖 ```bash npm install ``` ### 2. 配置环境变量 复制 `.env.example` 文件为 `.env`,并根据实际情况修改配置: ```bash cp .env.example .env ``` `.env` 文件内容: ```env # MongoDB数据库配置 MONGODB_URI=mongodb://172.16.20.21:39099 DB_NAME=drawlots-system # 服务器端口 PORT=3000 ``` ### 3. 启动后端服务 ```bash npm start ``` 后端服务将在 `http://localhost:3000` 启动。 ### 4. 安装前端依赖 ```bash cd frontend npm install ``` ### 5. 启动前端服务 ```bash npm run dev ``` 前端服务将在 `http://localhost:5173` 启动。 ## 数据库表结构 ### 1. 用户表 (users) ```javascript { _id: ObjectId, name: String, // 用户名称(唯一) createdAt: Date // 创建时间 } ``` ### 2. 奖品表 (prizes) ```javascript { _id: ObjectId, prizeNumber: String, // 奖品号(唯一) createdAt: Date // 创建时间 } ``` ### 3. 用户奖品关联表 (user_prizes) ```javascript { _id: ObjectId, userId: ObjectId, // 用户ID(唯一) prizeId: ObjectId, // 奖品ID(唯一) drawnAt: Date // 抽奖时间 } ``` ## 核心API接口 ### 接口1:验证用户资格 验证用户是否在用户列表中。 **请求:** ``` POST /api/draw/verify Content-Type: application/json { "username": "张三" } ``` **响应示例(验证成功):** ```json { "success": true, "message": "验证成功", "data": { "userId": "...", "username": "张三" } } ``` **响应示例(无资格):** ```json { "success": false, "message": "您没有参与资格" } ``` --- ### 接口2:抽奖接口 随机抽取奖品并分配给用户。 **请求:** ``` POST /api/draw Content-Type: application/json { "username": "张三" } ``` **响应示例(抽奖成功):** ```json { "success": true, "message": "抽奖成功,您抽中的号码是一等奖", "data": { "username": "张三", "prizeNumber": "一等奖", "drawnAt": "2024-01-01T00:00:00.000Z" } } ``` **响应示例(已抽过奖):** ```json { "success": false, "message": "您已经抽过奖了", "data": { "prizeNumber": "一等奖" } } ``` **响应示例(无资格):** ```json { "success": false, "message": "您没有参与资格" } ``` --- ### 接口3:查询抽奖结果 查询用户抽中的奖品号。 **请求:** ``` POST /api/draw/query Content-Type: application/json { "username": "张三" } ``` **响应示例(已抽奖):** ```json { "success": true, "message": "查询成功", "data": { "username": "张三", "prizeNumber": "一等奖", "drawnAt": "2024-01-01T00:00:00.000Z" } } ``` **响应示例(未抽奖):** ```json { "success": false, "message": "您还没有抽奖" } ``` --- ### 接口4:获取剩余奖品数量 获取当前剩余奖品数量(用于前端轮询)。 **请求:** ``` GET /api/draw/remaining ``` **响应示例:** ```json { "success": true, "data": { "totalPrizes": 10, "drawnPrizesCount": 3, "remainingCount": 7 } } ``` --- ### 接口5:获取所有奖品列表 获取所有奖品列表(用于显示转盘)。 **请求:** ``` GET /api/draw/prizes ``` **响应示例:** ```json { "success": true, "data": [ { "_id": "...", "prizeNumber": "一等奖", "createdAt": "2024-01-01T00:00:00.000Z" }, { "_id": "...", "prizeNumber": "二等奖", "createdAt": "2024-01-01T00:00:00.000Z" } ] } ``` --- ## 辅助接口 ### 用户管理 #### 获取所有用户 ``` GET /api/users ``` #### 创建单个用户 ``` POST /api/users Content-Type: application/json { "name": "张三" } ``` #### 批量创建用户 ``` POST /api/users/batch Content-Type: application/json { "names": ["张三", "李四", "王五"] } ``` #### 删除用户 ``` DELETE /api/users/:id ``` ### 奖品管理 #### 获取所有奖品 ``` GET /api/prizes ``` #### 创建单个奖品 ``` POST /api/prizes Content-Type: application/json { "prizeNumber": "奖1" } ``` #### 批量创建奖品 ``` POST /api/prizes/batch Content-Type: application/json { "prizeNumbers": ["奖1", "奖2", "奖3"] } ``` #### 删除奖品 ``` DELETE /api/prizes/:id ``` ### 其他抽奖相关 #### 获取所有抽奖结果 ``` GET /api/draw/results ``` #### 重置所有抽奖记录 ``` DELETE /api/draw/reset ``` ## 前端功能说明 ### 核心功能 1. **用户登录流程** - 检查 localStorage 缓存 - 无缓存 → 输入用户名 → 验证资格 - 有资格 → 缓存用户名 - 无资格 → 提示无资格 2. **抽奖流程** - 检查是否已抽奖 - 已抽奖 → 显示结果 - 未抽奖 → 显示抽奖按钮 - 点击抽奖 → 调用接口 → 显示结果 + 转盘动画 - 已抽奖用户不可更换用户名 3. **实时数据** - 每3秒轮询剩余奖品数量 - 每3秒轮询抽奖排行榜 - 前端定时查询后端接口 4. **转盘效果** - 显示所有奖品号 - 点击抽奖后转盘旋转动画 - 5秒后显示抽奖结果 5. **排行榜** - 显示所有用户抽奖记录 - 按抽奖时间倒序排列 - 当前用户记录高亮显示 ## 使用示例 ### 初始化数据 ```bash # 1. 批量添加用户 curl -X POST http://localhost:3000/api/users/batch \ -H "Content-Type: application/json" \ -d '{"names": ["张三", "李四", "王五", "赵六", "钱七"]}' # 2. 批量添加奖品 curl -X POST http://localhost:3000/api/prizes/batch \ -H "Content-Type: application/json" \ -d '{"prizeNumbers": ["一等奖", "二等奖", "三等奖", "四等奖", "五等奖"]}' ``` ### 核心功能测试 ```bash # 1. 验证用户资格 curl -X POST http://localhost:3000/api/draw/verify \ -H "Content-Type: application/json" \ -d '{"username": "张三"}' # 2. 抽奖 curl -X POST http://localhost:3000/api/draw \ -H "Content-Type: application/json" \ -d '{"username": "张三"}' # 3. 查询抽奖结果 curl -X POST http://localhost:3000/api/draw/query \ -H "Content-Type: application/json" \ -d '{"username": "张三"}' # 4. 查看剩余奖品 curl http://localhost:3000/api/draw/remaining # 5. 查看排行榜 curl http://localhost:3000/api/draw/results ``` ## 核心功能说明 1. **用户唯一性**:通过数据库唯一索引确保用户名称不重复 2. **奖品唯一性**:通过数据库唯一索引确保奖品号不重复 3. **一人一奖**:通过 `userId` 的唯一索引确保一个用户只能对应一个奖品 4. **一奖一人**:通过 `prizeId` 的唯一索引确保一个奖品只能对应一个用户 5. **随机抽奖**:从未被抽中的奖品中随机选择 6. **防重复抽奖**:用户抽奖前会检查是否已抽过奖 7. **资格验证**:所有操作都会验证用户是否在用户列表中 8. **实时数据**:前端定时轮询后端接口更新数据 9. **转盘动画**:抽奖时有流畅的旋转动画效果 10. **排行榜展示**:实时显示所有用户抽奖结果 ## 注意事项 1. 确保 MongoDB 服务正常运行 2. 确保数据库地址配置正确 3. 抽奖前需要先添加用户和奖品 4. 用户和奖品数量建议相等,否则会有用户或奖品剩余 5. 用户名区分大小写 6. 奖品号区分大小写 7. 前端每3秒轮询一次后端接口获取最新数据 8. 已抽奖用户无法更换用户名重新抽奖 ## 技术栈 ### 后端 - Node.js - Koa2 - MongoDB - Mongoose ### 前端 - Vue 3 - Vite - Axios ## 开发说明 ### 后端开发 ```bash # 启动开发模式 npm start # 修改代码后需要手动重启 ``` ### 前端开发 ```bash cd frontend npm run dev # Vite 支持热更新,修改代码自动刷新 ``` ### 生产部署 ```bash # 构建前端 cd frontend npm run build # 后端生产环境 # 设置 NODE_ENV=production npm start ``` ## 常见问题 ### Q: 如何重置抽奖数据? A: 调用 `DELETE /api/draw/reset` 接口重置所有抽奖记录 ### Q: 前端轮询频率可以修改吗? A: 可以修改 `frontend/src/App.vue` 中的 `setInterval` 时间间隔 ### Q: 如何修改转盘动画时间? A: 可以修改 `frontend/src/App.vue` 中的 `setTimeout` 时间和CSS中的 `transition` 时间 ### Q: 如何自定义转盘颜色? A: 修改 `frontend/src/App.vue` 中的 `.wheel` 样式的 `conic-gradient` ## 许可证 ISC