1. 项目背景与核心需求
医疗资源分配不均和挂号难问题长期困扰着患者就医体验。传统医院窗口挂号模式存在排队时间长、号源信息不透明、黄牛倒号等问题。基于Web的在线挂号系统通过信息化手段重构就医流程,实现号源电子化管理、分时段预约和实名制就医。
这个系统需要解决三个核心痛点:
- 患者端:提供7×24小时可访问的预约渠道,支持按科室/医生/时间段精准查询号源
- 医院端:实现号池动态管理、就诊时段智能分配、爽约自动回收机制
- 管理端:建立医疗数据统计平台,为医院资源配置提供决策支持
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 B/S架构优势分析
采用Browser/Server模式相比传统C/S架构具有:
- 零客户端安装:患者通过浏览器即可访问,降低使用门槛
- 跨平台兼容:适配PC、手机、平板等各种终端设备
- 集中式维护:系统升级只需更新服务端,无需逐个终端部署
2.2 Spring Boot技术选型
选择Spring Boot作为后端框架的考虑因素:
- 自动配置:通过starter依赖快速集成MyBatis、Redis等组件
- 内嵌容器:无需额外部署Tomcat,简化运维流程
- 健康检查:自带Actuator模块提供系统监控端点
- 示例配置:
java复制@SpringBootApplication
public class RegistrationSystem {
public static void main(String[] args) {
SpringApplication.run(RegistrationSystem.class, args);
}
}
2.3 分层架构设计
系统采用经典三层架构:
- 表现层:Thymeleaf模板引擎+HTML5前端页面
- 业务层:Spring MVC控制器+Service业务逻辑
- 持久层:MyBatis-Plus实现数据库操作
关键接口示例:
java复制public interface DoctorService {
List<TimeSlot> getAvailableSlots(Long doctorId, LocalDate date);
AppointmentResult makeAppointment(AppointmentDTO dto);
}
3. 核心功能实现
3.1 号源管理模块
采用Redis缓存热门科室号源,解决高并发抢号问题:
java复制// 号源预加载到Redis
public void preloadSlots(Long departmentId) {
List<TimeSlot> slots = slotMapper.selectAvailableSlots(departmentId);
String key = "slots:dept:" + departmentId;
redisTemplate.opsForValue().set(key, slots, 1, TimeUnit.HOURS);
}
3.2 预约业务流程
采用乐观锁防止超卖:
sql复制UPDATE time_slots
SET status = 'RESERVED'
WHERE id = #{slotId} AND status = 'AVAILABLE'
3.3 支付对接方案
集成支付宝/微信支付时需注意:
- 支付超时:设置15分钟未支付自动释放号源
- 对账机制:每日定时核对支付系统与本地订单状态
- 退款处理:针对取消预约的情况实现原路退款
4. 数据库设计要点
4.1 主要表结构
sql复制CREATE TABLE doctor (
id BIGINT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
department_id BIGINT,
title VARCHAR(20),
introduction TEXT
);
CREATE TABLE time_slot (
id BIGINT PRIMARY KEY,
doctor_id BIGINT,
start_time DATETIME,
end_time DATETIME,
status ENUM('AVAILABLE','RESERVED','COMPLETED')
);
4.2 索引优化策略
- 在doctor表的department_id字段建立索引
- 对time_slot的(doctor_id, start_time)建立联合索引
- 就诊记录表按患者ID分库分表
5. 安全防护措施
5.1 防刷机制
- 图形验证码:预约操作前必须验证
- 频率限制:同一IP每分钟最多5次请求
- 黑名单:识别异常设备指纹
5.2 数据安全
- 敏感字段加密:患者身份证号采用AES加密存储
- 日志脱敏:在日志文件中隐藏手机号中间四位
- SQL防护:使用MyBatis参数绑定防止注入
6. 典型问题解决方案
6.1 高并发场景处理
采用多级缓存策略:
- 本地缓存:Caffeine缓存科室列表等低频变更数据
- 分布式缓存:Redis缓存热门号源
- 数据库:最终数据持久化
6.2 分布式事务
预约支付场景使用Seata实现TCC模式:
java复制@TwoPhaseBusinessAction(name = "appointmentAction")
public boolean prepare(BusinessActionContext context) {
// 预留资源
}
public boolean commit(BusinessActionContext context) {
// 确认完成
}
7. 扩展功能设计
7.1 智能推荐
基于历史数据实现:
- 科室推荐:根据症状描述匹配相关科室
- 医生推荐:根据患者评价和专长推荐
7.2 消息通知
多通道通知方案:
- 短信:预约成功提醒
- 微信模板消息:就诊前提醒
- 站内信:停诊变更通知
我在实际开发中发现,支付超时处理是最容易出问题的环节。建议采用状态机模式管理预约生命周期,通过定时任务扫描待支付订单,避免号源被长期占用。同时要注意支付回调接口的幂等性设计,防止重复处理通知消息。
