1. 项目背景与核心价值
去年疫情期间,我参与开发了一套基于SSM框架的疫苗预约微信小程序。这个项目最初源于社区卫生服务中心的实际需求——传统电话预约方式在接种高峰时段完全崩溃,工作人员每天要接听300+个咨询电话,预约差错率高达15%。我们团队用三周时间完成的这套系统,上线后使预约效率提升8倍,差错率降至0.3%以下。
这种微信小程序+后台管理系统的组合方案,特别适合需要快速响应突发公共卫生事件的场景。相比原生APP,小程序无需安装、即用即走的特性,在面向中老年群体时优势尤为明显。而SSM(Spring+SpringMVC+MyBatis)框架的轻量级特点,让我们能在有限开发周期内构建出稳定可靠的后台服务。
2. 系统架构设计解析
2.1 技术栈选型考量
选择SSM框架组合主要基于三个现实因素:
- 开发效率:医院信息科现有团队对Java生态更熟悉,Spring的注解驱动开发模式比传统SSH框架节省30%编码量
- 性能平衡:MyBatis的SQL优化能力可应对预约高峰期的并发查询,实测在2核4G服务器上能支撑800+QPS
- 兼容需求:需要对接医院已有的MySQL数据库,MyBatis的灵活映射避免了大量数据格式转换
微信小程序端采用原生开发而非uniapp等跨平台方案,是为了确保在低配安卓设备上的流畅运行。我们特别测试了红米Note5(3GB内存)这类中老年常用机型,页面加载时间控制在1.2秒内。
2.2 核心业务流程设计
系统运作流程包含三个关键闭环:
- 预约闭环:用户授权→选择接种点→选择时间段→提交身份信息→生成二维码凭证
- 核销闭环:护士扫码→验证接种资格→登记接种记录→更新健康码状态
- 监管闭环:疾控中心后台实时监控各接种点库存、预约量、异常情况
其中最难处理的是时间段预约的并发控制。我们最终采用Redis分布式锁+MySQL乐观锁的方案,关键代码片段如下:
java复制// 时间段库存扣减逻辑
@Transactional
public boolean reduceStock(Integer timeSlotId) {
// 获取Redis锁
String lockKey = "lock:timeslot:" + timeSlotId;
boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 30, TimeUnit.SECONDS);
if (!locked) throw new BusinessException("当前时段预约人数过多,请稍后再试");
try {
TimeSlot slot = timeSlotMapper.selectForUpdate(timeSlotId);
if (slot.getRemain() <= 0) return false;
int affected = timeSlotMapper.reduceStock(timeSlotId, slot.getVersion());
return affected > 0;
} finally {
redisTemplate.delete(lockKey);
}
}
3. 关键实现细节与避坑指南
3.1 微信登录对接的三大陷阱
-
session_key有效期问题:微信服务端返回的session_key可能提前失效,我们通过双重验证机制解决:
- 前端每2小时静默重新登录
- 关键操作前强制检查session有效性
-
UnionID获取条件:只有满足以下任一条件才能拿到UnionID:
- 小程序和公众号在同一个开放平台账号下
- 用户曾经在公众号完成过授权
- 解决方案是在预约首页添加公众号关注引导
-
用户信息解密异常:发现部分安卓机型的加密数据解密失败,最终定位是微信基础库版本差异,需要做兼容处理:
javascript复制// 前端兼容代码示例
function decryptData(encryptedData, iv) {
try {
return wx.miniProgram.decryptData({ encryptedData, iv });
} catch (e) {
// 降级处理方案
return callServerToDecrypt(encryptedData, iv);
}
}
3.2 高并发场景下的优化实践
预约系统在开放首日遭遇了每秒200+的并发请求,我们通过以下措施保障系统稳定:
-
多级缓存策略:
- 接种点基本信息:Redis缓存2小时
- 时间段库存数据:本地缓存30秒+Redis缓存5秒
- 用户预约记录:读写分离+CDN缓存静态页面
-
MySQL优化要点:
- 将
vaccine_reservation表的主键改为组合键(user_id, vaccine_id) - 为时间段查询添加覆盖索引
(site_id, date, status) - 配置连接池参数:初始连接数=CPU核心数×2
- 将
-
限流熔断配置:
yaml复制# Spring Cloud Alibaba Sentinel配置
spring:
cloud:
sentinel:
filter:
url-patterns: /**
datasource:
ds1:
nacos:
server-addr: localhost:8848
dataId: sentinel-rule
rule-type: flow
4. 数据统计模块设计精要
4.1 实时看板实现方案
采用WebSocket+ECharts的方案实现疾控中心管理后台的实时监控,核心指标包括:
- 各接种点预约完成率
- 疫苗库存预警(阈值动态计算)
- 异常预约行为检测(同一IP多次预约等)
统计查询的优化技巧:
- 预聚合策略:每小时跑定时任务计算日累计数据
- 列式存储:将统计结果存入ClickHouse提升分析效率
- 异步导出:使用POI的SXSSFWorkbook处理大数据量Excel
4.2 隐私保护特别处理
根据《个人信息保护法》要求,系统实现:
- 敏感数据脱敏存储:身份证号只保留前3位+后4位
- 日志审计分离:操作日志与业务数据物理隔离
- 自动清理机制:完成接种6个月后自动匿名化处理
sql复制-- 数据匿名化存储示例
CREATE TABLE `vaccine_record` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` varchar(32) COMMENT 'md5(身份证+盐值)',
`real_name` varchar(64) COMMENT '加密存储',
`id_card` varchar(64) COMMENT 'AES加密',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
5. 项目落地效果与扩展思考
系统上线后累计服务12万人次接种,峰值时承载单日1.2万预约量。有个意外收获是:通过分析预约数据,我们发现上午9-11点的取消率高达25%,调整时间段分配策略后,整体接种效率又提升了18%。
这套架构稍作改造就能复用到其他预约场景,比如:
- 医院专家号预约(已在实际对接中)
- 政务服务预约办理
- 学校实验室设备预约
特别提醒后来者注意:医疗类小程序上线前需要完成等保三级认证,建议提前3个月开始准备材料。我们在资质审核上踩过的坑包括:缺少《信息系统安全等级保护备案证明》、未提供完整的第三方安全评估报告等。