1. 项目背景与核心价值
医院预约挂号系统是当前医疗信息化建设中的刚需场景。我去年参与某三甲医院互联网医院建设时,亲眼目睹了传统窗口挂号模式带来的种种问题:患者凌晨排队、黄牛倒号、就诊时段分配不均等。这套基于SpringBoot+微信小程序的解决方案,正是针对这些痛点设计的。
微信小程序作为前端载体具有天然优势:无需下载安装、即用即走,特别适合挂号这种低频刚需场景。而后端选用SpringBoot框架,则看中了其快速开发、微服务友好的特性。两者结合,既能保证患者端的便捷性,又能满足医院对系统稳定性、扩展性的要求。
从技术实现角度看,这个毕设项目涵盖了企业级应用开发的完整链路:
- 前端:微信小程序页面开发与组件化设计
- 后端:SpringBoot RESTful API开发
- 数据层:MySQL关系型数据建模
- 系统集成:微信支付对接、消息模板推送
- 运维部署:Linux环境下的服务发布
提示:实际医院场景中还需考虑医保对接、号源池分布式锁等进阶需求,但作为毕设项目,当前实现已足够体现核心技术要点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计解析
2.1 技术栈选型依据
前端选择微信小程序而非H5的原因:
- 打开速度比Web页面快30%以上(实测首屏加载<800ms)
- 原生组件(如picker、swiper)体验更流畅
- 可直接调用微信生态能力(登录、支付、订阅消息)
- 审核发布机制保证应用质量
后端SpringBoot的优势体现:
java复制@SpringBootApplication
public class RegistrationApplication {
public static void main(String[] args) {
// 内嵌Tomcat容器启动
SpringApplication.run(RegistrationApplication.class, args);
}
}
- 自动配置机制减少XML配置工作量
- Starter依赖快速集成MyBatis、Redis等组件
- Actuator端点提供运维监控能力
- 与微信小程序鉴权体系天然契合
2.2 核心业务流程图
挂号业务的主流程包含以下关键节点:
- 患者微信授权登录获取openid
- 查询可预约科室与医生排班
- 选择时段并锁定号源(分布式事务)
- 微信支付完成订单
- 生成电子就诊凭证
- 就诊前提醒(模板消息)
mermaid复制graph TD
A[微信登录] --> B[查询号源]
B --> C{号源充足?}
C -->|是| D[锁定号源]
C -->|否| E[返回失败]
D --> F[创建订单]
F --> G[发起支付]
G --> H{支付成功?}
H -->|是| I[更新订单状态]
H -->|否| J[释放号源]
2.3 数据库关键表设计
主要实体关系模型:
- 患者表(patient):关联微信openid
- 科室表(department):树形结构存储科室层级
- 医生表(doctor):关联所属科室
- 排班表(schedule):医生出诊时间配置
- 号源表(registration):时段细分到15分钟粒度
- 订单表(order):包含支付状态、退款记录
sql复制CREATE TABLE `registration` (
`id` bigint NOT NULL AUTO_INCREMENT,
`doctor_id` bigint NOT NULL COMMENT '医生ID',
`schedule_id` bigint NOT NULL COMMENT '排班ID',
`start_time` datetime NOT NULL COMMENT '时段开始时间',
`end_time` datetime NOT NULL COMMENT '时段结束时间',
`status` tinyint DEFAULT '0' COMMENT '0可预约 1已锁定 2已预约',
`version` int DEFAULT '0' COMMENT '乐观锁版本号',
PRIMARY KEY (`id`),
KEY `idx_doctor_schedule` (`doctor_id`,`schedule_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3. 核心功能实现细节
3.1 微信登录集成
小程序端调用wx.login获取code,传给后端换取openid:
javascript复制// 小程序端登录逻辑
wx.login({
success: res => {
wx.request({
url: 'https://api.example.com/auth/login',
data: { code: res.code }
})
}
})
SpringBoot后端处理:
java复制@RestController
@RequestMapping("/auth")
public class AuthController {
@Value("${wechat.appid}")
private String appId;
@Value("${wechat.secret}")
private String secret;
@PostMapping("/login")
public Result login(@RequestParam String code) {
// 构造请求URL
String url = "https://api.weixin.qq.com/sns/jscode2session?" +
"appid=" + appId +
"&secret=" + secret +
"&js_code=" + code +
"&grant_type=authorization_code";
// 发送HTTP请求
String response = restTemplate.getForObject(url, String.class);
JSONObject json = JSON.parseObject(response);
// 获取openid
String openid = json.getString("openid");
if(StringUtils.isEmpty(openid)) {
throw new BusinessException("微信登录失败");
}
// 后续业务处理...
}
}
注意:实际生产环境需要增加会话密钥加密传输、登录态token管理等安全措施
3.2 号源锁定与并发控制
采用乐观锁解决超卖问题:
java复制@Transactional
public boolean lockRegistration(Long registrationId, String openid) {
// 查询号源当前状态
Registration reg = registrationMapper.selectById(registrationId);
if(reg.getStatus() != 0) {
return false;
}
// 尝试锁定
int updated = registrationMapper.updateStatus(
registrationId,
0, // 期望原状态
1, // 目标状态
reg.getVersion() // 版本号
);
if(updated == 0) {
throw new ConcurrentLockException("号源已被其他用户抢先锁定");
}
// 创建预订单
Order order = new Order();
order.setRegistrationId(registrationId);
order.setOpenid(openid);
orderMapper.insert(order);
return true;
}
3.3 微信支付对接
支付流程关键步骤:
- 后端创建支付订单并签名
- 小程序端调用wx.requestPayment
- 微信异步通知支付结果
- 更新业务订单状态
支付参数生成示例:
java复制public Map<String, String> createPayParams(String openid, String orderNo, BigDecimal amount) {
Map<String, String> params = new HashMap<>();
params.put("appid", appId);
params.put("mch_id", mchId);
params.put("nonce_str", WXPayUtil.generateNonceStr());
params.put("body", "医院挂号费");
params.put("out_trade_no", orderNo);
params.put("total_fee", amount.multiply(new BigDecimal(100)).intValue() + "");
params.put("spbill_create_ip", "123.12.12.123");
params.put("notify_url", "https://api.example.com/pay/notify");
params.put("trade_type", "JSAPI");
params.put("openid", openid);
// 签名并生成XML请求参数
String sign = WXPayUtil.generateSignature(params, apiKey);
params.put("sign", sign);
return params;
}
4. 典型问题排查实录
4.1 微信支付签名失败
现象:小程序端调用支付时提示"签名错误"
排查过程:
- 检查商户API密钥是否正确(区分大小写)
- 验证参数顺序是否符合微信要求(ASCII排序)
- 确认金额单位是否为分(需乘以100)
- 检查nonce_str是否每次请求重新生成
- 使用微信官方签名校验工具比对
最终定位:开发环境与生产环境混用相同的商户号,导致密钥不匹配
4.2 号源状态不同步
现象:支付成功后号源仍显示可预约
解决方案:
- 引入状态机明确各状态转换关系:
mermaid复制stateDiagram [*] --> 可预约 可预约 --> 已锁定: 用户点击预约 已锁定 --> 已预约: 支付成功 已锁定 --> 可预约: 超时未支付 已预约 --> 已就诊: 核销 - 增加定时任务释放超时未支付号源
- 添加分布式锁防止并发修改
4.3 小程序审核驳回
常见驳回原因及应对:
- 医疗类目未开通:需提交医疗机构合作证明
- 用户隐私协议不全:补充《隐私保护指引》
- 功能描述不清晰:重写"关于我们"页面
- 测试账号未提供:准备演示视频+测试账号
5. 项目扩展方向建议
5.1 业务功能扩展
- 检查报告查询(对接LIS系统)
- 处方药品配送(与药房系统集成)
- 满意度评价体系
- 家庭账号管理(代老人/儿童挂号)
5.2 技术优化方案
- 引入Redis缓存热门科室查询
- 使用Elasticsearch实现症状搜索
- 采用Spring Cloud实现微服务化
- 增加Prometheus监控指标
5.3 毕设答辩要点
- 技术选型对比(为什么不用PHP/Python?)
- 并发问题解决方案(乐观锁 vs 悲观锁)
- 微信生态整合深度(登录+支付+消息)
- 系统可测量指标(QPS、响应时间)
- 商业价值分析(与传统挂号方式对比)
我在实际部署时发现,医院内网环境往往有严格的安全策略,建议提前准备:
- HTTPS证书(避免混合内容问题)
- 域名备案(微信要求备案域名)
- 防火墙白名单(放行微信服务器IP段)
- 数据库审计日志(满足等保要求)
