🐛 修复违章记录导入的类型与事项字段混淆问题

- 导入模型将合并的"类型/事项"列拆分为"*类型"与"*事项"两列,与导出模型保持一致
- 校验与清空逻辑改为按车船类型严格匹配:车辆只允许填类型,船舶只允许填事项,误填对侧字段直接报错而非静默丢弃
- 将清空对侧字段的时机从 prepare 移到 validate 之后,避免用户误填内容被静默丢弃
- 提取 CAR/SHIP 常量,替换散落的"车辆"/"船舶"字面量
This commit is contained in:
2026-09-20 17:51:29 +08:00
parent 9668f6059a
commit 98697af6df
2 changed files with 31 additions and 15 deletions
@@ -60,8 +60,11 @@ public class ViolationRecordImportExcel implements Serializable {
@ExcelProperty("*驾驶人")
private String driverName;
@ExcelProperty("*类型/事项")
private String violationTypeOrItem;
@ExcelProperty("*类型")
private String violationType;
@ExcelProperty("*事项")
private String violationItem;
@ExcelProperty("*时间")
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
@@ -67,6 +67,8 @@ public class ViolationRecordServiceImpl extends BaseServiceImpl<ViolationRecordM
private static final int MAX_DEDUCT_POINTS = 15;
private static final String PROCESSED = "已处理";
private static final String UNPROCESSED = "未处理";
private static final String CAR = "车辆";
private static final String SHIP = "船舶";
@Override
public IPage<ViolationRecordVO> selectViolationRecordPage(IPage<ViolationRecordVO> page, ViolationRecordVO violationRecord) {
@@ -81,6 +83,7 @@ public class ViolationRecordServiceImpl extends BaseServiceImpl<ViolationRecordM
prepare(violationRecord);
validate(violationRecord);
validateVehicleTypeImmutable(violationRecord);
clearIrrelevantField(violationRecord);
return saveOrUpdate(violationRecord);
}
@@ -95,11 +98,6 @@ public class ViolationRecordServiceImpl extends BaseServiceImpl<ViolationRecordM
ViolationRecordImportExcel excel = data.get(index);
try {
ViolationRecord violationRecord = Objects.requireNonNull(BeanUtil.copyProperties(excel, ViolationRecord.class));
if ("船舶".equals(trimToEmpty(excel.getVehicleType()))) {
violationRecord.setViolationItem(excel.getViolationTypeOrItem());
} else {
violationRecord.setViolationType(excel.getViolationTypeOrItem());
}
submit(violationRecord);
} catch (Exception exception) {
excel.setErrorMessage("" + (index + 2) + "行:" + exception.getMessage());
@@ -132,21 +130,30 @@ public class ViolationRecordServiceImpl extends BaseServiceImpl<ViolationRecordM
violationRecord.setProcessDescription(trimToEmpty(violationRecord.getProcessDescription()));
violationRecord.setProcessResult(trimToNull(violationRecord.getProcessResult()));
violationRecord.setAttachments(trimToNull(violationRecord.getAttachments()));
if ("车辆".equals(violationRecord.getVehicleType())) {
if (UNPROCESSED.equals(violationRecord.getProcessStatus())) {
violationRecord.setProcessResult(null);
}
}
/**
* 清空与车船类型不匹配的对侧字段
* <p>
* 必须在 validate 之后执行:校验需要看到用户填了什么,
* 若提前清空,误填的内容会被静默丢弃,用户无从察觉。
*/
private void clearIrrelevantField(ViolationRecord violationRecord) {
if (CAR.equals(violationRecord.getVehicleType())) {
violationRecord.setViolationItem(null);
} else {
violationRecord.setViolationType(null);
}
if (UNPROCESSED.equals(violationRecord.getProcessStatus())) {
violationRecord.setProcessResult(null);
}
}
private void validate(ViolationRecord violationRecord) {
if (Func.isEmpty(violationRecord.getVehicleType())) {
throw new ServiceException("车船类型不能为空");
}
if (!"车辆".equals(violationRecord.getVehicleType()) && !"船舶".equals(violationRecord.getVehicleType())) {
if (!CAR.equals(violationRecord.getVehicleType()) && !SHIP.equals(violationRecord.getVehicleType())) {
throw new ServiceException("车船类型不正确");
}
if (Func.isEmpty(violationRecord.getVehicleNo())) {
@@ -155,12 +162,18 @@ public class ViolationRecordServiceImpl extends BaseServiceImpl<ViolationRecordM
if (Func.isEmpty(violationRecord.getDriverName())) {
throw new ServiceException("驾驶人/船长不能为空");
}
if ("车辆".equals(violationRecord.getVehicleType()) && Func.isEmpty(violationRecord.getViolationType())) {
if (CAR.equals(violationRecord.getVehicleType()) && Func.isEmpty(violationRecord.getViolationType())) {
throw new ServiceException("类型不能为空");
}
if ("船舶".equals(violationRecord.getVehicleType()) && Func.isEmpty(violationRecord.getViolationItem())) {
if (SHIP.equals(violationRecord.getVehicleType()) && Func.isEmpty(violationRecord.getViolationItem())) {
throw new ServiceException("事项不能为空");
}
if (SHIP.equals(violationRecord.getVehicleType()) && Func.isNotEmpty(violationRecord.getViolationType())) {
throw new ServiceException("船舶不适用于类型,该列应留空");
}
if (CAR.equals(violationRecord.getVehicleType()) && Func.isNotEmpty(violationRecord.getViolationItem())) {
throw new ServiceException("车辆不适用于事项,该列应留空");
}
if (Func.isEmpty(violationRecord.getViolationTime())) {
throw new ServiceException("时间不能为空");
}
@@ -239,7 +252,7 @@ public class ViolationRecordServiceImpl extends BaseServiceImpl<ViolationRecordM
private String normalizeVehicleType(String vehicleType) {
String value = trimToEmpty(vehicleType);
return value.isEmpty() ? "车辆" : value;
return value.isEmpty() ? CAR : value;
}
private String normalizeProcessStatus(String processStatus) {