# 急救转运任务医院ID字段添加说明
## 📋 需求背景
急救转运任务中的医院信息来自 SQL Server 的 `hosp_data` 表,前端通过搜索选择医院。为了便于数据关联查询和分析,需要在 `sys_task_emergency` 表中不仅保存医院名称,还需要保存医院ID。
## 🎯 实现目标
- ✅ 在 `sys_task_emergency` 表中添加 `hospital_out_id` 和 `hospital_in_id` 字段
- ✅ 前端选择医院时同时保存医院ID和医院名称
- ✅ 后端接收并保存医院ID
- ✅ 支持通过医院ID进行关联查询
## 📊 数据库变更
### SQL 脚本
文件路径:`sql/add_hospital_id_fields.sql`
```sql
-- 1. 添加转出医院ID字段
ALTER TABLE sys_task_emergency
ADD COLUMN hospital_out_id BIGINT COMMENT '转出医院ID(关联hosp_data表的HospID)' AFTER hospital_out_name;
-- 2. 添加转入医院ID字段
ALTER TABLE sys_task_emergency
ADD COLUMN hospital_in_id BIGINT COMMENT '转入医院ID(关联hosp_data表的HospID)' AFTER hospital_in_name;
-- 3. 创建索引以提升查询性能
CREATE INDEX idx_hospital_out_id ON sys_task_emergency(hospital_out_id);
CREATE INDEX idx_hospital_in_id ON sys_task_emergency(hospital_in_id);
```
### 字段说明
| 字段名 | 类型 | 说明 | 允许NULL |
|--------|------|------|---------|
| hospital_out_id | BIGINT | 转出医院ID,关联 hosp_data.HospID | 是 |
| hospital_in_id | BIGINT | 转入医院ID,关联 hosp_data.HospID | 是 |
**为什么允许 NULL?**
- 历史数据可能只有医院名称没有ID
- 用户可能手动输入医院名称而不是从列表选择
- 保持数据兼容性
## 🔧 代码变更
### 1. 实体类更新
**文件**:`ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTaskEmergency.java`
```java
/** 转出医院ID(关联hosp_data表的HospID) */
private Long hospitalOutId;
/** 转入医院ID(关联hosp_data表的HospID) */
private Long hospitalInId;
// 添加对应的 getter 和 setter 方法
```
### 2. Mapper XML 更新
**文件**:`ruoyi-system/src/main/resources/mapper/system/SysTaskEmergencyMapper.xml`
**ResultMap 添加映射**:
```xml
```
**SQL 查询添加字段**:
```xml
hospital_out_id, hospital_in_id
```
**Insert 和 Update 添加字段处理**:
```xml
hospital_out_id,
hospital_in_id,
```
### 3. VO 类更新
**文件**:`ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TaskCreateVO.java`
**HospitalInfo 内部类添加字段**:
```java
public static class HospitalInfo {
private Long id; // 医院ID(关联hosp_data表的HospID)
private String name;
private String department;
// ... 其他字段
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
```
### 4. Service 层更新
**文件**:`ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java`
**saveEmergencyInfo 方法**:
```java
// 设置转出医院信息
if (createVO.getHospitalOut() != null) {
emergencyInfo.setHospitalOutId(createVO.getHospitalOut().getId());
emergencyInfo.setHospitalOutName(createVO.getHospitalOut().getName());
// ... 其他字段
}
// 设置转入医院信息
if (createVO.getHospitalIn() != null) {
emergencyInfo.setHospitalInId(createVO.getHospitalIn().getId());
emergencyInfo.setHospitalInName(createVO.getHospitalIn().getName());
// ... 其他字段
}
```
### 5. 前端更新
**文件**:`app/pages/task/create-emergency.vue`
**taskForm 初始化**:
```javascript
hospitalOut: {
id: null, // 医院ID
name: '',
department: '',
bedNumber: '',
address: ''
},
hospitalIn: {
id: null, // 医院ID
name: '',
department: '',
bedNumber: '',
address: ''
},
```
**医院选择方法**:
```javascript
// 选择转出医院
selectHospitalOut(hospital) {
this.taskForm.hospitalOut.id = hospital.hospId // 保存医院ID
this.taskForm.hospitalOut.name = hospital.hospName
this.taskForm.hospitalOut.address = hospital.hospAddress
// ... 其他逻辑
}
// 选择转入医院
selectHospitalIn(hospital) {
this.taskForm.hospitalIn.id = hospital.hospId // 保存医院ID
this.taskForm.hospitalIn.name = hospital.hospName
this.taskForm.hospitalIn.address = hospital.hospAddress
// ... 其他逻辑
}
```
## 📝 部署步骤
### 1. 数据库升级
```bash
# 方式1:命令行执行
mysql -u root -p ruoyi < sql/add_hospital_id_fields.sql
# 方式2:数据库客户端
source d:/project/急救转运/code/Api/RuoYi-Vue-master/sql/add_hospital_id_fields.sql
```
### 2. 后端代码部署
1. 确保所有 Java 文件已更新
2. 重新编译项目
3. 重启应用服务
### 3. 前端代码部署
1. 确保 Vue 文件已更新
2. 重新编译前端项目:
```bash
# H5版本
npm run build:h5
# 微信小程序版本
npm run build:mp-weixin
```
3. 部署到服务器
## ✅ 验证测试
### 测试步骤
1. **创建新任务**
- 在前端创建一个急救转运任务
- 从医院列表中选择转出医院和转入医院
- 提交任务
2. **验证数据库**
```sql
SELECT
task_id,
hospital_out_id,
hospital_out_name,
hospital_in_id,
hospital_in_name
FROM sys_task_emergency
ORDER BY id DESC
LIMIT 10;
```
3. **预期结果**
- `hospital_out_id` 和 `hospital_in_id` 应该有值
- 值应该对应 `hosp_data` 表中的 `HospID`
### 关联查询测试
```sql
-- 查询任务及其关联的医院详细信息
SELECT
e.task_id,
e.hospital_out_id,
ho.HospName AS hospital_out_name,
ho.HospAddress AS hospital_out_address,
e.hospital_in_id,
hi.HospName AS hospital_in_name,
hi.HospAddress AS hospital_in_address
FROM sys_task_emergency e
LEFT JOIN hosp_data ho ON e.hospital_out_id = ho.HospID
LEFT JOIN hosp_data hi ON e.hospital_in_id = hi.HospID
WHERE e.task_id = <任务ID>;
```
## 🔍 数据分析应用
有了医院ID后,可以进行更深入的数据分析:
### 1. 统计各医院的转运量
```sql
-- 转出医院转运量统计
SELECT
e.hospital_out_id,
h.HospName,
COUNT(*) AS transfer_count
FROM sys_task_emergency e
LEFT JOIN hosp_data h ON e.hospital_out_id = h.HospID
WHERE e.hospital_out_id IS NOT NULL
GROUP BY e.hospital_out_id, h.HospName
ORDER BY transfer_count DESC
LIMIT 20;
-- 转入医院转运量统计
SELECT
e.hospital_in_id,
h.HospName,
COUNT(*) AS transfer_count
FROM sys_task_emergency e
LEFT JOIN hosp_data h ON e.hospital_in_id = h.HospID
WHERE e.hospital_in_id IS NOT NULL
GROUP BY e.hospital_in_id, h.HospName
ORDER BY transfer_count DESC
LIMIT 20;
```
### 2. 医院间转运路线分析
```sql
-- 最常见的转运路线
SELECT
e.hospital_out_id,
ho.HospName AS from_hospital,
e.hospital_in_id,
hi.HospName AS to_hospital,
COUNT(*) AS route_count,
AVG(e.transfer_distance) AS avg_distance,
AVG(e.transfer_price) AS avg_price
FROM sys_task_emergency e
LEFT JOIN hosp_data ho ON e.hospital_out_id = ho.HospID
LEFT JOIN hosp_data hi ON e.hospital_in_id = hi.HospID
WHERE e.hospital_out_id IS NOT NULL
AND e.hospital_in_id IS NOT NULL
GROUP BY e.hospital_out_id, ho.HospName, e.hospital_in_id, hi.HospName
HAVING route_count > 5
ORDER BY route_count DESC
LIMIT 50;
```
### 3. 医院区域分布分析
```sql
-- 按医院区域统计转运量
SELECT
h.HospCity AS city,
h.HospCounty AS district,
COUNT(*) AS total_count,
SUM(CASE WHEN e.hospital_out_id = h.HospID THEN 1 ELSE 0 END) AS out_count,
SUM(CASE WHEN e.hospital_in_id = h.HospID THEN 1 ELSE 0 END) AS in_count
FROM hosp_data h
LEFT JOIN sys_task_emergency e ON h.HospID IN (e.hospital_out_id, e.hospital_in_id)
GROUP BY h.HospCity, h.HospCounty
ORDER BY total_count DESC;
```
## 📌 注意事项
### 1. 数据兼容性
- 历史数据的医院ID字段为NULL是正常的
- 不影响历史数据的展示和使用
- 新创建的任务应该都包含医院ID
### 2. 数据一致性
- 医院名称仍然保留,用于显示和同步旧系统
- 医院ID用于关联查询和数据分析
- 如果从医院列表选择,ID和名称应该一致
- 如果手动输入,只有名称没有ID
### 3. 性能优化
- 已为医院ID字段创建索引
- 关联查询时优先使用医院ID
- 定期检查索引有效性
### 4. 旧系统同步
- 旧系统仍然使用医院名称字段
- 医院ID字段不需要同步到旧系统
- 保持现有同步逻辑不变
## 🎉 总结
本次更新为 `sys_task_emergency` 表添加了医院ID字段,实现了:
1. ✅ **数据关联**:可以通过医院ID关联查询医院详细信息
2. ✅ **数据分析**:支持按医院、路线等维度进行统计分析
3. ✅ **向后兼容**:不影响历史数据,保持系统稳定性
4. ✅ **前后端联动**:前端选择医院时自动保存ID,后端正确存储
所有代码变更已完成,执行数据库脚本后即可使用新功能!🚀