从零搭建一个微信小程序活动管理平台(一):架构设计与技术选型
本系列共 7 篇,完整拆解一个微信小程序活动管理平台的技术实现。涵盖活动报名、服务预约、活动接龙、出入登记、排号叫号五大工具模块,从架构设计到代码细节,带你走完一个完整项目的全流程。
为什么要做这个项目?
在社区运营、教培机构、物业管理、门店经营等场景中,「收集信息」是高频刚需。组织者常常面临这些痛点:
- 微信群接龙消息刷屏,统计全靠手动数
- Excel 传来传去,版本混乱、数据丢失
- 预约靠人工协调,容易撞期超约
- 出入登记纸质签名,字迹潦草、无法追溯
市面上的问卷工具虽然能解决部分问题,但功能通用、不够垂直,用户填完还要跳转到其他页面查看结果。
数簿预约报名助手 就是为了解决这些问题而生的微信小程序——创建活动 → 生成二维码 → 扫码填写 → 后台自动汇总,10 秒搞定一场活动的信息收集。
五大工具模块
项目围绕 5 个核心工具展开,每个工具对应一个独立场景:
| 工具 | 场景 | 核心能力 |
|---|---|---|
| 活动报名 | 社区活动、培训讲座、团建 | 自定义表单字段、人数限制、白名单验证、现场签到 |
| 服务预约 | 诊所预约、美容美发、会议室 | 分时段预约、名额限制、日期范围选择 |
| 活动接龙 | 团购接龙、拼团、排队报名 | 支持+1人、自定义字段、实时排序 |
| 出入登记 | 小区门禁、访客管理、考勤 | 进出类型区分、审批制流程、扫码登记 |
| 排号叫号 | 理发店、政务窗口、售后服务 | 实时取号、自动叫号、暂停/恢复 |
五个工具共享同一套用户体系、通知系统和审核流程,但各自的数据模型和业务逻辑完全独立。
技术栈选型
前端:原生微信小程序 + Vant Weapp
选择原生开发而不是 uni-app 或 Taro,原因有三:
- 性能优先:小程序本身运行在受限环境,原生开发没有额外的编译层和运行时开销
- API 跟进:微信新 API 第一时间可用,不需要等框架适配
- 项目体量适中:24 个页面的规模,原生开发完全可控
UI 组件库选了 Vant Weapp,轻量、设计规范统一,按需引入不会增加包体积。
后端:Node.js + Express + Sequelize + MySQL
| 技术 | 版本 | 选型理由 |
|---|---|---|
| Express | 4.18 | 轻量灵活,中间件生态丰富 |
| Sequelize | 6.37 | 成熟的 ORM,支持 model-first 设计 |
| MySQL | 8.4 | 成熟稳定,JSON 类型原生支持 |
| JWT | jsonwebtoken | 无状态鉴权,适合小程序场景 |
没有选择 Koa 或 Nest.js,是因为项目已有大量 Express 中间件沉淀,Express 的学习成本和迁移成本都更低。
辅助服务
- Redis/ioredis:缓存层(可选,降级为内存缓存)
- sharp:图片压缩处理
- multer:文件上传
- winston:日志管理(按天切割)
- node-schedule:定时任务
- nodemailer:邮件通知
- PM2:进程管理 + 守护
项目目录结构
前端
baomingyuyue/
├── app.js # 应用入口,静默登录 + 通知角标
├── app.json # 页面注册 + TabBar 配置
├── app.wxss # 全局样式(Tailwind 风格工具类)
├── config.js # 全局常量(BASE_URL、分页、TabBar索引)
│
├── assets/ # 静态资源(TabBar 图标、工具图标)
├── components/ # 自定义组件
│ ├── login-popup/ # 登录弹窗
│ └── privacy-popup/ # 隐私协议弹窗
│
├── pages/ # 页面模块
│ ├── index/ # 首页(TabBar #0)
│ ├── manage/ # 管理(TabBar #1)
│ ├── create-select/ # 创建(TabBar #2)
│ ├── notification/ # 通知(TabBar #3)
│ ├── profile/ # 我的(TabBar #4)
│ ├── registration/ # 活动报名(create/detail/register/checkin)
│ ├── booking/ # 服务预约(create/detail/book)
│ ├── chain/ # 活动接龙(create/detail/join)
│ ├── entry-exit/ # 出入登记(create/detail/register)
│ ├── queue/ # 排号叫号(create/detail/ticket)
│ ├── admin/ # 管理员审核
│ ├── feedback/ # 意见建议
│ └── templates/ # WXML 复用模板(field-render)
│
└── utils/ # 工具模块
├── request.js # HTTP 请求封装
├── api.js # API 函数集合(40+ 个接口)
├── auth.js # 登录态管理
└── util.js # 工具函数(日期、校验、状态管理)
后端
src/
├── models/ # 数据模型层
├── modules/ # 业务模块
│ ├── auth/ # 认证模块
│ ├── wechat/ # 微信相关
│ ├── toolkit/ # 核心:5 大工具 + 通知 + 反馈
│ ├── member/ # 会员体系
│ ├── system/ # 系统管理
│ └── common/ # 通用服务
├── routes/ # 路由聚合
└── shared/ # 共享中间件和工具函数
数据库设计概览
核心思路:统一活动表 + JSON 扩展字段
5 种工具类型的公共字段(标题、描述、状态、创建者等)放在统一的活动表中,各工具的专有字段存储在 extra JSON 列里。这样新增工具类型不需要加字段或建新表。
活动表的核心字段包括:活动 ID、工具类型(区分 5 种工具)、标题、描述、封面图、状态、创建者信息、extra JSON 扩展字段,以及创建和更新时间。
各工具的 extra 内容示例:
// registration: 报名表单字段、人数限制、白名单
{ "fields": [...], "maxParticipants": 50, "accessMode": "whitelist" }
// booking: 日期范围、时间段配置
{ "start_date": "2026-07-01", "end_date": "2026-07-31", "time_slots": [...] }
// chain: 自定义字段、截止时间
{ "customFields": [...], "deadline": "2026-08-01" }
// entry-exit: 登记类型、审批开关
{ "registerType": "both", "requireApproval": true }
// queue: 号段前缀、当前号码
{ "prefix": "A", "currentNumber": 0 }
参与记录表
每种工具有独立的参与记录表,通过活动 ID 关联:
| 工具 | 记录用途 | 核心信息 |
|---|---|---|
| 活动报名 | 报名记录 | 自定义字段值(JSON), 状态, 签到时间 |
| 服务预约 | 预约记录 | 日期, 时间段ID, 时间段标签 |
| 活动接龙 | 接龙记录 | 排序号, +1人数, 自定义字段值(JSON) |
| 出入登记 | 出入记录 | 类型(进入/离开), 审批状态 |
| 排号叫号 | 排号票 | 票号, 排队状态 |
活动状态生命周期
活动从创建到结束,经历以下状态流转:
draft(草稿)
↓ 提交审核
pending_review(审核中)
↓ 管理员操作
├── approved → active(已发布)
└── rejected → rejected(审核未通过)
↓ 修改后重新提交
pending_review
active(已发布)
├── 手动关闭 → closed(已关闭)→ 重新开放 → active
├── 结束时间到达 → ended(已结束)→ 编辑延期 → pending_review → active
└── 排号暂停 → paused(已暂停)→ 恢复 → active
关键设计点:ended 状态由后端自动检测。每次请求活动详情时,后端检查 active 状态的活动是否已过结束时间,如果是则自动标记为 ended,无需定时任务。
HTTP 请求封装
前端对 wx.request 做了统一封装,所有 API 调用通过 request.js 统一处理鉴权头和错误码:
- 自动注入 Token:每次请求自动从本地存储中读取 Token 并添加到
Authorization请求头 - 401 自动清除登录态:收到 401 响应时自动清除本地 Token,引导用户重新登录
- 统一错误提示:非 200 响应自动弹出 Toast 提示错误信息
API 层在此基础上定义了 40+ 个业务函数,每个函数对应一个后端接口,前端页面只需调用语义化的函数名(如 submitRegistration、getActivityDetail)即可。
后端响应规范
后端统一使用响应格式化类处理所有 HTTP 响应:
// 成功响应
{ "code": 200, "msg": "操作成功", "data": { ... } }
// 分页响应
{ "code": 200, "msg": "查询成功", "rows": [...], "total": 42 }
// 失败响应
{ "code": 500, "msg": "错误信息" }
配合字段名转换中间件,后端模型层的 snake_case 字段自动转为 camelCase 返回给前端,前端无需做任何键名转换。
鉴权体系
项目采用双角色鉴权:
| 角色 | 获取方式 | 适用场景 |
|---|---|---|
| 管理员 | 账号密码登录 | 后台管理系统 |
| 小程序用户 | 微信静默登录 | 小程序前端 |
两套 Token 使用不同的签名密钥和过期策略,互不干扰。
小程序端的登录流程:
页面 onLoad → silentLogin()
→ wx.login() 获取 code
→ 调用后端登录接口
→ 后端调用微信接口换取 openid
→ 自动创建/更新用户记录
→ 返回 JWT token
→ 存入 wx.Storage
用户无感知,打开小程序即已登录。
数簿预约报名助手小程序截图
小结
本文介绍了项目的整体架构和技术选型。核心设计决策回顾:
- 统一活动表 + JSON 扩展:用一个表承载 5 种工具,扩展性强
- 原生小程序开发:性能和灵活性优先于跨端能力
- Express + Sequelize:成熟稳定的技术栈,降低维护成本
- 自动检测 ended 状态:避免定时任务的复杂性
- 双角色 JWT 鉴权:管理员和小程序用户独立 token 体系
下一篇将深入 活动报名模块 的实现细节,包括动态表单引擎的设计、微信 checkbox 不响应的踩坑、白名单验证、签到逻辑等。
系列目录:
1. 从零搭建一个微信小程序活动管理平台(一):架构设计与技术选型(本文)
-
从零搭建一个微信小程序活动管理平台(二):活动报名 — 自定义表单、白名单与签到(敬请期待)
-
从零搭建一个微信小程序活动管理平台(三):服务预约 — 分时段预约名额限制与时间解析(敬请期待)
-
从零搭建一个微信小程序活动管理平台(四):活动接龙:支持+1人和自定义字段的接龙系统(敬请期待)
-
从零搭建一个微信小程序活动管理平台(五):出入登记与排号叫号:两种实时场景的技术实现(敬请期待)
-
从零搭建一个微信小程序活动管理平台(六):通用能力:动态表单、二维码生成、分享机制与状态管理(敬请期待)
-
从零搭建一个微信小程序活动管理平台(七):管理后台:审核系统与数据管理实践(敬请期待)
最后附上小程序成品,可以扫码看看。