# 任务车辆关联插入问题修复说明 ## 问题描述 在新增任务车辆关联时出现以下错误: ``` ### 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. **数据审计**:记录所有分配操作的审计信息