1. 项目背景与核心需求
医院专家门诊预约挂号系统是医疗信息化建设中的重要一环。传统线下挂号方式存在排队时间长、号源分配不透明等问题,而现有的线上预约平台又往往操作复杂、体验不佳。基于微信小程序的解决方案恰好能解决这些痛点:
- 微信生态覆盖率高,用户无需额外安装APP
- 小程序即用即走的特点符合挂号场景的临时性需求
- 可充分利用微信的支付、消息通知等原生能力
我们采用SpringBoot作为后端框架,主要考虑其:
- 快速开发特性:内嵌Tomcat、自动化配置
- 丰富的starter生态:整合MyBatis、Redis等组件非常便捷
- 微服务友好:便于后期扩展为分布式架构
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计
2.1 技术栈选型
前端技术栈:
- 微信小程序原生开发(WXML+WXSS)
- Vant Weapp组件库(UI统一规范)
- ECharts for Weixin(数据可视化)
后端技术栈:
- SpringBoot 2.7.x
- MyBatis-Plus 3.5.x
- Redis 6.x(缓存/分布式锁)
- RabbitMQ 3.9.x(异步消息)
数据库:
- MySQL 8.0(关系型数据)
- MongoDB 5.0(非结构化日志)
2.2 核心模块划分
-
用户服务
- 微信授权登录
- 就诊人管理
- 消息订阅
-
预约服务
- 号源池管理
- 预约规则引擎
- 锁号机制
-
支付服务
- 微信支付对接
- 退款处理
- 对账系统
-
管理后台
- 医生排班
- 号源投放
- 数据看板
3. 关键实现细节
3.1 微信登录集成
java复制// 获取openid示例代码
public String getWxOpenId(String code) throws Exception {
String url = "https://api.weixin.qq.com/sns/jscode2session?appid="
+ appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code";
String response = restTemplate.getForObject(url, String.class);
JSONObject json = JSON.parseObject(response);
return json.getString("openid");
}
注意事项:
- 务必在后端进行code2session调用,避免前端暴露appsecret
- openid需要与业务系统用户绑定
- 建议增加session_key过期处理机制
3.2 号源池设计
采用分时段的号池模型:
sql复制CREATE TABLE `schedule` (
`id` bigint NOT NULL AUTO_INCREMENT,
`doctor_id` bigint NOT NULL,
`dept_id` int NOT NULL,
`date` date NOT NULL,
`time_period` varchar(20) NOT NULL COMMENT '上午/下午/晚上',
`total_num` int DEFAULT '0' COMMENT '总号源数',
`available_num` int DEFAULT '0' COMMENT '剩余号源数',
`version` int DEFAULT '0' COMMENT '乐观锁版本号',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_doctor_date` (`doctor_id`,`date`,`time_period`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
号源扣减采用Redis分布式锁+数据库乐观锁:
java复制public boolean reduceAvailableNumber(Long scheduleId) {
String lockKey = "lock:schedule:" + scheduleId;
try {
// 获取分布式锁
boolean locked = redisTemplate.opsForValue()
.setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS);
if (!locked) {
return false;
}
// 乐观锁更新
int updated = scheduleMapper.updateAvailableNum(scheduleId);
return updated > 0;
} finally {
redisTemplate.delete(lockKey);
}
}
3.3 高并发优化方案
-
缓存策略:
- 医生排班信息:Redis缓存2小时
- 热门科室:本地缓存+Redis二级缓存
-
读写分离:
- 查询走从库
- 写入走主库
-
限流措施:
- 预约接口:令牌桶算法限流
- 支付接口:滑动窗口限流
-
异步处理:
- 预约成功通知走消息队列
- 支付结果回调异步处理
4. 典型问题解决方案
4.1 重复预约问题
解决方案:
- 前端防重:提交按钮置灰
- 后端防重:唯一索引+分布式锁
- 用户ID+医生ID+就诊日期建立唯一索引
- 预约操作加分布式锁
4.2 超卖问题
处理流程:
- 查询剩余号源(带缓存)
- 预扣减(Redis原子操作)
- 创建订单(数据库事务)
- 实际扣减(最终一致性)
4.3 支付超时处理
状态机设计:
code复制待支付 -> 支付成功/支付超时
↓
取消预约(释放号源)
定时任务扫描超过30分钟未支付的订单,自动取消并释放号源。
5. 安全防护措施
-
接口安全:
- 敏感接口签名验证
- 参数过滤防XSS
- 频率限制防刷
-
数据安全:
- 敏感字段加密存储
- 日志脱敏处理
- 数据库定期备份
-
业务安全:
- 预约黑名单机制
- 异常行为监控
- 操作日志审计
6. 性能优化实践
-
小程序端:
- 分包加载
- 图片CDN加速
- 骨架屏优化
-
服务端:
- Nginx动静分离
- 接口响应压缩
- 慢SQL监控
-
数据库:
- 索引优化
- 冷热数据分离
- 查询结果缓存
7. 扩展性设计
-
多医院支持:
- 租户隔离方案
- 统一接入平台
-
智能推荐:
- 基于历史预约的医生推荐
- 智能分时段建议
-
互联网医院对接:
- 在线问诊集成
- 电子处方流转
实际部署时,我们采用Docker容器化部署方案,配合Jenkins实现CI/CD。监控方面使用Prometheus+Grafana搭建监控平台,关键指标包括:
- 预约成功率
- 接口响应时间
- 系统错误率
- 并发用户数
这套系统在某三甲医院上线后,线上预约率从35%提升至82%,窗口排队时间平均减少60%,取得了显著的应用效果。
