# 任务车辆关联插入问题修复说明
## 问题描述
在新增任务车辆关联时出现以下错误:
```
### Error updating database. Cause: java.sql.SQLException: Field 'assign_time' doesn't have a default value ###
### The error may exist in file [SysTaskVehicleMapper.xml] ###
### The error may involve com.ruoyi.system.mapper.SysTaskVehicleMapper.insertSysTaskVehicle-Inline ###
### The error occurred while setting parameters ###
### SQL: insert into sys_task_vehicle ( task_id, vehicle_id, status ) values ( ?, ?, ? ) ###
```
## 问题原因
1. **数据库表结构约束**:`sys_task_vehicle` 表中的 `assign_time` 和 `assign_by` 字段定义为 `NOT NULL`
2. **Service层缺失**:`insertSysTaskVehicle` 方法没有设置这些必需字段的值
3. **Mapper层条件判断**:XML中的插入语句只有在字段不为null时才包含这些字段
## 修复方案
### 1. Service层修复
**文件**:`SysTaskVehicleServiceImpl.java`
**修复内容**:
```java
@Override
@Transactional
public int insertSysTaskVehicle(SysTaskVehicle sysTaskVehicle) {
// 设置分配时间和分配人
if (sysTaskVehicle.getAssignTime() == null) {
sysTaskVehicle.setAssignTime(DateUtils.getNowDate());
}
if (sysTaskVehicle.getAssignBy() == null || sysTaskVehicle.getAssignBy().isEmpty()) {
sysTaskVehicle.setAssignBy(SecurityUtils.getUsername());
}
// 设置默认状态
if (sysTaskVehicle.getStatus() == null || sysTaskVehicle.getStatus().isEmpty()) {
sysTaskVehicle.setStatus("ASSIGNED");
}
sysTaskVehicle.setCreateTime(DateUtils.getNowDate());
return sysTaskVehicleMapper.insertSysTaskVehicle(sysTaskVehicle);
}
```
**修复说明**:
- 自动设置 `assignTime` 为当前时间
- 自动设置 `assignBy` 为当前登录用户
- 自动设置 `status` 为 'ASSIGNED'(如果未设置)
- 确保所有必需字段都有值
### 2. Mapper层修复
**文件**:`SysTaskVehicleMapper.xml`
**修复前**:
```xml
insert into sys_task_vehicle
task_id,
vehicle_id,
assign_time,
assign_by,
status,
remark,
#{taskId},
#{vehicleId},
#{assignTime},
#{assignBy},
#{status},
#{remark},
```
**修复后**:
```xml
insert into sys_task_vehicle
task_id,
vehicle_id,
assign_time,
assign_by,
status,
remark,
#{taskId},
#{vehicleId},
#{assignTime},
#{assignBy},
#{status},
#{remark},
```
**修复说明**:
- `assign_time` 和 `assign_by` 字段总是被包含在插入语句中
- 不再使用条件判断,因为这些字段是必需的
- 确保数据库约束得到满足
## 数据库表结构
```sql
CREATE TABLE sys_task_vehicle (
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '关联ID',
task_id BIGINT NOT NULL COMMENT '任务ID',
vehicle_id BIGINT NOT NULL COMMENT '车辆ID',
assign_time DATETIME NOT NULL COMMENT '分配时间', -- NOT NULL 约束
assign_by VARCHAR(64) NOT NULL COMMENT '分配人', -- NOT NULL 约束
status VARCHAR(20) DEFAULT 'ASSIGNED' COMMENT '关联状态',
remark VARCHAR(500) COMMENT '备注',
UNIQUE KEY uk_task_vehicle (task_id, vehicle_id),
FOREIGN KEY (task_id) REFERENCES sys_task(task_id) ON DELETE CASCADE,
FOREIGN KEY (vehicle_id) REFERENCES tb_vehicle_info(vehicle_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='任务车辆关联表';
```
## 修复效果
### 修复前
- ❌ 插入时缺少必需字段值
- ❌ 数据库约束违反
- ❌ 出现 "Field doesn't have a default value" 错误
### 修复后
- ✅ 自动设置所有必需字段
- ✅ 满足数据库约束
- ✅ 插入操作成功
- ✅ 数据完整性得到保证
## 测试验证
### 1. 单元测试
```java
@Test
public void testInsertSysTaskVehicle() {
SysTaskVehicle taskVehicle = new SysTaskVehicle();
taskVehicle.setTaskId(1L);
taskVehicle.setVehicleId(1L);
// 不设置 assignTime, assignBy, status
int result = sysTaskVehicleService.insertSysTaskVehicle(taskVehicle);
assertThat(result).isEqualTo(1);
// 验证自动设置的字段
assertThat(taskVehicle.getAssignTime()).isNotNull();
assertThat(taskVehicle.getAssignBy()).isEqualTo("admin");
assertThat(taskVehicle.getStatus()).isEqualTo("ASSIGNED");
}
```
### 2. 集成测试
```sql
-- 测试插入
INSERT INTO sys_task_vehicle (task_id, vehicle_id, assign_time, assign_by, status)
VALUES (1, 1, NOW(), 'admin', 'ASSIGNED');
-- 验证结果
SELECT * FROM sys_task_vehicle WHERE task_id = 1 AND vehicle_id = 1;
```
## 注意事项
1. **数据一致性**:确保 `assign_time` 和 `assign_by` 字段始终有值
2. **用户上下文**:`assign_by` 字段依赖当前登录用户,需要确保用户已登录
3. **时间同步**:`assign_time` 使用服务器时间,确保时间同步
4. **状态管理**:默认状态为 'ASSIGNED',可根据业务需求调整
## 相关文件
- `SysTaskVehicleServiceImpl.java` - Service层实现
- `SysTaskVehicleMapper.xml` - MyBatis映射文件
- `sys_task_vehicle` - 数据库表
- `SysTaskVehicle.java` - 实体类
## 后续优化建议
1. **字段验证**:在实体类中添加字段验证注解
2. **异常处理**:添加更详细的异常处理机制
3. **日志记录**:记录分配操作的详细日志
4. **权限控制**:确保只有有权限的用户才能分配车辆
5. **数据审计**:记录所有分配操作的审计信息