
1. 项目概述这个基于SpringBootVueMySQL的健康医院门诊在线挂号系统是我去年指导的一个计算机专业毕业设计项目。整套系统采用前后端分离架构实现了从患者预约挂号到医生接诊的完整业务流程。相比传统医院排队挂号的方式这套系统能有效减少患者等待时间提高医院工作效率。系统主要功能模块包括患者端注册登录、科室查询、医生排班查看、在线预约挂号、订单管理、个人中心医生端排班管理、患者队列查看、接诊处理、病历录入管理员端用户管理、科室管理、医生管理、排班管理、系统监控2. 技术架构解析2.1 后端技术选型后端采用SpringBoot 2.7.3框架主要基于以下考虑快速开发SpringBoot的自动配置和起步依赖大大简化了项目搭建过程生态丰富可以方便集成MyBatis、Redis、RabbitMQ等常用组件易于部署内嵌Tomcat服务器打包成jar即可运行数据库选用MySQL 8.0主要表结构设计CREATE TABLE user ( id int NOT NULL AUTO_INCREMENT, username varchar(50) NOT NULL, password varchar(100) NOT NULL, real_name varchar(50) DEFAULT NULL, phone varchar(20) DEFAULT NULL, role tinyint NOT NULL COMMENT 0-管理员 1-医生 2-患者, PRIMARY KEY (id), UNIQUE KEY idx_username (username) ); CREATE TABLE department ( id int NOT NULL AUTO_INCREMENT, name varchar(50) NOT NULL, description varchar(200) DEFAULT NULL, PRIMARY KEY (id) );2.2 前端技术方案前端采用Vue 2.6 Element UI构建主要特点组件化开发提高代码复用率响应式设计适配PC和移动端Axios实现前后端数据交互Vue Router管理页面路由Vuex进行状态管理典型页面组件结构src/ ├── api/ # 接口定义 ├── assets/ # 静态资源 ├── components/ # 公共组件 │ ├── Header.vue │ ├── Sidebar.vue │ └── ... ├── router/ # 路由配置 ├── store/ # Vuex状态 ├── views/ # 页面视图 │ ├── patient/ # 患者页面 │ ├── doctor/ # 医生页面 │ └── admin/ # 管理员页面 └── main.js # 入口文件3. 核心功能实现3.1 预约挂号流程挂号业务是系统的核心功能主要流程如下患者登录后选择科室系统显示该科室医生列表及排班信息患者选择医生和时段系统检查号源是否可用生成预约订单并锁定号源患者支付挂号费预约成功生成就诊凭证关键代码实现SpringBoot控制器PostMapping(/appointment) public Result makeAppointment(RequestBody AppointmentDTO dto) { // 检查号源是否可用 Schedule schedule scheduleService.getById(dto.getScheduleId()); if(schedule null || schedule.getStatus() ! 1) { return Result.error(该排班不可预约); } // 检查是否重复预约 if(appointmentService.checkDuplicate(dto.getPatientId(), schedule.getDoctorId())) { return Result.error(您已预约过该医生); } // 创建预约记录 Appointment appointment new Appointment(); BeanUtils.copyProperties(dto, appointment); appointment.setAppointmentNo(generateAppointmentNo()); appointment.setStatus(0); // 待支付 if(appointmentService.save(appointment)) { // 锁定号源 schedule.setRemain(schedule.getRemain() - 1); scheduleService.updateById(schedule); return Result.ok(appointment); } return Result.error(预约失败); }3.2 医生接诊模块医生端主要功能实现要点使用WebSocket实现实时患者队列更新接诊状态机设计等待中 → 就诊中 → 已完成可中途转为暂离状态病历录入采用富文本编辑器处方信息关联药品库存系统前端接诊界面关键代码template div classdoctor-container el-card classpatient-queue h3候诊患者列表/h3 el-table :dataqueueData row-clickhandleSelectPatient el-table-column propappointmentNo label预约号/el-table-column el-table-column proppatientName label姓名/el-table-column el-table-column propappointmentTime label预约时间/el-table-column /el-table /el-card el-card classdiagnosis-area v-ifcurrentPatient h3当前就诊{{currentPatient.patientName}}/h3 el-form :modeldiagnosisForm label-width80px el-form-item label主诉 el-input v-modeldiagnosisForm.chiefComplaint/el-input /el-form-item el-form-item label诊断 tinymce-editor v-modeldiagnosisForm.diagnosisResult/tinymce-editor /el-form-item /el-form /el-card /div /template4. 系统部署方案4.1 开发环境配置后端环境JDK 1.8Maven 3.6MySQL 8.0Redis 6.0前端环境Node.js 14.xnpm 6.x4.2 生产环境部署采用Docker容器化部署方案后端Dockerfile示例FROM openjdk:8-jdk-alpine VOLUME /tmp ADD target/hospital-system.jar app.jar ENTRYPOINT [java,-Djava.security.egdfile:/dev/./urandom,-jar,/app.jar]前端Nginx配置示例server { listen 80; server_name yourdomain.com; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://backend:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }部署步骤构建前端静态资源npm run build打包后端应用mvn clean package使用docker-compose编排服务version: 3 services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: hospital volumes: - mysql_data:/var/lib/mysql backend: build: ./backend ports: - 8080:8080 depends_on: - mysql - redis frontend: image: nginx:alpine ports: - 80:80 volumes: - ./frontend/dist:/usr/share/nginx/html - ./nginx.conf:/etc/nginx/conf.d/default.conf redis: image: redis:6-alpine volumes: mysql_data:5. 开发经验与优化建议5.1 性能优化实践缓存策略使用Redis缓存科室列表、医生信息等不常变的数据实现二级缓存Caffeine Redis缓存击穿解决方案互斥锁异步加载数据库优化为常用查询字段建立索引大表分库分表如就诊记录表按月份拆分使用连接池控制连接数前端优化路由懒加载组件异步加载图片等静态资源CDN加速5.2 安全防护措施认证授权JWT实现无状态认证基于角色的访问控制RBAC敏感操作二次验证数据安全密码加密存储BCrypt敏感信息脱敏SQL注入防护MyBatis参数化查询接口安全防重放攻击timestampnonce频率限制Redis实现敏感接口签名验证5.3 扩展性设计微服务化改造预留将挂号、支付、病历等模块拆分为独立服务使用Spring Cloud Alibaba体系服务间通信采用Dubbo RPC多终端适配微信小程序端开发医院内部H5应用管理后台Electron桌面版大数据分析扩展就诊数据接入Hadoop使用Spark进行数据分析可视化大屏展示6. 常见问题解决方案6.1 开发环境问题前端跨域问题// vue.config.js module.exports { devServer: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } }MySQL时区问题# application.yml spring: datasource: url: jdbc:mysql://localhost:3306/hospital?useSSLfalseserverTimezoneAsia/Shanghai6.2 生产环境问题并发挂号冲突使用数据库乐观锁version字段分布式锁Redis实现消息队列削峰填谷定时任务补偿Scheduled(cron 0 0 1 * * ?) public void cancelTimeoutAppointments() { // 取消超时未支付的预约 LambdaQueryWrapperAppointment wrapper new LambdaQueryWrapper(); wrapper.eq(Appointment::getStatus, 0) .le(Appointment::getCreateTime, LocalDateTime.now().minusMinutes(30)); ListAppointment list appointmentService.list(wrapper); list.forEach(item - { item.setStatus(2); // 已取消 appointmentService.updateById(item); // 释放号源 Schedule schedule scheduleService.getById(item.getScheduleId()); schedule.setRemain(schedule.getRemain() 1); scheduleService.updateById(schedule); }); }6.3 业务逻辑问题医生排班冲突检测public boolean checkScheduleConflict(Schedule schedule) { LambdaQueryWrapperSchedule wrapper new LambdaQueryWrapper(); wrapper.eq(Schedule::getDoctorId, schedule.getDoctorId()) .eq(Schedule::getWorkDate, schedule.getWorkDate()) .ne(schedule.getId() ! null, Schedule::getId, schedule.getId()) .and(w - w.between(Schedule::getStartTime, schedule.getStartTime(), schedule.getEndTime()) .or() .between(Schedule::getEndTime, schedule.getStartTime(), schedule.getEndTime())); return scheduleService.count(wrapper) 0; }号源自动释放支付超时自动取消30分钟就诊前一天短信提醒就诊当天提前30分钟签到