作为一名从业十余年的全栈开发者,我近期完成了一个面向社区诊所的在线预约挂号系统。这个系统采用SpringBoot+Vue前后端分离架构,解决了传统诊所面临的三大痛点:患者排队时间长、医生时间分配不均、纸质档案管理混乱。系统上线后,某社区诊所的日均处理患者量提升了40%,医生空闲时段利用率提高了65%。
这个项目特别适合计算机专业学生作为毕业设计选题,原因有三:首先,业务场景贴近生活,需求明确;其次,技术栈主流且完整,涵盖SpringBoot、Vue、MySQL等企业常用技术;最后,系统模块划分清晰,既有基础CRUD操作,也包含排队算法等亮点功能。
后端技术栈:
前端技术栈:
数据库:
code复制[浏览器层] Vue SPA
↑↓ HTTP/HTTPS
[应用层] SpringBoot (REST API)
↑↓ JDBC/MyBatis
[数据层] MySQL Cluster
↑
[缓存层] Redis Sentinel
这种分层架构的优势在于:
系统核心是自主设计的动态权重排队算法,主要考虑以下因素:
Java实现代码片段:
java复制public class QueuePriorityCalculator {
private static final double TIME_WEIGHT = 0.3;
private static final double URGENCY_WEIGHT = 0.4;
// ...其他权重常量
public double calculatePriority(Appointment appt) {
double score = 0;
score += normalize(appt.getBookTime()) * TIME_WEIGHT;
score += (appt.getUrgencyLevel() / 5.0) * URGENCY_WEIGHT;
// ...其他因素计算
return score;
}
private double normalize(LocalDateTime bookTime) {
// 时间标准化处理逻辑
}
}
采用手机号+验证码与账号密码双模式登录:
密码登录流程:
短信登录流程:
安全防护措施:
患者表(patient)
sql复制CREATE TABLE `patient` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`id_card` varchar(18) COLLATE utf8mb4_bin NOT NULL COMMENT '身份证号',
`name` varchar(50) COLLATE utf8mb4_bin NOT NULL COMMENT '姓名',
`phone` varchar(11) COLLATE utf8mb4_bin NOT NULL COMMENT '手机号',
`gender` tinyint NOT NULL DEFAULT '0' COMMENT '性别0未知1男2女',
`birth_date` date DEFAULT NULL COMMENT '出生日期',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_idcard` (`id_card`),
KEY `idx_phone` (`phone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
预约记录表(appointment)
sql复制CREATE TABLE `appointment` (
`id` bigint NOT NULL AUTO_INCREMENT,
`patient_id` bigint NOT NULL,
`doctor_id` bigint NOT NULL,
`department_id` int NOT NULL,
`appt_time` datetime NOT NULL COMMENT '预约时间',
`status` tinyint NOT NULL DEFAULT '0' COMMENT '0待确认1已预约2已取消3已完成',
`urgent_level` tinyint DEFAULT '1' COMMENT '紧急程度1-5',
`symptoms` varchar(500) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '症状描述',
`queue_position` int DEFAULT NULL COMMENT '实时排队位置',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_doctor_time` (`doctor_id`,`appt_time`),
KEY `idx_patient` (`patient_id`,`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
索引策略:
分表方案:
缓存方案:
问题现象:热门医生时段出现超预约情况
解决方案:
java复制@Transactional
public boolean makeAppointment(Long doctorId, LocalDateTime time) {
DoctorSchedule schedule = scheduleMapper.selectForUpdate(doctorId, time);
if (schedule.getRemain() > 0) {
int updated = scheduleMapper.reduceRemain(
doctorId, time, schedule.getVersion());
return updated > 0;
}
return false;
}
java复制public boolean tryLock(String key, long expireSeconds) {
String value = UUID.randomUUID().toString();
Boolean acquired = redisTemplate.opsForValue()
.setIfAbsent(key, value, expireSeconds, TimeUnit.SECONDS);
return Boolean.TRUE.equals(acquired);
}
使用XXL-JOB实现:
配置示例:
java复制@XxlJob("cleanExpiredAppointments")
public void cleanExpiredJobs() {
LocalDateTime now = LocalDateTime.now();
List<Appointment> expired = appointmentMapper.selectExpired(now);
expired.forEach(appt -> {
appt.setStatus(CANCELED);
appointmentMapper.updateById(appt);
// 发送通知
});
}
服务器规格:
Docker部署示例:
dockerfile复制FROM openjdk:11-jre
COPY target/clinic-system.jar /app/
WORKDIR /app
EXPOSE 8080
ENTRYPOINT ["java","-jar","clinic-system.jar",
"--spring.profiles.active=prod"]
JMeter压测结果(单节点):
优化前后对比:
| 场景 | 优化前RT | 优化后RT | 提升幅度 |
|---|---|---|---|
| 科室列表查询 | 450ms | 80ms | 82% |
| 预约提交 | 320ms | 150ms | 53% |
智能分诊系统:
药品库存管理:
数据统计分析:
技术章节建议结构:
在系统开发过程中,我特别注重三个原则:首先是用户体验,所有功能设计都经过诊所工作人员实测反馈;其次是代码质量,SonarQube检测保持A级标准;最后是文档完整性,从API文档到部署手册一应俱全。这个项目让我深刻体会到,一个好的医疗系统不仅要技术过关,更要理解医疗行业的特殊需求。比如排队算法中加入急诊优先逻辑,就是根据实际医护人员的建议增加的。