Spring Boot实战:构建医院床位资源管理系统,实现全院床位智能调配 📅 发布时间:2026/8/21 23:38:48 👁 浏览次数: 这次我们来看一个基于 Spring Boot 的医院床位资源管理系统——“全院一张床”。这个项目不是概念演示而是一个旨在解决医院床位资源紧张、科室间调配困难、床位利用率不均衡等实际痛点的实战型系统。对于医院信息科、医疗软件开发者以及学习 Spring Boot 项目实战的同学来说它提供了一个从设计到实现的完整参考。项目的核心思路是打破传统按科室固定分配床位的模式建立一个全院统一的床位资源池实现床位的动态、智能调配。这不仅能提升床位周转率还能优化患者入院流程。本文将带你从零开始理解其设计思路并完成一个可运行的系统搭建与功能验证。我们会重点关注系统的架构设计、核心功能实现、数据库建模以及如何通过 Spring Boot 快速构建 RESTful API 服务。1. 核心能力速览能力项说明项目类型基于 Spring Boot 的医院床位资源管理后台系统技术栈Spring Boot, Spring MVC, MyBatis/Spring Data JPA, MySQL, (可选)Redis, Vue.js (前端)核心功能床位资源池管理、患者智能分床、床位动态调配、床位状态监控、统计报表部署方式传统 Jar 包部署、Docker 容器化部署接口能力提供完整的 RESTful API支持与医院现有系统HIS、EMR集成适合场景医院床位资源优化管理、医疗信息化教学、Spring Boot 全栈项目实战2. 适用场景与使用边界这个系统主要服务于两类用户一是医院的管理者与信息科他们需要一个工具来可视化全院床位状态并执行高效的跨科室床位调度二是软件开发者与学习者可以通过这个项目深入理解 Spring Boot 在企业级应用中的分层架构、复杂业务逻辑设计以及前后端分离的协作模式。它能解决的核心问题包括资源利用率低某些科室床位紧张而另一些科室床位空置。调配流程繁琐跨科室借床依赖人工电话沟通效率低下且易出错。状态不透明管理者无法实时掌握全院床位的占用、空闲、消毒、维修等状态。缺乏数据支撑缺少床位周转率、平均住院日等关键指标的统计分析。使用边界与注意事项非临床系统本系统专注于床位资源管理不涉及具体的电子病历、医嘱、护理等临床业务流程。它需要与医院核心的HIS医院信息系统进行数据对接如患者信息、科室信息。数据安全与隐私处理患者住院信息时必须严格遵守《个人信息保护法》和医疗数据安全规范。系统部署在内网环境并对敏感数据进行脱敏或加密处理。流程依赖系统的成功运行依赖于医院内部建立配套的管理制度和操作流程系统仅是工具支撑。3. 环境准备与前置条件在开始部署和编码之前请确保你的开发或测试环境满足以下要求。基础运行环境操作系统Windows 10/11, macOS, 或 Linux (如 Ubuntu 20.04)。推荐使用 Linux 服务器进行生产环境部署。Java 开发套件JDK 8 或 JDK 11 (推荐 JDK 11与 Spring Boot 2.x 兼容性更好)。可通过java -version命令验证。项目构建工具Apache Maven 3.6 或 Gradle。本文以 Maven 为例。集成开发环境IntelliJ IDEA (推荐) 或 Eclipse。确保已安装 Spring Boot 相关插件。数据库MySQL 5.7 或 8.0。需要提前创建好数据库例如hospital_bed_db。(可选) 缓存Redis 5.0用于缓存热点数据如科室列表、床位状态字典提升系统性能。(可选) 前端环境Node.js (14)用于运行或构建 Vue.js 前端项目。项目结构与依赖管理一个标准的 Spring Boot “全院一张床”项目会采用分层架构。在开始前你应通过 Maven 的pom.xml文件管理依赖。核心依赖通常包括spring-boot-starter-web用于构建Web和RESTful API。spring-boot-starter-data-jpa或mybatis-spring-boot-starter用于数据持久化。mysql-connector-javaMySQL数据库驱动。spring-boot-starter-test单元测试。lombok简化实体类代码。spring-boot-starter-cache与spring-boot-starter-data-redis(可选) 用于集成缓存。4. 数据库设计与核心表结构“全院一张床”系统的核心在于数据模型。一个精简而有效的设计是项目成功的基础。以下是几个核心实体表的设计思路。1. 科室表 (department):存储医院所有科室的基本信息是床位归属的逻辑单元。CREATE TABLE department ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键ID, dept_code varchar(50) NOT NULL COMMENT 科室编码, dept_name varchar(100) NOT NULL COMMENT 科室名称, dept_type varchar(20) DEFAULT NULL COMMENT 科室类型 (内科/外科/急诊...), bed_capacity int(11) DEFAULT 0 COMMENT 核定床位数, status tinyint(4) DEFAULT 1 COMMENT 状态 (1启用0停用), create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_dept_code (dept_code) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT科室信息表;2. 床位表 (bed):这是系统的核心表每一张物理床位对应一条记录。其current_dept_id字段是实现“动态归属”的关键。CREATE TABLE bed ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键ID, bed_code varchar(50) NOT NULL COMMENT 床位编码 (如: 3F-101), bed_name varchar(100) DEFAULT NULL COMMENT 床位名称, physical_dept_id bigint(20) NOT NULL COMMENT 物理所属科室ID, current_dept_id bigint(20) DEFAULT NULL COMMENT 当前逻辑所属科室ID (为空则表示在资源池), bed_status varchar(20) NOT NULL DEFAULT IDLE COMMENT 床位状态 (IDLE空闲, OCCUPIED占用, CLEANING消毒, MAINTENANCE维修, RESERVED预留), bed_type varchar(20) DEFAULT NULL COMMENT 床位类型 (普通床, 抢救床, 隔离床...), equipment_info varchar(500) DEFAULT NULL COMMENT 设备信息, is_enabled tinyint(4) DEFAULT 1 COMMENT 是否启用, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_bed_code (bed_code), KEY idx_current_dept (current_dept_id), KEY idx_status (bed_status), CONSTRAINT fk_bed_physical_dept FOREIGN KEY (physical_dept_id) REFERENCES department (id), CONSTRAINT fk_bed_current_dept FOREIGN KEY (current_dept_id) REFERENCES department (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT床位信息表;3. 患者住院记录表 (hospitalization):记录患者与床位的绑定关系是业务流转的核心。CREATE TABLE hospitalization ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键ID, admission_no varchar(50) NOT NULL COMMENT 住院号, patient_id varchar(50) NOT NULL COMMENT 患者ID (关联HIS), patient_name varchar(100) NOT NULL COMMENT 患者姓名, bed_id bigint(20) NOT NULL COMMENT 所占床位ID, admitting_dept_id bigint(20) NOT NULL COMMENT 收治科室ID, actual_dept_id bigint(20) DEFAULT NULL COMMENT 实际入住科室ID (动态调配后可能不同), admission_time datetime NOT NULL COMMENT 入院时间, discharge_time datetime DEFAULT NULL COMMENT 出院时间, status varchar(20) DEFAULT IN_HOSPITAL COMMENT 状态 (IN_HOSPITAL在院, DISCHARGED已出院, TRANSFERRED已转科), create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_admission_no (admission_no), KEY idx_bed_id (bed_id), KEY idx_patient (patient_id), CONSTRAINT fk_hosp_bed FOREIGN KEY (bed_id) REFERENCES bed (id), CONSTRAINT fk_hosp_admit_dept FOREIGN KEY (admitting_dept_id) REFERENCES department (id), CONSTRAINT fk_hosp_actual_dept FOREIGN KEY (actual_dept_id) REFERENCES department (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT患者住院记录表;4. 床位调配记录表 (bed_transfer_log):记录每一次床位调配的完整过程用于审计和追溯。CREATE TABLE bed_transfer_log ( id bigint(20) NOT NULL AUTO_INCREMENT, bed_id bigint(20) NOT NULL COMMENT 床位ID, from_dept_id bigint(20) DEFAULT NULL COMMENT 调出科室ID, to_dept_id bigint(20) NOT NULL COMMENT 调入科室ID, transfer_reason varchar(255) DEFAULT NULL COMMENT 调配原因, operator_id varchar(50) DEFAULT NULL COMMENT 操作员, transfer_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 调配时间, hospitalization_id bigint(20) DEFAULT NULL COMMENT 关联的住院记录ID (如果有患者), PRIMARY KEY (id), KEY idx_bed (bed_id), KEY idx_time (transfer_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT床位调配日志表;5. Spring Boot 后端核心功能实现有了数据模型接下来我们使用 Spring Boot 实现核心业务逻辑。我们将采用经典的三层架构Controller - Service - Repository。5.1 项目配置与启动首先配置application.yml或application.properties文件连接数据库。# application.yml spring: datasource: url: jdbc:mysql://localhost:3306/hospital_bed_db?useUnicodetruecharacterEncodingutf-8useSSLfalseserverTimezoneAsia/Shanghai username: your_username password: your_password driver-class-name: com.mysql.cj.jdbc.Driver jpa: # 如果使用 JPA hibernate: ddl-auto: update # 首次启动可设为update生产环境用validate或none show-sql: true properties: hibernate: dialect: org.hibernate.dialect.MySQL8Dialect # 可选 Redis 配置 # redis: # host: localhost # port: 6379 # password: # database: 0 server: port: 8080 servlet: context-path: /api logging: level: com.yourcompany.hospital: debug主启动类非常简单package com.yourcompany.hospital; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; // 可选 SpringBootApplication EnableCaching // 启用缓存注解 public class HospitalBedApplication { public static void main(String[] args) { SpringApplication.run(HospitalBedApplication.class, args); } }启动后访问http://localhost:8080/api即可看到服务已运行。5.2 床位状态查询与统计接口这是最基础也是最常用的功能。我们创建一个BedController和BedService。实体类 (Bed.java):package com.yourcompany.hospital.entity; import lombok.Data; import javax.persistence.*; import java.time.LocalDateTime; Data Entity Table(name bed) public class Bed { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String bedCode; private String bedName; ManyToOne JoinColumn(name physical_dept_id, referencedColumnName id) private Department physicalDept; // 物理科室 ManyToOne JoinColumn(name current_dept_id, referencedColumnName id) private Department currentDept; // 当前逻辑科室 private String bedStatus; // IDLE, OCCUPIED... private String bedType; private Boolean isEnabled; private LocalDateTime createTime; private LocalDateTime updateTime; }服务层 (BedService.java):package com.yourcompany.hospital.service; import com.yourcompany.hospital.entity.Bed; import com.yourcompany.hospital.repository.BedRepository; import com.yourcompany.hospital.vo.BedStatsVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; import java.util.stream.Collectors; Service public class BedService { Autowired private BedRepository bedRepository; // 查询某个科室的床位列表 public ListBed getBedsByDept(Long deptId, String status) { if (deptId ! null status ! null) { return bedRepository.findByCurrentDeptIdAndBedStatus(deptId, status); } else if (deptId ! null) { return bedRepository.findByCurrentDeptId(deptId); } else if (status ! null) { return bedRepository.findByBedStatus(status); } else { return bedRepository.findAll(); } } // 获取全院床位统计 (可缓存) Cacheable(value bedStats, key all) public BedStatsVO getBedStatistics() { ListBed allBeds bedRepository.findAll(); long total allBeds.size(); long idle allBeds.stream().filter(b - IDLE.equals(b.getBedStatus())).count(); long occupied allBeds.stream().filter(b - OCCUPIED.equals(b.getBedStatus())).count(); // ... 其他状态统计 MapLong, Long deptBedCount allBeds.stream() .filter(b - b.getCurrentDept() ! null) .collect(Collectors.groupingBy(b - b.getCurrentDept().getId(), Collectors.counting())); BedStatsVO stats new BedStatsVO(); stats.setTotalBeds(total); stats.setIdleBeds(idle); stats.setOccupiedBeds(occupied); stats.setOccupationRate(total 0 ? (double) occupied / total : 0.0); stats.setDeptBedDistribution(deptBedCount); return stats; } // 查找空闲床位 (智能推荐逻辑可扩展) public ListBed findAvailableBeds(Long requiredDeptId, String preferredBedType) { // 1. 优先在当前申请科室的空闲床位中查找 ListBed bedsInDept bedRepository.findByCurrentDeptIdAndBedStatus(requiredDeptId, IDLE); if (!bedsInDept.isEmpty()) { if (preferredBedType ! null) { return bedsInDept.stream().filter(b - preferredBedType.equals(b.getBedType())).collect(Collectors.toList()); } return bedsInDept; } // 2. 当前科室无空闲从全院资源池current_dept_id为NULL中查找 ListBed bedsInPool bedRepository.findByCurrentDeptIdIsNullAndBedStatus(IDLE); // 可以在此处加入更复杂的推荐算法如距离、科室相关性等 return bedsInPool; } }控制层 (BedController.java):package com.yourcompany.hospital.controller; import com.yourcompany.hospital.entity.Bed; import com.yourcompany.hospital.service.BedService; import com.yourcompany.hospital.vo.BedStatsVO; import com.yourcompany.hospital.vo.CommonResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; RestController RequestMapping(/beds) public class BedController { Autowired private BedService bedService; GetMapping public CommonResultListBed listBeds(RequestParam(required false) Long deptId, RequestParam(required false) String status) { ListBed beds bedService.getBedsByDept(deptId, status); return CommonResult.success(beds); } GetMapping(/stats) public CommonResultBedStatsVO getStatistics() { BedStatsVO stats bedService.getBedStatistics(); return CommonResult.success(stats); } GetMapping(/available) public CommonResultListBed findAvailableBeds(RequestParam Long deptId, RequestParam(required false) String bedType) { ListBed availableBeds bedService.findAvailableBeds(deptId, bedType); return CommonResult.success(availableBeds); } }5.3 床位动态调配接口这是“全院一张床”的核心业务流程。调配可能涉及无患者的空闲床位也可能涉及带有患者的床位转科。服务层方法 (BedTransferService.java):package com.yourcompany.hospital.service; import com.yourcompany.hospital.entity.Bed; import com.yourcompany.hospital.entity.BedTransferLog; import com.yourcompany.hospital.entity.Hospitalization; import com.yourcompany.hospital.repository.BedRepository; import com.yourcompany.hospital.repository.BedTransferLogRepository; import com.yourcompany.hospital.repository.HospitalizationRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; Service public class BedTransferService { Autowired private BedRepository bedRepository; Autowired private BedTransferLogRepository transferLogRepository; Autowired private HospitalizationRepository hospitalizationRepository; /** * 床位调配不带患者 * param bedId 床位ID * param targetDeptId 目标科室ID * param reason 调配原因 * param operator 操作员 */ Transactional public void transferBed(Long bedId, Long targetDeptId, String reason, String operator) { Bed bed bedRepository.findById(bedId).orElseThrow(() - new RuntimeException(床位不存在)); if (OCCUPIED.equals(bed.getBedStatus())) { throw new RuntimeException(该床位已被占用无法直接调配); } Long fromDeptId bed.getCurrentDept() ! null ? bed.getCurrentDept().getId() : null; // 更新床位的当前所属科室 // 这里需要注入Department的Repository或Service来获取目标科室实体 // bed.setCurrentDept(targetDept); bedRepository.updateCurrentDept(bedId, targetDeptId); // 假设有自定义更新方法 // 记录日志 BedTransferLog log new BedTransferLog(); log.setBedId(bedId); log.setFromDeptId(fromDeptId); log.setToDeptId(targetDeptId); log.setTransferReason(reason); log.setOperatorId(operator); log.setTransferTime(LocalDateTime.now()); transferLogRepository.save(log); } /** * 患者转科连带床位调配 * param hospitalizationId 住院记录ID * param targetDeptId 目标科室ID * param reason 转科原因 * param operator 操作员 */ Transactional public void transferPatientWithBed(Long hospitalizationId, Long targetDeptId, String reason, String operator) { Hospitalization hospitalization hospitalizationRepository.findById(hospitalizationId) .orElseThrow(() - new RuntimeException(住院记录不存在)); Bed bed hospitalization.getBed(); Long fromDeptId hospitalization.getActualDeptId(); // 1. 更新住院记录的实际入住科室 hospitalization.setActualDeptId(targetDeptId); hospitalizationRepository.save(hospitalization); // 2. 更新床位的当前所属科室 bedRepository.updateCurrentDept(bed.getId(), targetDeptId); // 3. 记录转科调配日志 BedTransferLog log new BedTransferLog(); log.setBedId(bed.getId()); log.setFromDeptId(fromDeptId); log.setToDeptId(targetDeptId); log.setTransferReason(reason); log.setOperatorId(operator); log.setTransferTime(LocalDateTime.now()); log.setHospitalizationId(hospitalizationId); transferLogRepository.save(log); } }6. 前端界面与功能演示后端 API 准备好后我们需要一个前端界面进行交互。这里以 Vue.js Element UI 为例展示几个核心页面的关键代码。6.1 全院床位状态总览页这个页面通过调用/api/beds/stats接口以图表和卡片形式展示核心数据。template div classdashboard el-row :gutter20 el-col :span6 el-card div classcard-content div classcard-title总床位数/div div classcard-number{{ stats.totalBeds }}/div /div /el-card /el-col el-col :span6 el-card div classcard-content div classcard-title占用床位/div div classcard-number stylecolor: #f56c6c;{{ stats.occupiedBeds }}/div /div /el-card /el-col el-col :span6 el-card div classcard-content div classcard-title空闲床位/div div classcard-number stylecolor: #67c23a;{{ stats.idleBeds }}/div /div /el-card /el-col el-col :span6 el-card div classcard-content div classcard-title床位使用率/div div classcard-number{{ (stats.occupationRate * 100).toFixed(1) }}%/div /div /el-card /el-col /el-row el-row :gutter20 stylemargin-top: 20px; el-col :span12 el-card div slotheader科室床位分布/div div iddeptBedChart styleheight: 300px;/div /el-card /el-col el-col :span12 el-card div slotheader床位状态分布/div div idstatusPieChart styleheight: 300px;/div /el-card /el-col /el-row /div /template script import * as echarts from echarts; import { getBedStatistics } from /api/bed; export default { name: Dashboard, data() { return { stats: { totalBeds: 0, idleBeds: 0, occupiedBeds: 0, occupationRate: 0 } }; }, mounted() { this.loadStatistics(); }, methods: { async loadStatistics() { const res await getBedStatistics(); if (res.code 200) { this.stats res.data; this.$nextTick(() { this.renderDeptChart(res.data.deptBedDistribution); this.renderStatusPie(); }); } }, renderDeptChart(distributionMap) { // 使用 ECharts 渲染柱状图 const chartDom document.getElementById(deptBedChart); const myChart echarts.init(chartDom); const option { xAxis: { type: category, data: Object.keys(distributionMap) }, yAxis: { type: value }, series: [{ data: Object.values(distributionMap), type: bar }] }; myChart.setOption(option); }, renderStatusPie() { // 渲染饼图 } } }; /script6.2 床位管理列表与调配操作这个页面展示床位列表并提供“调配”按钮。template div classbed-management el-card div slotheader classclearfix span床位管理/span el-button stylefloat: right; typeprimary clickhandleAdd新增床位/el-button /div el-table :databedList stripe el-table-column propbedCode label床位编码/el-table-column el-table-column propbedName label床位名称/el-table-column el-table-column propphysicalDept.deptName label物理科室/el-table-column el-table-column propcurrentDept.deptName label当前科室/el-table-column el-table-column propbedStatus label状态 template slot-scopescope el-tag :typegetStatusTagType(scope.row.bedStatus){{ scope.row.bedStatus }}/el-tag /template /el-table-column el-table-column label操作 width200 template slot-scopescope el-button sizemini clickhandleView(scope.row)查看/el-button el-button sizemini typeprimary clickhandleTransfer(scope.row) :disabledscope.row.bedStatus OCCUPIED调配/el-button /template /el-table-column /el-table /el-card !-- 床位调配对话框 -- el-dialog title床位调配 :visible.synctransferDialogVisible el-form :modeltransferForm label-width100px el-form-item label目标科室 el-select v-modeltransferForm.targetDeptId placeholder请选择 el-option v-fordept in deptList :keydept.id :labeldept.deptName :valuedept.id/el-option /el-select /el-form-item el-form-item label调配原因 el-input v-modeltransferForm.reason typetextarea/el-input /el-form-item /el-form div slotfooter el-button clicktransferDialogVisible false取消/el-button el-button typeprimary clickconfirmTransfer确定/el-button /div /el-dialog /div /template script import { getBedList, transferBed } from /api/bed; import { getDeptList } from /api/department; export default { name: BedManagement, data() { return { bedList: [], deptList: [], transferDialogVisible: false, currentBed: null, transferForm: { targetDeptId: , reason: } }; }, mounted() { this.loadBedList(); this.loadDeptList(); }, methods: { async loadBedList() { const res await getBedList(); if (res.code 200) { this.bedList res.data; } }, async loadDeptList() { const res await getDeptList(); if (res.code 200) { this.deptList res.data; } }, handleTransfer(row) { this.currentBed row; this.transferForm.targetDeptId ; this.transferForm.reason ; this.transferDialogVisible true; }, async confirmTransfer() { if (!this.transferForm.targetDeptId) { this.$message.warning(请选择目标科室); return; } const params { bedId: this.currentBed.id, targetDeptId: this.transferForm.targetDeptId, reason: this.transferForm.reason, operator: this.$store.state.user.name // 从状态管理获取当前用户 }; const res await transferBed(params); if (res.code 200) { this.$message.success(调配成功); this.transferDialogVisible false; this.loadBedList(); // 刷新列表 } else { this.$message.error(res.message || 调配失败); } }, getStatusTagType(status) { const map { IDLE: success, OCCUPIED: danger, CLEANING: warning, MAINTENANCE: info }; return map[status] || ; } } }; /script7. 系统部署与运行验证完成开发后我们需要将系统打包部署并进行功能验证。7.1 后端打包与运行使用 Maven 打包 Spring Boot 应用为可执行 Jar 包。# 在项目根目录下执行 mvn clean package -DskipTests打包成功后会在target目录下生成hospital-bed-0.0.1-SNAPSHOT.jar文件。运行 Jar 包java -jar target/hospital-bed-0.0.1-SNAPSHOT.jar或者指定配置文件java -jar -Dspring.profiles.activeprod target/hospital-bed-0.0.1-SNAPSHOT.jar使用 Docker 部署 (可选)创建DockerfileFROM openjdk:11-jre-slim VOLUME /tmp COPY target/hospital-bed-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT [java,-Djava.security.egdfile:/dev/./urandom,-jar,/app.jar]构建并运行镜像docker build -t hospital-bed . docker run -d -p 8080:8080 --name bed-system hospital-bed7.2 功能验证测试启动后端服务后使用 Postman 或直接通过前端界面进行测试。1. 测试接口连通性GET http://localhost:8080/api/beds/stats应返回 JSON 格式的统计数据。GET http://localhost:8080/api/beds?deptId1应返回指定科室的床位列表。2. 测试床位调配流程通过前端界面或调用POST /api/bed/transfer接口尝试将一个空闲床位从科室A调配到科室B。验证床位列表和科室统计信息是否实时更新。检查bed_transfer_log表是否生成了正确的日志记录。3. 测试患者入院与智能分床模拟一个患者入院请求调用患者入院接口并指定目标科室。系统应能自动从目标科室或全院资源池中分配一个空闲床位。验证hospitalization表和bed表的状态更新是否正确。4. 验证数据一致性在进行一系列操作入院、转科、出院后确保bed表的bed_status和current_dept_id与hospitalization表中的记录始终保持逻辑一致。8. 常见问题与排查方法在开发和部署过程中你可能会遇到以下问题。问题现象可能原因排查方式解决方案服务启动失败端口被占用8080 端口已被其他程序使用使用netstat -ano | findstr :8080(Win) 或lsof -i:8080(Linux/Mac) 查看杀死占用进程或在application.yml中修改server.port启动时报数据库连接错误数据库地址、用户名、密码错误数据库未启动驱动未加载检查application.yml配置确认 MySQL 服务已启动检查pom.xml中驱动依赖修正配置启动数据库添加mysql-connector-java依赖调用 API 返回 404请求路径错误RequestMapping注解路径不匹配未添加RestController检查浏览器或 Postman 的完整 URL检查 Controller 类的映射路径确保请求路径与server.servlet.context-path及 Controller 路径拼接正确前端调用 API 跨域错误后端未配置 CORS (跨域资源共享)浏览器控制台查看错误信息在后端添加 CORS 配置类或使用CrossOrigin注解床位调配后列表未刷新前端未重新请求数据后端事务未提交检查前端调用成功后是否重新调用查询接口检查后端方法是否添加了Transactional在前端操作成功后调用数据刷新方法确保服务层方法有事务注解查询性能慢页面卡顿数据量大未分页复杂查询未加索引未使用缓存检查 SQL 执行计划观察后端日志为常用查询字段添加数据库索引对统计类接口使用 Redis 缓存列表查询实现分页打包成 Jar 后运行找不到模板文件前端资源未正确打包到 Jar 中或路径问题检查static和templates目录位置如果前后端分离则无需打包前端资源对于前后端分离项目确保前端独立部署后端仅提供 API9. 最佳实践与扩展建议最佳实践分页查询所有列表接口如床位列表、患者列表务必实现分页避免一次性加载过多数据。接口幂等性对于床位调配、患者入院等关键操作考虑设计幂等接口防止重复提交。操作日志除了bed_transfer_log关键业务操作如床位状态修改、患者出院都应记录详细的操作日志便于审计。数据权限根据用户角色如科室管理员、全院管理员控制其对床位数据的增删改查权限。定时任务可以引入定时任务如使用 SpringScheduled定期同步 HIS 系统中的患者基础信息或清理过期缓存。扩展建议智能推荐算法在findAvailableBeds方法中可以集成更复杂的推荐逻辑例如考虑科室间的距离同楼层优先、床位类型匹配度、患者性别等。消息通知当床位被调配、患者被成功分床时可以通过集成消息中间件如 RabbitMQ或短信平台通知相关科室护士站。工作流引擎对于复杂的转科审批流程可以集成工作流引擎如 Flowable 或 Activiti实现电子化审批流。数据大屏为医院领导层开发一个数据可视化大屏实时展示全院床位使用热力图、周转率趋势等核心指标。移动端支持开发微信小程序或 H5 页面让科室医生或护士能随时随地查看床位状态、提交调配申请。“全院一张床”系统是一个典型的 Spring Boot 全栈项目它涵盖了从数据库设计、后端业务逻辑开发到前端界面展示的完整流程。通过实现它你不仅能掌握 Spring Boot 的核心技术更能理解如何用技术解决真实的业务痛点。建议在理解本文所述核心逻辑的基础上动手编码实现并尝试引入缓存、消息队列等中间件来优化系统这将是一次非常有价值的项目实战经验。