资讯动态

微信小程序疫苗预约系统源码解析:高并发号源扣减与幂等下单实战

发布时间:2026/9/25 4:18:15 来源:尧图企业网站定制
简介这份资源是基于微信小程序的疫苗预约接种系统源码面向具备Java与小程序开发基础、需要课程设计或二次开发参考的开发者。项目对原有疫苗预约系统进行重构后二次开发管理员端覆盖数据分析图、接种点与医护人员管理、预约计划维护、接种者信息及支付、预约、签到、预检、接种、留观等历史记录查询接种者端支持疫苗与接种点浏览、预约申请提交、模拟支付及接种二维码状态查看功能链路完整。压缩包共644个文件约3.56MB以html、vue、xml、java、js等前后端源码为主辅以scss、css样式与gif、jpg、png图片资源另含sql脚本、properties配置和md说明结构清晰便于按模块阅读。导入IDEA后修改pom中的MySQL驱动及数据库、图片路径配置即可启动。目前已有1054人学习适合作为毕业设计、课程作业或小程序全栈练习的参考模板。1. 疫苗预约接种小程序从一份源码包到能跑通的业务闭环社区接种点最头疼的不是没苗而是放号那一刻的并发和现场秩序。一份「基于微信小程序的疫苗预约接种系统源码.zip」落到手里真正要回答的是三件事它能不能扛住放号瞬间的请求、接种记录和库存怎么对齐、以及我改完能不能直接上线。这套系统本质是「小程序端 后端服务 数据库」的三段式结构小程序负责建档、选苗、选时段、看凭证后端负责号源扣减、幂等下单、接种核销数据库负责库存与记录的一致性。适合两类人一类是课程设计或毕设需要完整业务链路的同学另一类是社区/门诊想快速搭一套轻量预约工具的开发者。下面按「先立住原理、再动手复现、最后讲坑」的顺序拆开讲源码只是起点跑通业务闭环才是终点。2. 拆解源码包结构小程序端、服务端、数据库各管什么拿到压缩包先别急着导入 IDE先搞清楚目录分层否则后面改一个字段要在三个地方来回找。常见做法是根目录下分miniprogram/、server/、sql/三块有的还会带admin/管理后台。这一章先把「谁负责什么」讲清楚再给出导入和初始化的具体命令。2.1 目录分层与职责边界典型结构长这样不同作者命名略有差异但职责划分基本一致目录职责关键文件miniprogram/小程序页面、组件、请求封装app.js、pages/、utils/request.jsserver/接口、库存扣减、核销逻辑app.js入口、routes/、service/sql/建表语句与初始数据schema.sql、init_data.sqladmin/可选号源配置、接种记录导出视实现而定小程序端只做展示和表单校验真正的库存判断必须在服务端做这是后面避坑章节要反复强调的点。请求封装一般在utils/request.js里统一处理 token 和错误码改接口地址就改这一处。2.2 导入与初始化三条命令跑起来先建库再导数据顺序反了会报外键错误。以 MySQL 为例# 1. 创建数据库字符集用 utf8mb4疫苗名称可能有生僻字 mysql -u root -p -e CREATE DATABASE vaccine_db DEFAULT CHARSET utf8mb4; # 2. 导入表结构和初始号源数据 mysql -u root -p vaccine_db sql/schema.sql mysql -u root -p vaccine_db sql/init_data.sql # 3. 启动服务端端口按源码里的配置来常见是 3000 cd server npm install npm run dev逻辑说明第一步单独建库是为了控制字符集很多源码包默认 latin1中文疫苗名会变问号。第二步分两次导入schema 建表、init_data 灌初始数据方便你只重置数据不动结构。第三步npm run dev走的是 nodemon 热重载改代码不用重启。参数说明数据库连接信息通常在server/config.js或.env里重点看host、user、password、database四项服务端口如果和本地其他项目冲突改PORT即可但小程序端request.js里的 baseUrl 要同步改否则请求全 404。2.3 小程序端配置appid 与合法域名用微信开发者工具打开miniprogram/目录第一件事是填自己的 appid。测试阶段可以在「详情 → 本地设置」勾选「不校验合法域名」但上线前必须把后端域名配到小程序后台的 request 合法域名里且必须是 https。// utils/request.js 里通常长这样改 baseUrl 指向你的服务 const BASE_URL https://your-domain.com/api; function request(options) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL options.url, method: options.method || GET, data: options.data || {}, header: { Authorization: wx.getStorageSync(token) || }, success: res res.statusCode 200 ? resolve(res.data) : reject(res.data), fail: reject }); }); }逻辑说明统一封装的好处是 token 注入和错误处理只写一次。Authorization从本地缓存取登录后写入。参数说明BASE_URL上线必须是 https 且已备案域名method默认 GET提交预约要用 POSTstatusCode非 200 统一走 reject页面里 catch 后弹提示。3. 预约核心链路号源扣减、幂等下单与接种记录落库这一章是整套系统的命门。放号瞬间几十上百人同时点如果扣库存写成「先查再减」超卖是必然的。下面把下单链路拆成三步校验资格、原子扣减、写预约单再讲幂等和接种记录怎么落。3.1 号源扣减为什么必须用原子操作新手最容易翻车的地方先SELECT stock判断大于 0再UPDATE stock stock - 1。两个请求同时查到 stock1都判断通过结果扣成 -1。正确做法是把判断和扣减合并成一条 SQL靠数据库行锁保证原子性-- 原子扣减只有库存大于 0 才会更新成功 UPDATE vaccine_slot SET stock stock - 1, updated_at NOW() WHERE slot_id ? AND stock 0; -- 检查影响行数为 0 说明没抢到 -- affectedRows 1 才算预约成功逻辑说明WHERE stock 0是条件SET stock stock - 1是动作数据库在执行时对目标行加锁两个并发请求会串行执行第二个请求看到 stock 已经是 0affectedRows 为 0直接返回「已约满」。参数说明slot_id是时段主键建议加唯一索引配合updated_at便于排查。这一步必须在事务里扣减成功后紧接着写预约单失败一起回滚。3.2 幂等下单防止用户连点两次生成两条记录用户手抖连点、或者网络超时重试都会造成重复预约。常见做法是前端按钮置灰 后端幂等键双保险。幂等键可以用「用户ID 时段ID」拼一个唯一索引-- 预约单表加唯一索引同一用户同一时段只能有一条有效记录 ALTER TABLE appointment ADD UNIQUE KEY uk_user_slot (user_id, slot_id, status);逻辑说明status参与唯一索引是为了允许「取消后重新预约」——取消时 status 改成 canceled新记录 status 是 booked两者不冲突。参数说明如果业务允许同一时段约多种疫苗唯一索引要加上vaccine_id。插入时捕获唯一键冲突异常直接返回「请勿重复提交」比先查后插更可靠。3.3 接种记录落库与状态流转预约单和接种记录建议分两张表。预约单管「约没约上」接种记录管「打没打」。状态流转booked已预约→ checked_in已核销→ completed已接种取消走 canceled。核销时用扫码或输入预约码服务端校验状态必须是 booked 才能流转// 核销接口核心逻辑 async function checkIn(appointmentId) { const rows await db.query( UPDATE appointment SET status checked_in, checkin_time NOW() WHERE id ? AND status booked, [appointmentId] ); if (rows.affectedRows 0) { throw new Error(预约状态异常无法核销); } // 核销成功后写接种记录 await db.query(INSERT INTO vaccination_record (appointment_id, vaccine_id, user_id, vaccinate_time) VALUES (?, ?, ?, NOW()), [appointmentId, vaccineId, userId]); }逻辑说明WHERE status booked保证只有有效预约能核销重复扫码第二次 affectedRows 为 0直接报错。参数说明checkin_time记录核销时刻vaccinate_time记录实际接种时刻两者可能不同报表统计用哪个要提前和业务确认。4. 避坑与排查源码跑不起来时先看这几条源码包质量参差不齐下面五条是我踩过或见别人踩过的按「现象 → 原因 → 解决」写照着排查能省大半天。4.1 小程序请求全部失败控制台报「不在以下 request 合法域名列表中」现象开发者工具里接口全红真机预览也请求不到。原因小程序默认校验请求域名本地 http 或未备案域名会被拦。解决开发阶段在「详情 → 本地设置」勾选「不校验合法域名」上线前把后端域名配到小程序后台必须 https 且已备案配置后重新编译。4.2 导入 SQL 报「Cannot add foreign key constraint」现象执行 schema.sql 中途报外键错误。原因建表顺序不对子表先于父表创建或字段类型/字符集不一致。解决按依赖顺序导入先父表后子表检查外键字段和主表主键的类型、字符集是否完全一致utf8mb4 对 utf8 也会报错。4.3 放号后库存变成负数现象后台看库存 -3超卖了。原因扣减逻辑写成了先查后减并发下判断失效。解决改成UPDATE ... WHERE stock 0的原子写法检查 affectedRows如果用了 Redis 预扣要保证 Redis 和数据库最终一致加对账补偿。4.4 用户反馈「约上了但查不到记录」现象用户截图显示预约成功但我的预约列表为空。原因扣库存和写预约单不在同一事务扣减成功但插入失败或者插入时用户ID取错。解决把两步包进事务任一失败回滚检查写单时 user_id 是否来自 token 解析而非前端传参前端传参可被篡改。4.5 核销时提示「预约状态异常」但用户确实约了现象现场核销失败用户着急。原因用户之前取消过又重新预约旧记录 status 是 canceled扫码扫到旧码或者唯一索引设计导致新记录没插进去。解决核销时按「用户ID 时段ID」查最新有效记录而不是只按预约码检查唯一索引是否把 canceled 也算进去了。5. 上线前压测与库存对账两个能救命的技巧源码跑通只是及格线放号场景必须压测。我一般用autocannon或wrk对扣减接口打并发重点看两件事库存有没有超卖、响应时间有没有雪崩。命令很简单# 对预约接口打 200 并发持续 30 秒 npx autocannon -c 200 -d 30 -m POST -H Content-Type: application/json \ -b {slotId:1,userId:1001} http://localhost:3000/api/appointment逻辑说明-c 200是 200 个并发连接-d 30持续 30 秒-b是请求体。跑完看Non-2xx responses和数据库最终库存。参数说明userId 要每次不同否则会被幂等键挡住测不出真实并发slotId 选一个库存充足的时段先测扣减逻辑再测超卖边界。压测后必做库存对账初始库存 - 成功预约数 剩余库存差一条都要查。我习惯在服务端加一个对账脚本每天凌晨跑一次把vaccine_slot.stock和appointment表里 booked 状态的数量比对不一致就告警。这个习惯救过我一次——某次 Redis 预扣和数据库不同步对账脚本提前发现没等到用户投诉。最后一个技巧把「放号时间」做成配置项而不是硬编码。社区接种点经常临时调整放号时间硬编码意味着改代码重新发版。我在config表里加一行release_time管理后台可改服务端定时任务读配置触发放号。这个改动不大但上线后运维省心很多。做这类系统业务灵活性往往比技术炫技更重要希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑