编辑 | blame | 历史 | 原始文档

福祉车与急救转运数据结构分离实现说明

📋 概述

已成功将福祉车和急救转运任务的扩展信息分离到独立的数据库表中,实现数据结构的清晰隔离。


✅ 已完成的工作

1. 数据库层面分离

1.1 急救转运扩展表 (sys_task_emergency)

用途: 存储急救转运任务的专属信息

核心字段:
sql - 患者信息: patient_name, patient_phone, patient_gender, patient_condition等 - 转出医院: hospital_out_name, hospital_out_address, GPS坐标等 - 转入医院: hospital_in_name, hospital_in_address, GPS坐标等 - 费用信息: transfer_distance, transfer_price

SQL文件: sql/sys_task_emergency.sql

1.2 福祉车扩展表 (sys_task_welfare) ⭐ 新增

用途: 存储福祉车任务的专属信息

核心字段:
sql - 乘客信息: passenger_name, passenger_phone, passenger_age, passenger_gender等 - 特殊需求: special_needs - 服务信息: service_type (轮椅接送、担架转运等) - 接送地址: pickup_address, pickup_longitude, pickup_latitude - 目的地址: destination_address, destination_longitude, destination_latitude - 费用信息: service_distance, service_price

SQL文件: sql/sys_task_welfare.sql ⭐ 新建

表结构对比:
| 字段类别 | 急救转运表 | 福祉车表 |
|---------|-----------|---------|
| 核心信息 | 患者 | 乘客 |
| 地址类型 | 医院 | 普通地址 |
| 特色字段 | 病情、医院科室床号 | 特殊需求、服务类型 |
| 关联方式 | task_id (外键) | task_id (外键) |


2. 实体类层面分离

2.1 急救转运实体 (SysTaskEmergency.java)

位置: ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTaskEmergency.java

核心属性:
java - PatientInfo: 患者信息(姓名、电话、性别、身份证、病情) - HospitalInfo Out: 转出医院信息 - HospitalInfo In: 转入医院信息 - 费用: transferDistance, transferPrice

2.2 福祉车实体 (SysTaskWelfare.java) ⭐ 新增

位置: ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTaskWelfare.java

核心属性:
java - 乘客信息: passengerContact, passengerPhone, passengerName, passengerAge, passengerGender - 特殊需求: specialNeeds - 服务类型: serviceType - 接送地址: pickupAddress, pickupLongitude, pickupLatitude - 目的地址: destinationAddress, destinationLongitude, destinationLatitude - 费用: serviceDistance, servicePrice


3. Mapper层面分离

3.1 急救转运Mapper

  • 接口: SysTaskEmergencyMapper.java
  • XML: SysTaskEmergencyMapper.xml

3.2 福祉车Mapper ⭐ 新增

  • 接口: SysTaskWelfareMapper.java
  • XML: SysTaskWelfareMapper.xml

方法对比:
java // 都提供相同的CRUD方法 - selectByTaskId(Long taskId) - insert(entity) - update(entity) - deleteByTaskId(Long taskId)


4. Service层面分离

4.1 任务创建逻辑分离

急救转运:
java if ("EMERGENCY_TRANSFER".equals(createVO.getTaskType())) { saveEmergencyInfo(task.getTaskId(), createVO); }

福祉车:
java if ("WELFARE".equals(createVO.getTaskType())) { saveWelfareInfo(task.getTaskId(), createVO); }

4.2 扩展信息保存方法

急救转运 - saveEmergencyInfo():
java private void saveEmergencyInfo(Long taskId, TaskCreateVO createVO) { SysTaskEmergency emergencyInfo = new SysTaskEmergency(); // 设置患者信息 // 设置转出医院信息 // 设置转入医院信息 // 设置费用信息 sysTaskEmergencyMapper.insertSysTaskEmergency(emergencyInfo); }

福祉车 - saveWelfareInfo() ⭐ 重构:
java private void saveWelfareInfo(Long taskId, TaskCreateVO createVO) { SysTaskWelfare welfareInfo = new SysTaskWelfare(); // 设置乘客信息 // 设置地址信息 // 设置GPS坐标 // 设置距离和费用 sysTaskWelfareMapper.insertSysTaskWelfare(welfareInfo); }

4.3 查询逻辑分离

selectSysTaskByTaskId() 方法:
java if ("EMERGENCY_TRANSFER".equals(task.getTaskType())) { SysTaskEmergency emergencyInfo = sysTaskEmergencyMapper.selectSysTaskEmergencyByTaskId(taskId); task.setEmergencyInfo(emergencyInfo); } else if ("WELFARE".equals(task.getTaskType())) { SysTaskWelfare welfareInfo = sysTaskWelfareMapper.selectSysTaskWelfareByTaskId(taskId); task.setWelfareInfo(welfareInfo); }

getTaskDetail() 方法同样进行了分离处理


5. SysTask实体类扩展

新增两个独立的扩展信息字段:

public class SysTask extends BaseEntity {
    // ... 基础字段 ...
    
    /** 急救转运扩展信息 */
    private SysTaskEmergency emergencyInfo;
    
    /** 福祉车扩展信息 */
    private SysTaskWelfare welfareInfo;  // ⭐ 新增
    
    // ... getter/setter ...
}

🔄 数据流程对比

急救转运任务流程

创建急救转运任务
    ↓
taskType = 'EMERGENCY_TRANSFER'
    ↓
保存 sys_task 主表
    ↓
调用 saveEmergencyInfo()
    ↓
保存到 sys_task_emergency 表
    ↓
查询时加载 emergencyInfo
    ↓
返回完整急救转运任务

福祉车任务流程

创建福祉车任务
    ↓
taskType = 'WELFARE'
    ↓
保存 sys_task 主表
    ↓
调用 saveWelfareInfo()
    ↓
保存到 sys_task_welfare 表  ⭐ 独立表
    ↓
查询时加载 welfareInfo  ⭐ 独立字段
    ↓
返回完整福祉车任务

📊 数据存储对比

急救转运任务数据

主表 (sys_task):
sql task_id = 1 task_type = 'EMERGENCY_TRANSFER' task_status = 'PENDING' departure_address = NULL (不使用,用扩展表的医院地址) destination_address = NULL

扩展表 (sys_task_emergency):
sql task_id = 1 patient_name = '李四' patient_phone = '13800138000' hospital_out_name = '广州市第一人民医院' hospital_in_name = '广东省人民医院' transfer_distance = 5.2 transfer_price = 800

福祉车任务数据

主表 (sys_task):
sql task_id = 2 task_type = 'WELFARE' task_status = 'PENDING' departure_address = '广州市天河区...' (可选,主要用扩展表) destination_address = '广州市越秀区...'

扩展表 (sys_task_welfare) ⭐:
sql task_id = 2 passenger_name = NULL (可选) passenger_contact = '张三' passenger_phone = '13800138000' pickup_address = '广州市天河区XX路123号' destination_address = '广州市越秀区YY路456号' service_distance = 5.2 service_price = 300


🎯 分离的优势

1. 数据结构清晰

  • ✅ 急救转运和福祉车各有专属表
  • ✅ 字段语义明确,不会混淆
  • ✅ 易于理解和维护

2. 性能优化

  • ✅ 查询时只加载对应类型的扩展信息
  • ✅ 减少无效数据传输
  • ✅ 索引更精确

3. 扩展性好

  • ✅ 新增任务类型时,可创建独立扩展表
  • ✅ 不影响现有表结构
  • ✅ 符合开闭原则

4. 业务隔离

  • ✅ 急救转运和福祉车业务逻辑完全分离
  • ✅ 修改一种类型不影响另一种
  • ✅ 降低耦合度

📁 新增文件清单

数据库脚本

  • sql/sys_task_welfare.sql - 福祉车扩展表结构

Java实体类

  • ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTaskWelfare.java

Mapper接口和XML

  • ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysTaskWelfareMapper.java
  • ruoyi-system/src/main/resources/mapper/system/SysTaskWelfareMapper.xml

修改文件清单

  • SysTask.java - 添加 welfareInfo 字段
  • SysTaskServiceImpl.java - 分离保存和查询逻辑

🚀 部署步骤

1. 执行数据库脚本

# 创建福祉车扩展表
mysql -u root -p your_database < sql/sys_task_welfare.sql

2. 重新编译后端

cd d:\project\急救转运\code\Api\RuoYi-Vue-master
mvn clean package -DskipTests

3. 重启服务

bin\run.bat

4. 验证数据

-- 验证急救转运任务
SELECT 
    t.task_id,
    t.task_type,
    e.patient_name,
    e.hospital_out_name
FROM sys_task t
LEFT JOIN sys_task_emergency e ON t.task_id = e.task_id
WHERE t.task_type = 'EMERGENCY_TRANSFER';

-- 验证福祉车任务
SELECT 
    t.task_id,
    t.task_type,
    w.passenger_contact,
    w.pickup_address,
    w.destination_address
FROM sys_task t
LEFT JOIN sys_task_welfare w ON t.task_id = w.task_id
WHERE t.task_type = 'WELFARE';

✅ 测试建议

1. 急救转运任务测试

  • [ ] 创建急救转运任务,填写患者和医院信息
  • [ ] 验证数据保存到 sys_task_emergency
  • [ ] 查询任务详情,确认 emergencyInfo 字段有数据
  • [ ] 确认 welfareInfo 字段为 null

2. 福祉车任务测试

  • [ ] 创建福祉车任务,填写乘客和地址信息
  • [ ] 验证数据保存到 sys_task_welfare 表 (不是emergency表)
  • [ ] 查询任务详情,确认 welfareInfo 字段有数据
  • [ ] 确认 emergencyInfo 字段为 null

3. 数据隔离验证

-- 急救转运任务不应该在福祉车表中有数据
SELECT COUNT(*) FROM sys_task_welfare 
WHERE task_id IN (
    SELECT task_id FROM sys_task WHERE task_type = 'EMERGENCY_TRANSFER'
);
-- 预期结果: 0

-- 福祉车任务不应该在急救转运表中有数据
SELECT COUNT(*) FROM sys_task_emergency 
WHERE task_id IN (
    SELECT task_id FROM sys_task WHERE task_type = 'WELFARE'
);
-- 预期结果: 0

📝 前端无需修改

前端代码完全兼容,无需任何修改!

原因:
1. 前端提交的数据格式不变
2. 后端自动根据 taskType 选择正确的扩展表
3. 返回的JSON结构保持兼容


🎉 总结

分离前

sys_task_emergency 表
├── 急救转运数据 (患者、医院)
└── 福祉车数据 (乘客) ❌ 混在一起

分离后

sys_task_emergency 表
└── 急救转运数据 (患者、医院) ✅ 专用

sys_task_welfare 表
└── 福祉车数据 (乘客、地址) ✅ 专用

优点总结:
- ✅ 数据结构清晰,业务逻辑分离
- ✅ 性能更优,按需加载
- ✅ 易于扩展和维护
- ✅ 符合单一职责原则


实施完成时间: 2025-10-16
实施状态: ✅ 已完成
测试状态: ⏳ 待测试