# 任务车辆car_id和dept_id过滤功能说明
## 需求背景
在急救转运任务创建页面中,选择任务车辆时需要确保:
1. 只显示`car_id`不为空的车辆(已在旧系统中存在的车辆)
2. 只显示`dept_id`不为空的车辆(已分配给部门的车辆)
3. 避免用户选择到无效或未完成配置的车辆数据
## 数据说明
### tb_vehicle_info表字段
- **car_id**: 旧系统(SQL Server)中的车辆ID,用于关联旧系统数据
- **dept_id**: 车辆所属部门ID,关联sys_dept表
- **vehicle_no**: 车牌号
- **status**: 车辆状态(0-正常,1-停用)
### 过滤规则
只有同时满足以下条件的车辆才会在任务创建时显示:
- `car_id IS NOT NULL AND car_id != ''` - 车辆已在旧系统中存在
- `dept_id IS NOT NULL` - 车辆已分配给部门
- `status = '0'` - 车辆状态正常(由现有逻辑保证)
## 实现方案
### 后端SQL修改
**文件**: `ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml`
**修改位置**: `selectVehicleInfoList` 查询语句
**修改前**:
```xml
```
**修改后**:
```xml
```
**关键变化**:
- ✅ 添加 `and v.car_id is not null and v.car_id != ''` - 过滤car_id为空的记录
- ✅ 添加 `and v.dept_id is not null` - 过滤dept_id为空的记录
- ✅ 这些条件是强制性的,不受动态参数控制,始终生效
## 影响范围
### 直接影响
#### 1. 任务车辆选择
**页面**: `app/pages/task/create-emergency.vue`
**影响方法**: `getAvailableVehicles()`
```javascript
getAvailableVehicles() {
const deptId = this.currentUser.deptId
return listAvailableVehicles(deptId, 'EMERGENCY').then(response => {
const vehicleList = response.data || response.rows || []
// 返回的列表已自动过滤:只包含car_id和dept_id都不为空的车辆
this.vehicleOptions = vehicleList.map(vehicle => ({
id: vehicle.vehicleId,
name: vehicle.vehicleNo,
type: vehicle.vehicleType,
status: vehicle.status
}))
this.vehicles = this.vehicleOptions.map(v => v.name)
}).catch(() => {
this.vehicles = []
})
}
```
**效果**:
- 只显示有效的、已配置完整的车辆
- 用户无法选择到无效车辆
- 提升数据质量
#### 2. 车辆绑定
**页面**: `app/pages/bind-vehicle.vue`
**影响**:
- 用户绑定车辆时,只能看到有效车辆
- 避免绑定到无效车辆
#### 3. 后台车辆管理
**路径**: 系统管理 > 车辆管理
**影响**:
- 车辆列表查询会自动过滤无效记录
- 管理员需要确保新增车辆时填写car_id和dept_id
### 间接影响
#### 1. 车辆同步
**服务**: `VehicleSyncServiceImpl`
**注意事项**:
- 从SQL Server同步车辆时,必须确保car_id有值
- 建议在同步时同时设置dept_id
#### 2. 旧系统数据关联
**功能**: 调度单同步、服务单同步
**好处**:
- 确保新系统中的车辆都能在旧系统中找到对应记录
- 避免同步时出现关联失败
## 数据修复建议
### 1. 检查现有数据
执行以下SQL查询,检查是否有car_id或dept_id为空的车辆:
```sql
-- 检查car_id为空的车辆
SELECT vehicle_id, vehicle_no, car_id, dept_id, status
FROM tb_vehicle_info
WHERE car_id IS NULL OR car_id = '';
-- 检查dept_id为空的车辆
SELECT vehicle_id, vehicle_no, car_id, dept_id, status
FROM tb_vehicle_info
WHERE dept_id IS NULL;
-- 检查两者都为空的车辆
SELECT vehicle_id, vehicle_no, car_id, dept_id, status
FROM tb_vehicle_info
WHERE (car_id IS NULL OR car_id = '') OR dept_id IS NULL;
```
### 2. 修复数据
#### 方案1:手动补充car_id和dept_id
```sql
-- 示例:为车辆补充car_id和dept_id
UPDATE tb_vehicle_info
SET car_id = '对应的旧系统车辆ID',
dept_id = 对应的部门ID
WHERE vehicle_id = 具体的车辆ID;
```
#### 方案2:从旧系统重新同步
运行车辆同步定时任务,确保所有车辆都从旧系统正确同步。
#### 方案3:删除无效数据
如果确认某些车辆确实无效,可以删除:
```sql
-- 删除car_id和dept_id都为空的车辆
DELETE FROM tb_vehicle_info
WHERE (car_id IS NULL OR car_id = '') AND dept_id IS NULL;
```
**⚠️ 注意**: 删除前请先备份数据!
## 测试验证
### 测试场景1:正常车辆显示
**数据准备**:
```sql
INSERT INTO tb_vehicle_info (vehicle_no, car_id, dept_id, status)
VALUES ('粤A12345', '1001', 100, '0');
```
**预期结果**: 车辆在任务创建页面的下拉列表中显示
### 测试场景2:car_id为空的车辆
**数据准备**:
```sql
INSERT INTO tb_vehicle_info (vehicle_no, car_id, dept_id, status)
VALUES ('粤A67890', NULL, 100, '0');
```
**预期结果**: 车辆不在任务创建页面的下拉列表中显示
### 测试场景3:dept_id为空的车辆
**数据准备**:
```sql
INSERT INTO tb_vehicle_info (vehicle_no, car_id, dept_id, status)
VALUES ('粤A99999', '1002', NULL, '0');
```
**预期结果**: 车辆不在任务创建页面的下拉列表中显示
### 测试场景4:两者都为空的车辆
**数据准备**:
```sql
INSERT INTO tb_vehicle_info (vehicle_no, car_id, dept_id, status)
VALUES ('粤A00000', NULL, NULL, '0');
```
**预期结果**: 车辆不在任务创建页面的下拉列表中显示
### 测试场景5:car_id为空字符串
**数据准备**:
```sql
INSERT INTO tb_vehicle_info (vehicle_no, car_id, dept_id, status)
VALUES ('粤A11111', '', 100, '0');
```
**预期结果**: 车辆不在任务创建页面的下拉列表中显示
## 数据流程
```
前端调用 getAvailableVehicles()
↓
API: /task/vehicle/available
↓
Service: SysTaskServiceImpl.getAvailableVehicles()
↓
设置查询参数: status='0'
↓
Mapper: VehicleInfoMapper.selectVehicleInfoList()
↓
执行SQL查询:
SELECT * FROM tb_vehicle_info v
WHERE v.status = '0'
AND v.car_id IS NOT NULL
AND v.car_id != ''
AND v.dept_id IS NOT NULL
↓
返回过滤后的车辆列表
↓
前端显示车辆下拉列表
```
## 优化效果
### 1. 数据质量提升
- ✅ 确保任务关联的车辆都是有效的
- ✅ 避免因车辆数据不完整导致的业务异常
- ✅ 提高与旧系统的数据一致性
### 2. 用户体验优化
- ✅ 用户只能看到可用的车辆
- ✅ 减少选择错误的可能性
- ✅ 简化车辆选择流程
### 3. 系统稳定性
- ✅ 避免因关联数据缺失导致的同步失败
- ✅ 降低数据异常对业务的影响
- ✅ 提高系统的容错性
## 注意事项
### 1. 新增车辆时的要求
**后台管理系统**:
- 管理员新增车辆时,必须填写car_id和dept_id
- 建议在表单中设置为必填项
- 前端校验:提交前验证这两个字段不为空
**车辆同步**:
- 从旧系统同步车辆时,确保能获取到car_id
- 同步时设置合理的默认部门(dept_id)
### 2. 数据维护
**定期检查**:
```sql
-- 每月执行一次,检查是否有新增的无效车辆
SELECT COUNT(*) as invalid_count
FROM tb_vehicle_info
WHERE (car_id IS NULL OR car_id = '') OR dept_id IS NULL;
```
**数据监控**:
- 建议在后台管理系统中添加数据质量监控
- 当发现无效车辆时,及时通知管理员处理
### 3. 迁移兼容性
**历史数据处理**:
- 对于已创建的任务,关联的车辆可能包含无效数据
- 建议在任务详情页面做容错处理
- 显示车辆信息时,如果car_id为空,提示"车辆信息不完整"
### 4. 业务逻辑影响
**车辆绑定**:
- 用户只能绑定有效车辆
- 如果用户之前绑定了无效车辆,需要重新绑定
**任务分配**:
- 只能将任务分配给有效车辆
- 避免分配到无效车辆导致的业务流转异常
## 相关文件
### 后端文件
- `ruoyi-system/src/main/resources/mapper/system/VehicleInfoMapper.xml` - SQL查询修改
- `ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleInfoMapper.java` - Mapper接口
- `ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java` - 车辆查询服务
### 前端文件
- `app/pages/task/create-emergency.vue` - 急救转运任务创建页面
- `app/pages/bind-vehicle.vue` - 车辆绑定页面
- `app/api/vehicle.js` - 车辆API接口
### 文档文件
- `prd/任务车辆car_id和dept_id过滤说明.md`(本文档)
## 版本历史
- **v1.0** (2025-10-25): 初始版本,实现car_id和dept_id过滤功能