作为一名拥有十年Java全栈开发经验的工程师,我近期完成了一个基于SpringBoot的社区诊所在线挂号与排队系统。这个项目源于实际需求——传统社区诊所的纸质挂号方式效率低下,患者排队时间长,医生工作安排混乱。通过这个系统,患者可以提前在线预约,实时查看排队情况,医生也能有序安排诊疗工作。
这个毕业设计项目采用了当前主流的SpringBoot+Vue前后端分离架构,整合了MyBatisPlus、Shiro等框架,实现了完整的用户管理、挂号预约、排队叫号等功能模块。系统特别注重实际应用场景,比如考虑到老年用户的使用习惯,界面设计简洁明了;针对高峰期并发访问,做了相应的性能优化。
技术选型思考:为什么选择SpringBoot+Vue?
- SpringBoot的自动配置特性大幅减少了XML配置,内嵌Tomcat简化部署
- Vue的组件化开发模式适合构建交互复杂的前端应用
- MyBatisPlus的代码生成器可以快速构建CRUD接口
- 这种技术组合既能保证开发效率,又能满足毕业设计的技术深度要求
系统采用经典的三层架构设计:
code复制[浏览器] ←HTTP→ [Nginx] ←HTTP→ [SpringBoot] ←JDBC→ [MySQL]
↑
[Vue静态资源]
这种架构的优势在于:
系统主要包含以下功能模块:
开发心得:模块划分要遵循单一职责原则,每个模块的代码量控制在300-500行为宜,这样既方便调试也便于后期维护。
sql复制-- 用户表
CREATE TABLE `sys_user` (
`user_id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '用户名',
`password` varchar(100) NOT NULL COMMENT '密码',
`real_name` varchar(50) COMMENT '真实姓名',
`phone` varchar(20) COMMENT '手机号',
`role_id` int COMMENT '角色ID',
PRIMARY KEY (`user_id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 医生表
CREATE TABLE `doctor` (
`doctor_id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`department_id` int NOT NULL COMMENT '科室ID',
`title` varchar(50) COMMENT '职称',
`introduction` text COMMENT '简介',
PRIMARY KEY (`doctor_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 预约记录表
CREATE TABLE `appointment` (
`id` bigint NOT NULL AUTO_INCREMENT,
`patient_id` bigint NOT NULL,
`doctor_id` bigint NOT NULL,
`appoint_time` datetime NOT NULL,
`status` tinyint DEFAULT 0 COMMENT '0-待就诊 1-已就诊 2-已取消',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_doctor_time` (`doctor_id`,`appoint_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
索引设计:
事务处理:
java复制@Transactional(rollbackFor = Exception.class)
public void makeAppointment(AppointmentDTO dto) {
// 检查时间冲突
int conflict = appointmentMapper.checkTimeConflict(dto.getDoctorId(), dto.getAppointTime());
if(conflict > 0) {
throw new BusinessException("该时间段已被预约");
}
// 创建预约记录
Appointment appointment = new Appointment();
BeanUtils.copyProperties(dto, appointment);
appointmentMapper.insert(appointment);
// 更新医生日程
scheduleService.updateDoctorSchedule(dto.getDoctorId(), dto.getAppointTime());
}
踩坑记录:最初没有加事务注解,在高并发测试时出现了超预约的情况。后来通过@Transactional和乐观锁解决了这个问题。
挂号流程采用状态机模式设计:
code复制[可选] → [已预约] → [已就诊]/[已取消]
关键代码实现:
java复制public Result makeAppointment(AppointmentDTO dto) {
// 参数校验
if(dto.getPatientId() == null || dto.getDoctorId() == null) {
return Result.error("参数不完整");
}
// 业务校验
Doctor doctor = doctorService.getById(dto.getDoctorId());
if(doctor == null) {
return Result.error("医生不存在");
}
// 执行预约
return appointmentService.makeAppointment(dto);
}
前端通过WebSocket实时获取排队状态:
javascript复制// 建立WebSocket连接
const socket = new WebSocket(`ws://${location.host}/queue/ws`);
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
// 更新排队列表
this.queueList = data.queueList;
// 当前叫号提示
if(data.currentNumber) {
this.currentNumber = data.currentNumber;
}
};
后端推送逻辑:
java复制@ServerEndpoint("/queue/ws")
public class QueueWebSocket {
private static final Map<Long, Session> sessions = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session, @PathParam("deptId") Long deptId) {
sessions.put(deptId, session);
// 推送初始队列
pushQueueData(deptId);
}
public static void pushQueueUpdate(Long deptId) {
Session session = sessions.get(deptId);
if(session != null && session.isOpen()) {
session.getAsyncRemote().sendText(JSON.toJSONString(getQueueData(deptId)));
}
}
}
采用Shiro框架实现RBAC权限控制:
java复制@Bean
public ShiroFilterFactoryBean shiroFilter() {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
factoryBean.setSecurityManager(securityManager());
Map<String, String> filterMap = new LinkedHashMap<>();
// 静态资源不拦截
filterMap.put("/static/**", "anon");
// 登录接口开放
filterMap.put("/api/login", "anon");
// 其他请求需要认证
filterMap.put("/**", "authc");
factoryBean.setFilterChainDefinitionMap(filterMap);
return factoryBean;
}
java复制public String encryptPassword(String password) {
return new SimpleHash("SHA-256", password, null, 1024).toString();
}
SQL注入防护:
XSS防护:
使用JMeter进行压力测试:
优化措施:
问题现象:高峰期系统响应变慢,甚至出现超时。
排查过程:
解决方案:
经验总结:系统上线前一定要进行充分的压力测试,提前发现性能瓶颈。监控系统要完善,便于快速定位问题。
推荐部署架构:
code复制[Nginx] ←负载均衡→ [SpringBoot集群] ←→ [MySQL主从] ←→ [Redis缓存]
Docker部署示例:
dockerfile复制# SpringBoot应用Dockerfile
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD target/clinic-system.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
yaml复制stages:
- build
- test
- deploy
build:
stage: build
script:
- mvn clean package -DskipTests
test:
stage: test
script:
- mvn test
deploy:
stage: deploy
script:
- scp target/*.jar user@server:/app/
- ssh user@server "systemctl restart clinic"
如果想进一步提升这个项目的技术深度,可以考虑以下方向:
微服务化改造:
大数据分析:
移动端适配:
智能推荐:
这个项目从技术选型到实现都采用了当前企业主流的开发方案,不仅适合作为毕业设计,稍加完善也可以直接用于实际生产环境。我在开发过程中特别注重代码质量和系统性能,确保项目既展示了足够的技术深度,又具备良好的可扩展性。