1. 项目概述与设计思路
医疗挂号系统作为医院信息化建设的核心组成部分,其设计需要兼顾患者就医体验和医院管理效率。我们采用前后端分离架构,后端基于Spring Boot 3.x构建RESTful API,前端使用Vue3组合式API开发响应式界面,整体技术选型考虑了以下关键因素:
- 性能与稳定性:挂号系统面临瞬时高并发场景(如专家号放号时),Spring Boot的内置Tomcat容器配合Redis分布式锁能有效应对
- 类型安全:全栈使用TypeScript(前端)+Java强类型语言,减少运行时错误
- 可维护性:模块化设计使得患者端、医生端、管理后台可独立开发和部署
实际开发中发现:当日上午8:00-9:00的挂号请求量占全天60%以上,这是系统设计的重点优化时段
2. 核心模块设计与实现
2.1 患者端功能实现
患者端采用JWT无状态认证,关键流程包括:
-
预约挂号:
- 使用Redis sorted set存储号源池(score为时间戳)
- 分布式锁实现伪代码:
java复制public Result register(RegisterDTO dto) { String lockKey = "reg:" + dto.getScheduleId(); try { // 尝试获取锁(10秒自动释放防止死锁) boolean locked = redisTemplate.opsForValue() .setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS); if(!locked) throw new BusinessException("当前号源紧张,请重试"); // 检查剩余号源 Long remaining = redisTemplate.opsForZSet() .zCard("schedule:" + dto.getScheduleId()); if(remaining <=0) throw new BusinessException("号源已约满"); // 执行挂号业务逻辑 return doRegister(dto); } finally { redisTemplate.delete(lockKey); } }
-
支付对账:
- 采用支付宝/微信支付异步通知+主动查询双重校验
- 支付状态机设计:
code复制待支付 -> 支付成功 -> 已预约 -> 支付超时(30分钟)-> 已取消
2.2 医生工作站开发
医生端重点解决临床工作效率问题:
-
排班管理:
- 批量导入使用EasyExcel处理:
java复制@PostMapping("/schedule/import") public Result importSchedule(@RequestParam MultipartFile file) { List<ScheduleImportDTO> list = EasyExcel.read(file.getInputStream()) .head(ScheduleImportDTO.class) .sheet() .doReadSync(); // 数据校验和持久化... }
- 批量导入使用EasyExcel处理:
-
接诊队列:
- WebSocket实时推送新患者通知
- 状态看板使用Redis HyperLogLog统计当日接诊量
2.3 管理后台关键技术
-
权限控制系统:
- 基于Spring Security + RBAC模型
- 动态菜单数据库设计:
sql复制CREATE TABLE `sys_menu` ( `id` bigint NOT NULL AUTO_INCREMENT, `parent_id` bigint DEFAULT NULL, `name` varchar(50) NOT NULL, `perms` varchar(500) DEFAULT NULL COMMENT '权限标识', `type` tinyint DEFAULT 0 COMMENT '0目录 1菜单 2按钮', PRIMARY KEY (`id`) ) ENGINE=InnoDB;
-
数据统计:
- 使用Elasticsearch聚合分析挂号趋势
- 定时任务每日凌晨生成统计报表
3. 性能优化实践
3.1 高并发场景应对
-
缓存策略:
- 号源信息采用多级缓存(Redis → Caffeine → DB)
- 缓存键设计规范:
code复制reg:schedule:{id} // 号源详情 reg:stock:{date} // 每日余量
-
数据库优化:
- 分表策略:按月份拆分挂号记录表
- 索引设计:
sql复制ALTER TABLE `registration` ADD INDEX `idx_patient_date` (`patient_id`, `visit_date`);
3.2 前端性能提升
-
组件懒加载:
typescript复制const DepartmentList = defineAsyncComponent(() => import('./views/DepartmentList.vue') ) -
API请求优化:
- 使用axios拦截器实现智能重试
- 关键接口添加SWR缓存
4. 安全防护体系
4.1 认证与授权
-
JWT增强方案:
- 双Token机制(accessToken 30分钟过期 + refreshToken 7天有效期)
- 令牌指纹防止盗用:
java复制String fingerprint = DigestUtils.md5Hex(userAgent + ip); claims.put("fpt", fingerprint);
-
敏感操作保护:
- 医生登录需人脸识别
- 关键业务操作记录审计日志
4.2 数据安全
-
隐私数据加密:
- 患者身份证号使用AES加密存储
- 数据库字段级权限控制
-
防篡改机制:
- 重要业务表增加数据签名字段
- 使用HmacSHA256生成校验码
5. 部署与监控
5.1 容器化部署
Docker Compose编排示例:
yaml复制version: '3'
services:
app:
image: registry.example.com/reg-server:${TAG}
ports:
- "8080:8080"
depends_on:
- redis
- mysql
redis:
image: redis:6-alpine
volumes:
- redis_data:/data
volumes:
redis_data:
5.2 监控告警
-
指标收集:
- Spring Boot Actuator暴露metrics端点
- Prometheus采集频率设置为15s
-
看板配置:
- Grafana监控关键指标:
- 挂号成功率
- API响应时间P99
- 数据库连接池使用率
- Grafana监控关键指标:
6. 测试策略
6.1 自动化测试体系
-
单元测试:
- 使用JUnit5 + Mockito
- 业务逻辑覆盖率>80%
-
压力测试:
- JMeter模拟2000并发挂号
- 重点关注Redis连接池配置
6.2 全链路测试
-
场景验证:
- 患者预约→支付超时→自动取消→号源释放
- 医生排班冲突检测
-
兼容性测试:
- 微信小程序与H5页面一致性校验
- 不同DPI移动设备显示适配
7. 项目演进方向
-
智能推荐扩展:
- 基于就诊历史推荐相关科室
- 检查项目智能组合建议
-
运维增强:
- 基于ELK搭建日志分析平台
- 灰度发布能力建设
-
体验优化:
- 候诊时间实时预测
- 检查报告异常值可视化标注
在三个月生产环境运行中,系统日均处理挂号量超过1.2万次,高峰期Redis集群QPS稳定在8000+。后续计划引入Kubernetes进一步提升弹性伸缩能力,同时正在评估将部分查询服务迁移至GraphQL的方案。