医院应急演练救护车租赁调度系统设计与实现

发布时间:2026/10/8 14:39:00
医院应急演练救护车租赁调度系统设计与实现 医院应急演练看似是行政管理问题一旦落到执行层就是典型的“多角色、强时效、高并发、可追溯”的调度系统问题。以“石家庄医院应急演练120救护车辆租赁预约联系电话”这个搜索场景为例很多人想找的只是一部值班电话但真正能解决问题的是一个能管理车辆、预约订单、任务状态和联系方式的信息化平台。电话只是入口系统才是枢纽。本文从业务痛点、流程建模、数据库设计、接口实现和工程化落地五个层面拆解这类系统怎么做供医院信息科、软件项目经理和应急管理平台研发人员参考。1. 场景痛点与需求分析先看一个常见画面医院要组织一场应急演练模拟批量伤员转运。120急救指挥中心接到模拟任务需要安排车辆。本院救护车不够要从社会租赁公司调用车辆。操作人员拿着一张联系表挨个打电话问有没有车。好不容易确认有车再手动记录车牌、驾驶员、联系电话、出发时间。流程能跑通但存在几个明显问题。1.1 人工调度导致状态不透明打电话只能确认“有没有车”无法实时知道车辆当前位置、是否在维修、上一单是否已结算。租赁公司的车辆通常分散在城市不同区域靠记忆和经验派车往往出现车辆重复安排或距离过远的问题。1.2 应急场景下信息流转慢应急演练对时间有严格要求从接到任务到车辆出库通常只有几十分钟。如果电话占线、联系人外出整个流程就被卡住。纸质台账和微信群里零散消息无法形成统一信息视图决策人员看不到整体运力情况。1.3 费用结算和审计困难租赁车辆涉及费用应急演练结束后需要按车辆、时长、里程结算。纯手工记录容易漏记、错记后续审计缺少有效依据。更重要的是医院内部和租赁公司之间的账单对不齐往往要花大量时间核对。1.4 演练复盘缺少数据支撑应急演练结束后复盘会总要回答几个问题车辆响应用了多久车辆到位是否准时有没有出现调度冲突没有结构化数据这些问题只能靠主观回忆。把这个场景数字化并不是简单做一个“通讯录管理软件”而是要建立一套从预约申请、车辆分配、出车执行、任务完成到费用结算的闭环流程。这里的核心不是“联系电话”而是电话背后的资源调度和状态管理。2. 核心概念与业务流程在进入技术实现之前需要先统一几个概念。这样后续设计表结构和接口时大家理解的是同一套语言。2.1 关键术语应急演练医院组织的模拟突发事件医疗救援演练包括伤员转运、批量救治等场景。120救护车辆具备急救医疗设备的专用车辆这里主要指医院自有和租赁两种来源。车辆租赁预约指在自有运力不足时向第三方租赁公司申请调用救护车的业务动作。联系电话包括医院调度中心、租赁公司值班人员、驾驶员、医护随车人员的联系方式。调度任务一次从“呼叫”到“完成”的完整车辆使用过程可能有多个节点和状态。2.2 业务角色划分一个完整的应急演练车辆调度系统至少包含四类角色。角色核心操作关心的数据调度员创建演练任务、审核预约、分配车辆车辆空闲状态、租赁公司响应速度、任务进度驾驶员接收任务、上报位置、确认到达任务信息、导航路径、联系人方式租赁公司管理员维护车辆信息、确认订单、反馈可用资源车辆台账、订单状态、结算金额医院管理员查看全域运力、统计报表、审计记录车辆利用率、响应时长、费用汇总2.3 车辆状态与任务状态机建议把车辆和任务分别建模。车辆有全局状态任务有独立生命周期二者通过调度关系绑定。车辆状态建议设计为空闲、已预约、已出车、维修中、已停用。任务状态建议设计为待审批、已分配、待出车、执行中、已完成、已取消。状态流转要注意限制条件。例如只有车辆处于空闲状态才能被分配新任务任务执行中的车辆不能被其他预约单占用。这种约束如果只靠人工判断很容易出错在系统里要用唯一索引、状态校验和事务机制来保证。从业务角度理解这个系统本质上是“应急版打车调度平台”。普通打车平台处理的是乘客到司机的匹配这里处理的是演练任务到救护车辆的匹配。区别在于任务优先级更高、车辆类型更特殊、参与角色更多、结算规则更复杂。3. 总体架构与技术选型应急演练车辆调度系统不需要过度复杂但必须考虑峰值流量、任务可靠性和数据可追溯性。演练当天可能同时有几十个任务并发创建通知消息要在分钟级送达调度操作要防止并发冲突。3.1 架构分层推荐采用经典的四层架构。层级职责核心技术接入层小程序端、管理后台、开放接口小程序框架、Vue 或 React业务层预约、调度、通知、结算、报表Spring Boot、Redis、消息队列数据层业务数据、日志数据、配置数据MySQL、Redis、MinIO基础设施部署、监控、告警Docker、Nginx、Prometheus3.2 后端技术选型后端可以选用 Spring Boot 作为主框架原因有二一是生态成熟容易找到调度、权限、数据访问的配套组件二是适合传统医院信息科和外包团队的技术栈。数据存储以 MySQL 为主库保存订单、车辆、用户等核心业务数据Redis 用于缓存车辆状态和热点数据减少数据库压力消息队列用于异步发送短信和站内信通知避免调度操作长时间阻塞。前端管理后台建议用 Vue 3 加 Element Plus操作界面需要支持地图、任务列表和状态卡片。移动端建议用微信小程序因为院内工作人员和租赁公司驾驶员普遍使用微信不需要另外安装 App。3.3 为什么不用纯电话加Excel如果只做一张联系电话表可以放在 Excel 里也可以做成一个简单网页。但无法解决状态不透明、并发冲突和追溯审计的问题。纯电话模式等于把系统状态放在每一个人的大脑里信息同步靠口口相传天然存在延迟和失真。用系统管理车辆状态、用消息通知代替电话呼叫属于“低成本、高确定性”的改进。4. 环境准备与数据模型设计下面进入实操环节。这里以 Spring Boot 3 MyBatis-Plus MySQL 8 为例版本以当前稳定版本为准核心思路不依赖具体版本。4.1 开发环境清单环境项推荐选型说明JDKJDK 17 或 21与 Spring Boot 3 匹配构建工具Maven 3.9管理依赖数据库MySQL 8.x存储业务数据缓存Redis 6.x/7.x存储车辆状态、登录态消息队列RabbitMQ异步通知前端Vue 3 Element Plus管理后台移动端微信小程序驾驶员端、调度端4.2 数据库设计要点最核心的表是车辆表、租赁公司表、演练任务表、预约调度单表和调度记录表。下面给出关键建表语句。车辆信息表CREATE TABLE vehicle_info ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 主键ID, plate_no VARCHAR(20) NOT NULL COMMENT 车牌号, vehicle_type VARCHAR(50) COMMENT 车型如救护车、负压救护车, owner_type VARCHAR(20) NOT NULL COMMENT 所属类型SELF自营RENTAL租赁, company_id BIGINT COMMENT 租赁公司ID, status VARCHAR(20) NOT NULL DEFAULT IDLE COMMENT IDLE空闲BOOKED已预约OUT出车MAINTENANCE维修, current_lng DECIMAL(10, 6) COMMENT 当前经度, current_lat DECIMAL(10, 6) COMMENT 当前纬度, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uk_plate_no (plate_no) ) COMMENT 救护车辆信息表;预约调度单表CREATE TABLE rental_order ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 主键ID, order_no VARCHAR(32) NOT NULL COMMENT 业务单号, drill_no VARCHAR(32) COMMENT 关联应急演练编号, vehicle_id BIGINT COMMENT 车辆ID, rental_company_id BIGINT COMMENT 租赁公司ID, driver_name VARCHAR(50) COMMENT 驾驶员姓名, driver_phone VARCHAR(20) COMMENT 驾驶员联系电话, start_time DATETIME COMMENT 预计用车开始时间, end_time DATETIME COMMENT 预计用车结束时间, status VARCHAR(20) NOT NULL DEFAULT PENDING_APPROVAL COMMENT 状态, remark VARCHAR(500) COMMENT 备注, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uk_order_no (order_no) ) COMMENT 车辆租赁预约调度单;建议再设计一张联系电话表把医院调度中心、租赁公司值班人、驾驶员、医护随车人员的联系方式统一管理。这里的原则是联系人独立成表对外只暴露角色名称和经脱敏后的号码不直接展示原始号码。CREATE TABLE contact_info ( id BIGINT PRIMARY KEY AUTO_INCREMENT, contact_name VARCHAR(50) COMMENT 联系人姓名, role_type VARCHAR(30) COMMENT 角色DISPATCHER调度员DRIVER驾驶员COMPANY_ADMIN租赁公司管理员, phone_encrypted VARCHAR(128) COMMENT 加密联系电话, phone_plain VARCHAR(20) COMMENT 脱敏后展示号码如138****1234, org_id BIGINT COMMENT 所属机构ID, status TINYINT NOT NULL DEFAULT 1 COMMENT 1启用0停用, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ) COMMENT 联系电话管理表;4.3 关键索引与约束订单表按status和order_no建索引车辆表对company_id和status建联合索引。预约分配车辆时必须加事务和锁防止同一辆车被并发分配到两个任务。5. 核心功能代码实现代码实现部分选取三个关键场景创建预约单、分配车辆、前端提交预约请求。5.1 创建预约单的 Service 逻辑// 文件路径src/main/java/com/hospital/emergency/service/RentalOrderService.java Component public class RentalOrderService { Resource private RentalOrderMapper rentalOrderMapper; Resource private VehicleInfoMapper vehicleInfoMapper; Transactional(rollbackFor Exception.class) public Long createRentalOrder(RentalOrderCreateRequest request) { // 1. 生成业务单号 String orderNo YD System.currentTimeMillis(); // 2. 校验车辆状态防止超卖 VehicleInfo vehicle vehicleInfoMapper.selectById(request.getVehicleId()); if (vehicle null) { throw new BizException(车辆不存在); } if (!VehicleStatus.IDLE.name().equals(vehicle.getStatus())) { throw new BizException(车辆当前状态不可预约请刷新车辆列表); } // 3. 创建预约单 RentalOrderEntity order new RentalOrderEntity(); order.setOrderNo(orderNo); order.setDrillNo(request.getDrillNo()); order.setVehicleId(request.getVehicleId()); order.setRentalCompanyId(request.getRentalCompanyId()); order.setDriverName(request.getDriverName()); order.setDriverPhone(request.getDriverPhone()); order.setStartTime(request.getStartTime()); order.setEndTime(request.getEndTime()); order.setStatus(RentalOrderStatus.PENDING_APPROVAL.name()); rentalOrderMapper.insert(order); // 4. 锁住车辆避免后续重复分配 VehicleInfo update new VehicleInfo(); update.setId(vehicle.getId()); update.setStatus(VehicleStatus.BOOKED.name()); vehicleInfoMapper.updateById(update); return order.getId(); } }这里的关键点是事务和状态校验。如果第二步不加校验两个调度员同时看到“空闲”车辆可能同一个车辆被两次预约。数据库层面可以给vehicle_info.status加乐观锁或使用UPDATE ... WHERE status IDLE来保证并发安全。5.2 分配车辆的状态更新SQL为保证并发正确实际项目中建议用条件更新代替先查后改UPDATE vehicle_info SET status BOOKED, current_lng #{lng}, current_lat #{lat} WHERE id #{vehicleId} AND status IDLE;如果update返回的受影响行数为 0说明车辆已被其他任务占用需要重新选择车辆。这种写法比“先 select 再 update”更可靠能直接把并发冲突在数据库层解决。5.3 小程序端创建预约请求以微信小程序为例调度员在小程序里填写表单后调用后端接口。前端代码可以这样写// 文件路径miniprogram/pages/order/createOrder.js const createOrder (formData) { wx.request({ url: https://api.example.com/api/rental-order/create, method: POST, header: { Content-Type: application/json, Authorization: Bearer ${wx.getStorageSync(token)} }, data: { drillNo: formData.drillNo, vehicleId: formData.vehicleId, rentalCompanyId: formData.rentalCompanyId, driverName: formData.driverName, driverPhone: formData.driverPhone, startTime: formData.startTime, endTime: formData.endTime }, success(res) { if (res.data.code 0) { wx.showToast({ title: 预约成功, icon: success }); } else { wx.showModal({ title: 提示, content: res.data.message }); } } }); };5.4 配置文件的建议写法# 文件路径src/main/resources/application.yml spring: datasource: url: jdbc:mysql://localhost:3306/emergency_dispatch?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: your_password redis: host: localhost port: 6379 rabbitmq: host: localhost port: 5672 username: guest password: guest mybatis-plus: mapper-locations: classpath:/mapper/**/*.xml configuration: map-underscore-to-camel-case: true这里的your_password需要替换为实际数据库密码生产环境建议通过环境变量或配置中心注入不要写死在仓库里。6. 联系电话与数据权限设计前面反复提到“联系电话”这里单独讲透。医院应急演练场景中的电话信息非常敏感暴露调度员手机号、驾驶员手机号可能带来骚扰甚至安全风险。系统设计上要重点做三件事。6.1 号码加密存储数据库不能明文保存手机号。可以用 AES 加密后存入phone_encrypted字段同时保存一个脱敏后的展示号码。调度员在界面上看到的是138****1234点击呼叫按钮才通过后台解密后调起语音呼叫。6.2 统一总机代替直连最稳妥的方式是不暴露个人电话而是设置一个统一调度总机号。系统内部记录个人联系方式推送给用户时只展示总机号和分机标识。电话呼入后由总机转接既保护隐私又方便录音质检。6.3 权限分级不同角色看到不同字段。租赁公司的驾驶员只能看到目标任务联系人不能看整个通讯录医院管理层只能看汇总统计不进入具体订单详情。Shiro 或 Spring Security 都可以实现关键是资源访问规则要提前定义好。// 文件路径src/main/java/com/hospital/emergency/config/SecurityConfig.java示例 Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(auth - auth .requestMatchers(/api/**).authenticated() .requestMatchers(/api/admin/**).hasRole(ADMIN) .anyRequest().permitAll()) .formLogin().disable(); return http.build(); }7. 运行验证与效果验证代码写完后需要用接口测试验证流程是否跑通。7.1 启动服务mvn clean package -DskipTests java -jar target/emergency-dispatch.jar7.2 创建预约单接口测试curl -X POST http://localhost:8080/api/rental-order/create \ -H Content-Type: application/json \ -H Authorization: Bearer token \ -d { drillNo: DRILL20250101, vehicleId: 1, rentalCompanyId: 1, driverName: 张师傅, driverPhone: 13800138000, startTime: 2025-01-01 09:00:00, endTime: 2025-01-01 12:00:00 }预期返回内容类似{ code: 0, data: { orderId: 101, orderNo: YD1735000000001 }, message: success }如果返回“车辆当前状态不可预约”说明车辆状态不是 IDLE需要先检查数据库中的vehicle_info.status。整个验证过程要分为三步第一看接口返回码第二看数据库订单记录第三看车辆状态是否从 IDLE 变成 BOOKED。7.3 演练中状态流转怎么看调度员在管理后台看订单状态从“待审批”到“已分配”车辆图标从灰色变蓝色地图上能看到车辆位置。如果状态没有变化优先查消息队列日志和数据库变更记录。8. 常见问题与排查方法问题现象可能原因排查方式解决方案创建预约失败提示车辆状态不可预约车辆被并发任务占用查看 vehicle_info 表状态和订单表改用条件更新 SQL冲突时提示重试短信通知没发送消息队列消费异常查看 RabbitMQ 队列积压情况和消费者日志增加重试机制和死信队列联系电话无法点击拨打号码加密字段未解密查看后端解密接口是否异常统一封装解密服务禁止前端直接传明文号码应急演练任务状态卡在待审批审批节点未触发查看状态机代码和数据库触发日志增加定时任务扫描超时订单自动告警地图位置长时间不更新驾驶员端未上报位置查看前端定位权限和后端接口耗时增加上报失败缓冲和降级策略排查问题的核心思路是“状态优先”。先确认车辆状态、订单状态、消息队列状态分别是什么再根据不一致的地方定位代码。应急系统里一份可靠的状态日志比任何猜测都有价值。9. 工程化与最佳实践这类系统一旦进入生产环境需要考虑的不只是功能还有稳定性和安全性。下面几条直接来自一线信息化建设的常见经验。9.1 使用状态机引擎管理订单流转不要用 if-else 管理所有状态切换。建议引入状态机引擎把状态流转规则集中配置。这样后续新增“取消”“驳回”等状态时只需调整配置不需要改业务代码。9.2 分布式ID与幂等订单号不要用数据库自增建议用雪花算法生成。对外接接口要设计幂等键防止网络重试导致重复下单。比如前端在创建订单时生成一个requestId后端根据requestId判断重复请求。9.3 数据备份与演练保障应急演练系统虽然服务于演练但生产事故发生时可能就是真实救援的支撑。每场演练前要做数据备份演练期间监控订单接口响应时间。生产环境部署至少两台服务节点避免单点故障。9.4 日志与审计所有调度操作必须记录操作人、操作时间、变更前后状态。审计表单独设计保证事后可以追溯“谁在什么时间修改了哪台车的状态”。这块在应急事件复盘时是核心依据。9.5 安全边界联系电话不能明文入库。管理后台必须做登录认证和操作审计。接口层面要增加限流防止演练通知接口被刷。生产环境数据库账号遵循最小权限原则应用账号只授权业务库需要的增删改查权限。9.6 从简单方案开始迭代如果医院信息化基础较弱第一版可以只做三张表车辆表、订单表、联系表。先让调度员在手机上能查车辆状态、创建预约单、看到联系电话。跑顺之后再引入地图定位、消息队列和费用结算。一个小而可靠的系统远比一个复杂但没人能用的平台有实际价值。10. 总结与实施建议这篇文章围绕“石家庄医院应急演练120救护车辆租赁预约联系电话”这个场景拆解了应急演练车辆调度系统的需求、流程、数据模型、核心代码和工程化要点。实际项目中不需要一步到位建设完整平台但有几个优先级建议值得关注第一先把联系电话和车辆资源建模。这是所有调度能力的基础没有干净的数据后续功能都不可靠。第二用状态机管住车辆和订单。一次调度的本质就是状态从“空闲”到“完成任务”的流转。第三在并发处理上一定要用条件更新或锁避免演练高峰期出现车辆重复分配。第四联系电话必须脱敏和加密保护调度员和驾驶员隐私。本文给出的代码是教学级的最小实现。生产环境还需要补充用户认证、权限管理、前端页面、消息通知、费用结算和报表统计。建议先做一个小规模到医院试点比如只在一个病区或一个租赁公司范围内跑通流程再逐步扩展到整个应急演练指挥体系。演练结束后的复盘数据才是这个系统真正价值所在。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询