ARTICLE · 993941
抽奖精选小程序开发文档:从部署到二次开发(文末附源码和部署)
抽奖精选小程序开发文档:从部署到二次开发(文末附源码和部署)




源码下载地址:
抽奖精选小程序项目是一个基于微信小程序云开发的在线抽奖系统,支持公开/私有抽奖、满人自动开奖、中奖广播、订阅消息推送、用户记录查询等功能。
前端采用原生 WXML/WXSS/JS 开发,后端完全依赖微信云开发的云数据库和云函数,无需自建服务器。
一、效果图





二、技术架构
┌─────────────────────────────────────────┐│ 微信小程序前端 ││ pages/ + components/ + api/ │└─────────────┬───────────────────────────┘ │ wx.cloud.callFunction┌─────────────▼───────────────────────────┐│ 微信云开发 ││ ├─ 云数据库(JSON 文档型) ││ ├─ 云函数(Node.js) ││ └─ 云存储(图片资源) │└─────────────────────────────────────────┘2.1 前端技术栈
2.2 后端技术栈
openapi.subscribeMessage.send | |
openapi.wxacode.getUnlimited |
三、项目结构
mpcloud-online-lottery/├── cloudfunctions/ # 云函数目录│ ├── broadcast/ # 查询中奖广播│ ├── config/ # 查询全局配置│ ├── data-cleaning/ # 数据清理/重置订阅状态│ ├── lottery/ # 抽奖核心逻辑│ ├── subscribe/ # 订阅消息记录│ ├── subscribe-trigger/ # 触发订阅消息推送│ ├── user/ # 用户授权、记录查询│ └── wxacode/ # 小程序码生成、授权记录├── miniprogram/ # 小程序前端│ ├── api/ # 云函数调用封装│ │ ├── broadcast.js│ │ ├── config.js│ │ ├── lottery.js│ │ ├── setting.js│ │ ├── subscribe.js│ │ ├── user.js│ │ └── wxacode.js│ ├── components/ # 自定义组件│ │ ├── lottery-broadcast-item/│ │ └── lottery-record/│ ├── images/ # 图片资源│ ├── is-framework/ # 内部 UI 框架│ │ ├── components/│ │ ├── utils/│ │ ├── wxs/│ │ └── wxss/│ ├── pages/ # 页面│ │ ├── authorize/ # 用户授权│ │ ├── index/ # 首页/抽奖大厅│ │ ├── local/ # 占位页面│ │ ├── message/ # 占位页面│ │ ├── my/ # 我的│ │ │ ├── index│ │ │ └── record│ │ ├── participate/ # 抽奖详情│ │ │ ├── index│ │ │ └── users│ │ └── question/ # 抽奖规则│ ├── app.js│ ├── app.json│ ├── app.wxss│ ├── cloud.js # 云环境配置│ └── sitemap.json├── README.md├── collections.md├── install.bat├── project.config.json└── project.private.config.json四、数据库设计
需创建以下集合(collections.md):
broadcast | ||
config | ||
lottery | ||
participate | ||
subscribe | ||
user | ||
wxacode-user |
4.1 lottery 集合字段
{"pic": "cloud://.../reward/redpack.png", // 奖品主图"condition": {"type": 1, // 开奖类型:1=满人开奖"description": "满10人自动开奖","value": 10// 满多少人才开奖 },"status": 1, // 1=未开奖,-1=已开奖"sponsor": {"name": "公众号木番薯科技", // 赞助商名称"description": "赞助商介绍","avatar": "cloud://.../sponsor/xxx.jpg","appId": "wx..."// 跳转小程序 AppID },"rewards": [{ "name": "2元现金红包", "winners": 1 }],"type": 0, // 预留字段"value": 3, // 奖品价值(划线价)"share": { "imageUrl": "cloud://..." },"display": 1, // 1=公共,0=私有"endTime": "ISODate", // 开奖时间"winners": [[{ openid, userInfo }]] // 中奖者二维数组}4.2 participate 集合字段
{"openid": "...","lotteryId": "...","participatedTime": "ISODate"}4.3 user 集合字段
{"openid": "...","userInfo": { "avatarUrl": "...", "nickName": "..." },"authorizedTime": "ISODate"}4.4 subscribe 集合字段
{"openid": "...","subscribeId": "...", // 模板消息 ID"lotteryId": "...","subscribedTime": "ISODate","pushed": false, // 是否已推送"pushedTime": "ISODate"}4.5 broadcast 集合字段
{"type": "winner","openid": "...","lotteryId": "...","reward": "2元现金红包","rewardIndex": 0,"userInfo": { "avatarUrl": "...", "nickName": "..." },"broadcastTime": "ISODate"}五、云函数设计
5.1 lottery 云函数
入口根据 event.action 分发:
query-lotteries | |
query-lottery | |
participate | |
query-participated-users |
核心逻辑:满人自动开奖
校验用户是否已授权( user集合存在记录)。校验是否已参与( participate集合去重)。写入参与记录。 统计当前参与人数。 若 condition.type === 1且人数达到condition.value:使用聚合管道 $sample随机抽取中奖者。按奖项等级分配中奖者。 更新 lottery状态为-1,写入winners与endTime。为每位中奖者生成 broadcast记录。返回参与结果或开奖结果。
5.2 user 云函数
query-current-user | |
authorize | |
query-lotteries | |
query-lottery-records | |
query-lottery-record-counts |
5.3 broadcast 云函数
query-broadcasts:查询最近 20 条中奖广播,昵称脱敏后返回。
5.4 subscribe 云函数
subscribe-lottery-message:记录用户订阅关系。
5.5 subscribe-trigger 云函数
由定时触发器调用,扫描已开奖但未推送的订阅记录。 调用 openapi.subscribeMessage.send发送开奖提醒。更新 subscribe.pushed = true。
5.6 wxacode 云函数
get-unlimited:生成带 scene 的小程序码并上传云存储。authorize:记录通过小程序码进入的用户。
5.7 config 云函数
query-config/query-configs:读取全局配置。
5.8 data-cleaning 云函数
维护脚本,用于重置订阅推送状态或补全历史 broadcast 数据。
六、前端页面与组件
6.1 页面说明
pages/index/index | ||
pages/participate/index | ||
pages/participate/users | ||
pages/my/index | ||
pages/my/record | ||
pages/authorize/index | ||
pages/question/index | ||
pages/local/indexpages/message/index |
6.2 组件说明
lottery-broadcast-item | |
lottery-record | |
is-loadingis-no-data / is-navigation |
6.3 API 封装
miniprogram/api/ 下按模块封装 wx.cloud.callFunction,实现前后端解耦。
七、部署文档
7.1 前置条件
注册微信小程序账号,获取 AppID: wxde071bd6******8a(或替换为自己的)。开通微信云开发,创建云环境(示例: test-n2ekp)。安装微信开发者工具。
7.2 导入项目
打开微信开发者工具 → 导入项目。 选择 mpcloud-online-lottery目录。填入 AppID。 确认 project.config.json:miniprogramRoot:miniprogram/cloudfunctionRoot:cloudfunctions/
7.3 配置云环境
修改以下文件中的云环境 ID:
miniprogram/cloud.js:将env改为你自己的云环境 ID。所有云函数 index.js中已使用cloud.DYNAMIC_CURRENT_ENV,一般无需修改。
7.4 初始化数据库
进入云开发控制台 → 数据库。 创建集合: broadcast、config、lottery、participate、subscribe、user、wxacode-user。设置权限: broadcast、config、lottery、participate、subscribe:所有用户可读。user、wxacode-user:所有用户可读,仅创建者可读写。导入示例数据: 数据库/lottery.json数据库/broadcast.json
7.5 上传云存储资源
将 数据库/存储/ 下的图片上传至云存储,并修改 lottery 记录中的 pic、sponsor.avatar、share.imageUrl 为你自己的云存储文件 ID。
7.6 部署云函数
进入 cloudfunctions/下每个云函数目录。右键点击云函数文件夹 → 「上传并部署:云端安装依赖」。 必须部署的云函数: lotteryuserbroadcastconfigsubscribesubscribe-triggerwxacode
7.7 配置订阅消息模板
登录小程序管理后台 → 功能 → 订阅消息。 添加模板「开奖结果通知」或类似模板。 获取模板 ID,替换 miniprogram/app.js中subscribeIds['lottery-message-remind']的值。替换 cloudfunctions/subscribe-trigger/index.js中data字段与模板字段对应关系。
7.8 配置定时触发器
在 cloudfunctions/subscribe-trigger/目录下创建config.json:
{"permissions": {"openapi": ["subscribeMessage.send"] },"triggers": [ {"name": "subscribe-trigger","type": "timer","config": "0 */5 * * * * *" } ]}重新上传 subscribe-trigger云函数。
7.9 编译预览
点击开发者工具「编译」。 使用真机扫码预览。 验证首页列表、参与抽奖、自动开奖、订阅消息等功能。
八、关键技术点
8.1 满人自动开奖的原子性
由于云数据库不支持事务,开奖逻辑通过「先写 participate → 再 count → 再 sample → 再 update lottery」实现。在并发场景下可能存在多个用户同时触发开奖条件,导致多次开奖。生产环境建议:
使用数据库事务(云开发已支持)。 或引入分布式锁(如云函数单实例、Redis 等)。
8.2 私有抽奖的可见性控制
user 云函数通过聚合管道 $lookup 关联 participate,并添加 visible 字段:
visible: aggregate.or([ aggregate.eq(['$display', 1]), aggregate.neq(['$participatedTime', null])])即:公开抽奖始终可见,私有抽奖仅当用户已参与时才可见。
8.3 昵称脱敏
中奖名单返回时对昵称做脱敏处理:
nickName: newArray(nickName.length).join('*') + nickName.substr(-1)8.4 订阅消息推送
subscribe-trigger 云函数通过定时触发器轮询,将已开奖但未推送的订阅记录批量发送订阅消息。注意模板字段需与后台申请的模板保持一致。
8.5 分享裂变
抽奖详情页 onShareAppMessage 动态生成分享标题、图片与路径,路径携带 lotteryId,新用户进入首页时根据 options.lotteryId 跳转详情页。
九、二次开发建议
增加开奖类型:目前仅支持满人开奖,可扩展为「定时开奖」、「达到人数+定时双重条件开奖」。 增加奖品类型:除现金红包外,可支持优惠券、实物、虚拟卡券等。 增加后台管理:可开发一个管理端小程序或 Web 端,用于创建抽奖、审核、发货。 完善并发控制:对开奖逻辑增加事务或锁,避免重复开奖。 数据安全:敏感字段(如 openid)避免直接返回前端,必要时做脱敏。 日志与监控:云函数中增加更详细的日志,便于排查问题。
十、注意事项
示例数据中的云存储文件 ID 需替换为自己的,否则图片无法显示。 订阅消息模板 ID 需与小程序后台申请的一致。 subscribe-trigger的定时触发器配置需根据业务频率调整。私有抽奖通过 display=0控制,但参与记录仍对所有用户可读,生产环境需评估隐私风险。小程序码功能依赖 wxacode云函数,调用频率受微信接口限制。