
简介这是一套面向高校计算机专业毕业设计、课程设计及Java全栈学习者的医院急诊系统完整源码采用Spring Boot后端、Vue前端与MySQL数据库构建可帮助读者快速搭建医疗类管理系统并理解前后端分离架构。压缩包共852个文件约17.7MB涵盖138个Java源文件、50个Vue组件、50个HTML页面、44个CSS样式、153个JS脚本及SQL建表脚本、部署说明文档等前后端代码与数据库结构一应俱全。项目已通过运行测试配套说明文档记录了环境要求、部署步骤与常见问题处理方便在Eclipse或IDEA中导入调试。目前已有68人学习下载适合需要完整项目参考、想掌握Spring Boot与Vue整合开发、或准备毕业答辩与课程作业的读者可据此梳理急诊业务流程、复用代码结构并完成二次开发。1. 急诊系统源码到手之后先别急着跑搞清楚这套 SpringBoot Vue MySQL 到底能干什么拿到一份「基于 SpringBoot 的医院急诊系统源代码」压缩包很多人的第一反应是解压、导入 IDE、点运行。但急诊系统跟普通的增删改查管理系统完全不是一回事——它要处理的是分诊排队、急诊分级、留观床位、抢救记录这些带时间压力和状态流转的业务。如果你只是把它当成一个 SpringBoot 练手项目那这套源码的价值至少浪费了一半。这套技术栈的组合逻辑其实很清晰SpringBoot 负责后端接口和业务逻辑Vue 负责前端交互和实时刷新MySQL 存业务数据。急诊场景对响应速度要求高分诊台护士需要快速录入、医生需要即时看到排队队列所以前后端分离 RESTful 接口是合理选择。适合谁看正在做医疗信息化方向 Java 工程师、需要交付类似系统的外包团队、以及想拿一个真实业务场景练 SpringBoot Vue 全栈的开发者。下面我从环境搭建一路讲到急诊业务里最容易翻车的地方。2. 把源码跑起来JDK、MySQL、Node 三件套的版本对齐与最小启动路径2.1 先看 pom.xml 和 package.json别盲目装最新版源码能不能跑起来八成的问题出在版本不匹配上。热搜里「springboot版本太高」这个词不是白来的——很多医院急诊系统源码是基于 SpringBoot 2.x 写的你本地装了 3.x 的 JDK 17 去跑javax.servlet 包名全变成 jakarta.servlet编译直接报错。拿到源码后第一件事打开pom.xml看三处!-- pom.xml 关键位置 -- parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.7.6/version !-- 记下这个版本号 -- /parent properties java.version1.8/java.version !-- 决定你装 JDK 8 还是 11 -- /properties再看前端package.json里的vue版本和node引擎要求。Vue 2 和 Vue 3 的构建工具链差异很大Vue 2 项目用vue-cli-serviceVue 3 可能用vite。如果package.json里写的是vue: ^2.6.14你就别用 Node 18 以上的版本去npm installnode-sass 编译大概率失败。我一般会先确认这三个版本JDK 版本跟java.version一致MySQL 用 5.7 或 8.0看 JDBC 驱动配置Node 用 14 或 16 跑 Vue 2 项目。版本对齐了后面少折腾两小时。2.2 MySQL 建库与数据导入字符集和时区是两个必调参数急诊系统的数据表通常包含患者信息、分诊记录、床位状态等字段里中文不少。建库时字符集必须用utf8mb4否则生僻字或者 emoji 会插入失败。-- 创建数据库字符集和排序规则都要指定 CREATE DATABASE emergency_db DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci; -- 导入源码附带的 sql 文件假设文件名为 emergency.sql -- 在命令行执行 -- mysql -u root -p emergency_db emergency.sql导入完成后检查一下时区配置。急诊系统里「分诊时间」「抢救开始时间」这些字段对时区敏感如果 MySQL 用的是 UTC 而 Java 应用用的是东八区时间会差 8 小时。在application.yml里把 JDBC URL 补上时区参数spring: datasource: url: jdbc:mysql://localhost:3306/emergency_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: your_password driver-class-name: com.mysql.cj.jdbc.DriverserverTimezoneAsia/Shanghai这个参数不加MySQL 8.0 驱动会报时区错误。useSSLfalse在本地开发环境加上省得控制台一直刷警告。2.3 后端启动从 Maven 依赖下载到接口自测后端启动命令很简单但依赖下载这一步容易卡住。如果公司网络有限制配置一下阿里云镜像!-- settings.xml 中 mirror 配置 -- mirror idaliyunmaven/id mirrorOf*/mirrorOf name阿里云公共仓库/name urlhttps://maven.aliyun.com/repository/public/url /mirror然后在项目根目录执行# 跳过测试打包第一次跑建议加 -DskipTests mvn clean package -DskipTests # 启动 SpringBoot 应用 java -jar target/emergency-system-0.0.1-SNAPSHOT.jar启动成功后先别急着开前端。用 curl 或者 Postman 测一个基础接口比如分诊列表查询curl -X GET http://localhost:8080/api/triage/list?page1size10 \ -H Authorization: Bearer your_token如果返回 401说明接口需要登录态先调登录接口拿 token。如果返回 500看控制台堆栈大概率是数据库连接或者 MyBatis 映射问题。这一步能过后端就算通了。2.4 前端启动npm install 之后的代理配置前端目录下执行npm install然后看vue.config.js或者vite.config.js里的代理配置。前后端分离项目本地开发时前端跑在 8081后端跑在 8080跨域问题靠 devServer 代理解决// vue.config.js module.exports { devServer: { port: 8081, proxy: { /api: { target: http://localhost:8080, // 后端地址 changeOrigin: true, pathRewrite: { ^/api: /api } // 根据实际接口前缀调整 } } } }changeOrigin: true必须加否则后端收到的 Host 头不对某些安全拦截器会拒绝。配好后npm run serve浏览器打开http://localhost:8081能看到登录页就算前端通了。3. 急诊业务核心链路分诊排队、分级调度、留观床位在代码里怎么落地3.1 分诊排队从挂号到叫号的完整状态机急诊系统跟普通门诊最大的区别是「分级」。患者来了先到分诊台护士根据症状体征打一个分级一级濒危、二级危重、三级急症、四级非急症然后进入对应队列。这个逻辑在代码里通常是一个状态机。看后端 Service 层一般会有类似这样的方法// TriageServiceImpl.java 核心逻辑示意 public TriageRecord assignTriageLevel(TriageRequest request) { // 1. 根据评分规则计算分级 int level calculateLevel(request.getVitalSigns(), request.getSymptoms()); // 2. 生成排队序号按分级分别排队 int queueNumber queueService.nextNumber(level); // 3. 写入分诊记录 TriageRecord record new TriageRecord(); record.setPatientId(request.getPatientId()); record.setLevel(level); record.setQueueNumber(queueNumber); record.setStatus(TriageStatus.WAITING); record.setCreateTime(new Date()); triageMapper.insert(record); // 4. 推送到对应诊室的叫号队列 callQueueService.push(level, record); return record; }这里的关键参数是level的计算规则。不同医院的分级标准不一样源码里可能写死了一套规则你需要根据实际需求调整calculateLevel方法。另外queueNumber的生成要注意并发——两个护士同时分诊不能拿到同一个号。常见做法是用 Redis 的INCR或者数据库乐观锁。3.2 分级调度医生端如何按级别拉取待诊队列医生登录后看到的队列不是简单的先来先服务而是按分级权重排序。一级患者永远排在四级前面同级内按挂号时间排序。这个查询在 MyBatis 的 XML 里通常长这样!-- TriageMapper.xml -- select idselectDoctorQueue resultTypeTriageRecord SELECT * FROM triage_record WHERE status WAITING AND department_id #{deptId} ORDER BY level ASC, create_time ASC LIMIT #{offset}, #{size} /selectORDER BY level ASC, create_time ASC这一句就是分级调度的核心。level 越小优先级越高同级别按时间先后。如果医院要求「二级患者等待超过 10 分钟自动升级为一级」那还需要一个定时任务去扫描超时记录并更新 level。前端 Vue 这边医生端队列通常用轮询或者 WebSocket 刷新。轮询简单但浪费请求WebSocket 实时但增加复杂度。源码里如果用的是setInterval每 5 秒拉一次对于急诊场景够用了别过度设计。3.3 留观床位状态流转与并发抢占留观区床位是急诊系统的稀缺资源。一个床位从「空闲」到「占用」再到「清洁中」最后回到「空闲」状态流转必须严格。代码里常见的问题是两个护士同时给同一个床位办理入住导致数据覆盖。处理方式有两种。一种是数据库层面加唯一约束或者乐观锁-- 更新床位状态时带上旧状态条件 UPDATE bed SET status OCCUPIED, patient_id #{patientId} WHERE id #{bedId} AND status IDLE; -- 检查 affectedRows如果为 0 说明被别人抢了另一种是在 Service 层用synchronized或者分布式锁。单机部署用synchronized够用多节点部署就得上 Redis 锁。源码里如果没处理这个并发你在测试环境可能碰不到一上生产就会出问题。床位状态变更后前端需要刷新床位图。Vue 组件里通常是一个二维数组渲染床位卡片点击空闲床位弹出入住表单提交后重新拉取列表。这部分逻辑不复杂但要注意表单校验——患者 ID 必填、床位 ID 从点击事件里带过来别搞混。4. 避坑与排查急诊系统源码落地时最容易翻车的 5 个地方4.1 现象前端页面能打开但所有接口返回 404原因Vue 的代理配置里pathRewrite写错了或者后端server.servlet.context-path配了前缀但前端没加。解决打开浏览器开发者工具 Network 面板看请求的实际 URL 是什么。如果请求发到了http://localhost:8081/api/xxx但后端实际接口是http://localhost:8080/emergency/api/xxx那就要在代理里把pathRewrite改成{ ^/api: /emergency/api }。或者直接看后端application.yml里有没有context-path配置。4.2 现象MySQL 插入中文报错Incorrect string value原因数据库或者表的字符集不是utf8mb4或者 JDBC URL 里没指定characterEncodingutf8。解决先查SHOW CREATE TABLE triage_record;看表的字符集。如果是latin1或者utf8不是 utf8mb4执行ALTER TABLE triage_record CONVERT TO CHARACTER SET utf8mb4;。然后确认 JDBC URL 里有useUnicodetruecharacterEncodingutf8。两个都对了中文才能正常写入。4.3 现象分诊排队序号重复两个患者拿到同一个号原因queueService.nextNumber(level)方法没有做并发控制两个线程同时读到同一个最大值然后各自加一。解决把序号生成放到数据库里用UPDATE ... SET current_value current_value 1然后查回来或者用 Redis 的INCR命令。如果源码里用的是SELECT MAX(queue_number) 1那必须改掉。急诊场景下号重复是严重问题护士叫号会乱。4.4 现象医生端队列刷新后顺序变了一级患者跑到后面去了原因排序字段用错了或者前端拿到数据后又做了一次本地排序把顺序打乱。解决检查 MyBatis 的ORDER BY是不是level ASC, create_time ASC。然后看 Vue 组件里有没有对数组做sort()操作。如果有确认排序规则跟后端一致。另外注意level字段的类型如果是字符串类型10会排在2前面必须用数字类型。4.5 现象床位状态更新成功但前端显示没变原因更新接口返回成功但前端没有重新拉取数据或者 Vue 的响应式没触发。解决确认更新成功后调用了this.fetchBedList()重新获取数据。如果用了 Vuex检查 mutation 有没有正确提交。还有一种情况是后端返回了更新后的对象但前端直接改了本地数组的某个元素而 Vue 2 对数组下标赋值不触发响应式需要用this.$set()或者重新赋值整个数组。5. 从能跑到好用急诊系统源码二次开发时我常用的三个进阶技巧5.1 用 MyBatis-Plus 代码生成器快速扩展新表急诊系统源码里如果用的是 MyBatis-Plus那扩展新业务表会快很多。比如医院要加一个「急诊手术申请」模块你只需要建好表然后跑一下代码生成器// CodeGenerator.java 核心配置 AutoGenerator generator new AutoGenerator(); generator.setDataSource(new DataSourceConfig() .setUrl(jdbc:mysql://localhost:3306/emergency_db?serverTimezoneAsia/Shanghai) .setUsername(root) .setPassword(your_password) .setDriverName(com.mysql.cj.jdbc.Driver)); GlobalConfig globalConfig new GlobalConfig() .setOutputDir(System.getProperty(user.dir) /src/main/java) .setAuthor(your_name) .setOpen(false); generator.setGlobalConfig(globalConfig); generator.setPackageInfo(new PackageConfig() .setParent(com.emergency) .setEntity(entity) .setMapper(mapper) .setService(service) .setController(controller)); generator.execute();跑完之后 entity、mapper、service、controller 全有了你只需要改业务逻辑。这比手写快十倍而且不容易漏掉字段。注意生成之前把表注释写好生成的 Swagger 文档会好看很多。5.2 前端打包放进 SpringBoot 的 static 目录开发阶段前后端分离没问题但交付时如果客户只想要一个 jar 包那就需要把 Vue 打包产物放到 SpringBoot 的src/main/resources/static下。# 前端目录执行打包 npm run build # 把 dist 目录下的文件复制到后端 static 目录 cp -r dist/* ../emergency-backend/src/main/resources/static/然后在 SpringBoot 里加一个配置让所有非 API 请求都转发到index.htmlConfiguration public class WebConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/**) .addResourceLocations(classpath:/static/); } }这样打出来的 jar 包直接java -jar就能跑前端页面和后端接口在同一个端口省去了 Nginx 配置。注意 Vue Router 要用 hash 模式history 模式需要额外配置否则刷新页面会 404。5.3 用日志和埋点定位急诊业务里的「玄学」问题急诊系统上线后最怕的是「有时候叫号没反应」「有时候床位状态不对」。这种偶发问题靠猜没用得靠日志。我一般会在关键业务方法入口和出口打上 traceId// 在分诊方法入口 String traceId UUID.randomUUID().toString().substring(0, 8); log.info([{}] 分诊开始, patientId{}, level{}, traceId, patientId, level); // ... 业务逻辑 log.info([{}] 分诊完成, queueNumber{}, traceId, queueNumber);然后在 Nginx 或者网关层把 traceId 透传到前端响应头里。出问题时让护士报一下页面上的 traceId你直接去日志平台搜这个 ID整条链路一目了然。这个习惯我保持了五年比任何调试工具都好使。最后说一个我自己的教训急诊系统的源码拿到手别急着改业务逻辑先把分诊、叫号、床位这三个核心链路的代码读一遍画一张状态流转图。图画清楚了后面加功能还是改 bug 都不会迷路。希望帮到你。本文还有配套的精品资源点击获取