1. 项目概述
社区医疗门诊挂号管理系统是基于SpringBoot+Vue技术栈开发的一套面向基层医疗机构的数字化解决方案。这个系统我去年为本地社区卫生服务中心实际部署过,核心解决了传统纸质挂号带来的三大痛点:排队时间长、号源管理混乱、就诊数据难以统计。
从技术架构看,前端采用Vue.js实现响应式界面,后端基于SpringBoot提供RESTful API,中间通过JWT进行鉴权。数据库选用MySQL 8.0,配合Redis缓存高频访问数据如医生排班表。整套系统在2周内就完成了从零到生产环境的部署,现在日均处理挂号量超过300人次。
2. 核心功能模块设计
2.1 挂号预约子系统
采用分时预约机制,将每天划分为48个时段(每半小时为一个时段)。关键数据结构设计如下:
java复制// 号源池实体
@Entity
public class RegistrationPool {
@Id
@GeneratedValue
private Long id;
@ManyToOne
private Doctor doctor;
private LocalDate workDate;
private TimePeriod timeSlot; // 枚举值AM/PM
@ElementCollection
@CollectionTable(name="time_segments")
private List<LocalTime> availableTimes;
private Integer totalQuota;
private Integer remainingQuota;
}
实际开发中发现,单纯用数据库事务控制并发挂号会导致死锁。最终采用Redis+Lua脚本实现原子操作:
lua复制-- 挂号库存扣减脚本
local key = KEYS[1]
local change = tonumber(ARGV[1])
local current = tonumber(redis.call('GET', key))
if current >= change then
return redis.call('DECRBY', key, change)
else
return -1
end
2.2 医生排班管理
支持可视化拖拽排班,核心算法是处理时间冲突检测:
javascript复制// 前端冲突检测逻辑
function checkScheduleConflict(newSchedule, existingSchedules) {
return existingSchedules.some(item => {
return (newSchedule.start < item.end) &&
(newSchedule.end > item.start)
})
}
后台使用Spring Batch定期生成未来7天的默认排班模板,大幅减少管理员工作量。
3. 关键技术实现细节
3.1 跨域会话保持方案
由于采用前后端分离架构,我们实现了两种会话方案:
- JWT方案(适合移动端):
java复制@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager))
.addFilter(new JwtAuthorizationFilter(authenticationManager));
return http.build();
}
- Spring Session + Redis方案(适合Web端):
yaml复制spring:
session:
store-type: redis
timeout: 1800
redis:
host: 127.0.0.1
port: 6379
3.2 高并发挂号处理
通过压力测试发现,当并发超过500时系统响应时间急剧上升。最终采用三级缓存策略:
- 一级缓存:本地Caffeine(缓存科室信息等静态数据)
java复制@Bean
public CaffeineCacheManager cacheManager() {
return new CaffeineCacheManager("deptCache"){
@Override
protected Cache<Object, Object> createNativeCache(String name) {
return Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build();
}
};
}
-
二级缓存:Redis集群(缓存医生排班等半静态数据)
-
三级缓存:MySQL读写分离(业务数据最终落地方)
4. 典型问题排查实录
4.1 微信支付回调丢失
线上环境出现过3次支付成功但系统未更新状态的情况。排查发现是Nginx配置了80ms的超时中断:
nginx复制location /api/callback {
proxy_connect_timeout 300ms;
proxy_read_timeout 500ms;
proxy_send_timeout 500ms;
}
解决方案:
- 增加回调接口幂等性设计
- 添加补偿任务定时查询支付状态
- 记录详细日志包括网络耗时
4.2 Vue页面加载性能优化
首屏加载时间从4.2s优化到1.8s的关键措施:
- 路由懒加载:
javascript复制const DoctorList = () => import('./views/DoctorList.vue')
- 开启Gzip压缩(Nginx配置):
nginx复制gzip on;
gzip_types text/plain application/xml application/javascript;
gzip_min_length 1024;
- 使用WebP格式图片(通过vue-lazyload实现懒加载)
5. 部署实践心得
在宝塔面板部署时遇到几个典型问题:
- SpringBoot应用内存泄漏:
bash复制# 添加JVM参数监控
java -jar -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp clinic.jar
- Vue路由History模式404:
nginx复制location / {
try_files $uri $uri/ /index.html;
}
- 定时任务邮件提醒配置:
properties复制# application-prod.properties
spring.mail.host=smtp.exmail.qq.com
spring.mail.port=465
spring.mail.username=clinic@example.com
spring.mail.password=${MAIL_PASSWORD}
这套系统经过半年运行,最值得分享的经验是:在社区医疗场景下,必须考虑老年用户的操作习惯。我们最终增加了以下功能:
- 超大字体切换按钮
- 语音播报功能(使用Web Speech API)
- 亲属代预约功能(需人脸识别验证)
