夜雨聆风学习资料网

ARTICLE · 993941

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

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

抽奖精选小程序项目是一个基于微信小程序云开发的在线抽奖系统,支持公开/私有抽奖、满人自动开奖、中奖广播、订阅消息推送、用户记录查询等功能。

前端采用原生 WXML/WXSS/JS 开发,后端完全依赖微信云开发的云数据库和云函数,无需自建服务器。

一、效果图

二、技术架构

┌─────────────────────────────────────────┐│           微信小程序前端                 ││  pages/ + components/ + api/            │└─────────────┬───────────────────────────┘              │ wx.cloud.callFunction┌─────────────▼───────────────────────────┐│           微信云开发                     ││  ├─ 云数据库(JSON 文档型)               ││  ├─ 云函数(Node.js)                    ││  └─ 云存储(图片资源)                    │└─────────────────────────────────────────┘

2.1 前端技术栈

技术
说明
WXML/WXSS/JS
微信小程序原生开发
is-framework
项目内封装的 UI 框架(加载、导航、空数据、弹窗等)
wxs
数组、字符串处理辅助模块
本地缓存
状态通过 App 实例与云函数返回维护

2.2 后端技术栈

技术
说明
微信云函数
业务逻辑处理(lottery、user、broadcast 等)
云数据库
JSON 文档型数据库,存储 lottery、user、participate 等
云存储
存储奖品图、赞助商图、分享图、引导 GIF 等
订阅消息
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 分发:

action
功能
query-lotteries
分页查询公开抽奖列表
query-lottery
查询单个抽奖详情,附带当前用户参与状态
participate
参与抽奖,满足条件时自动开奖
query-participated-users
查询某抽奖的参与用户头像列表

核心逻辑:满人自动开奖

  1. 校验用户是否已授权(user 集合存在记录)。
  2. 校验是否已参与(participate 集合去重)。
  3. 写入参与记录。
  4. 统计当前参与人数。
  5. 若 condition.type === 1 且人数达到 condition.value:
    • 使用聚合管道 $sample 随机抽取中奖者。
    • 按奖项等级分配中奖者。
    • 更新 lottery 状态为 -1,写入 winners 与 endTime。
    • 为每位中奖者生成 broadcast 记录。
  6. 返回参与结果或开奖结果。

5.2 user 云函数

action
功能
query-current-user
查询当前登录用户
authorize
用户授权,写入/更新 user 记录
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/index
、pages/message/index
当前为占位页面

6.2 组件说明

组件
功能
lottery-broadcast-item
中奖广播单项
lottery-record
记录列表组件,支持下拉刷新与上拉加载
is-loading
 / is-no-data / is-navigation
is-framework 内置 UI 组件

6.3 API 封装

miniprogram/api/ 下按模块封装 wx.cloud.callFunction,实现前后端解耦。

七、部署文档

7.1 前置条件

  1. 注册微信小程序账号,获取 AppID:wxde071bd6******8a(或替换为自己的)。
  2. 开通微信云开发,创建云环境(示例:test-n2ekp)。
  3. 安装微信开发者工具。

7.2 导入项目

  1. 打开微信开发者工具 → 导入项目。
  2. 选择 mpcloud-online-lottery 目录。
  3. 填入 AppID。
  4. 确认 project.config.json:
    • miniprogramRoot: miniprogram/
    • cloudfunctionRoot: cloudfunctions/

7.3 配置云环境

修改以下文件中的云环境 ID:

  • miniprogram/cloud.js:将 env 改为你自己的云环境 ID。
  • 所有云函数 index.js 中已使用 cloud.DYNAMIC_CURRENT_ENV,一般无需修改。

7.4 初始化数据库

  1. 进入云开发控制台 → 数据库。
  2. 创建集合:broadcast、config、lottery、participate、subscribe、user、wxacode-user。
  3. 设置权限:
    • broadcast、config、lottery、participate、subscribe:所有用户可读。
    • user、wxacode-user:所有用户可读,仅创建者可读写。
  4. 导入示例数据:
    • 数据库/lottery.json
    • 数据库/broadcast.json

7.5 上传云存储资源

将 数据库/存储/ 下的图片上传至云存储,并修改 lottery 记录中的 pic、sponsor.avatar、share.imageUrl 为你自己的云存储文件 ID。

7.6 部署云函数

  1. 进入 cloudfunctions/ 下每个云函数目录。
  2. 右键点击云函数文件夹 → 「上传并部署:云端安装依赖」。
  3. 必须部署的云函数:
    • lottery
    • user
    • broadcast
    • config
    • subscribe
    • subscribe-trigger
    • wxacode

7.7 配置订阅消息模板

  1. 登录小程序管理后台 → 功能 → 订阅消息。
  2. 添加模板「开奖结果通知」或类似模板。
  3. 获取模板 ID,替换 miniprogram/app.js 中 subscribeIds['lottery-message-remind'] 的值。
  4. 替换 cloudfunctions/subscribe-trigger/index.js 中 data 字段与模板字段对应关系。

7.8 配置定时触发器

  1. 在 cloudfunctions/subscribe-trigger/ 目录下创建 config.json:
{"permissions": {"openapi": ["subscribeMessage.send"]  },"triggers": [    {"name": "subscribe-trigger","type": "timer","config": "0 */5 * * * * *"    }  ]}
  1. 重新上传 subscribe-trigger 云函数。

7.9 编译预览

  1. 点击开发者工具「编译」。
  2. 使用真机扫码预览。
  3. 验证首页列表、参与抽奖、自动开奖、订阅消息等功能。

八、关键技术点

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 跳转详情页。

九、二次开发建议

  1. 增加开奖类型:目前仅支持满人开奖,可扩展为「定时开奖」、「达到人数+定时双重条件开奖」。
  2. 增加奖品类型:除现金红包外,可支持优惠券、实物、虚拟卡券等。
  3. 增加后台管理:可开发一个管理端小程序或 Web 端,用于创建抽奖、审核、发货。
  4. 完善并发控制:对开奖逻辑增加事务或锁,避免重复开奖。
  5. 数据安全:敏感字段(如 openid)避免直接返回前端,必要时做脱敏。
  6. 日志与监控:云函数中增加更详细的日志,便于排查问题。

十、注意事项

  1. 示例数据中的云存储文件 ID 需替换为自己的,否则图片无法显示。
  2. 订阅消息模板 ID 需与小程序后台申请的一致。
  3. subscribe-trigger 的定时触发器配置需根据业务频率调整。
  4. 私有抽奖通过 display=0 控制,但参与记录仍对所有用户可读,生产环境需评估隐私风险。
  5. 小程序码功能依赖 wxacode 云函数,调用频率受微信接口限制。
源码下载地址:

相关学习资料