From f24209fa8e605cec08720557203fd02de0dca297 Mon Sep 17 00:00:00 2001 From: "weicw1996@qq.com" Date: Sat, 26 Sep 2026 10:46:39 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20=E8=AE=B0=E5=BD=95=E7=B1=BB=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=EF=BC=886=20=E4=B8=AA=E6=A8=A1=E5=9D=97=EF=BC=89?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E6=98=8E=E7=BB=86=E8=BF=94=E5=9B=9E=E5=85=A8?= =?UTF-8?q?=E9=87=8F=E5=8E=9F=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题:这 6 个模块(事故记录/年检记录/ETC记录/保险记录/维修记录/换胎记录) 在收集 errorList 后 setRollbackOnly 并 return,控制器据此导出「仅错误行」—— 失败明细不是原表全量,用户看不到哪几行是对的、不便对照原表修正。 改动(6 个模块同构处理): - 服务层:改为抛 ImportFailureException(data),明细携带**原表全部行**; 整批回滚由异常触发(替代 setRollbackOnly,语义不变)。 - 控制器:catch 异常后取 getFailureList() 导出,并补上传文件校验。 用 export(...) 保留按列标红(exportFailureReasonOnly 会丢失该能力)。 验证:mvn install -DskipTests 通过;记录类回归 48/48 (scripts/api-records-import-test.sh,6 模块 × 2 用例)。 标志性断言:3 行正确 + 第 4 行错 → 明细返回全部 4 行、仅第 4 行带原因、 库中零写入;全部正确 → 正常入库。 --- .../controller/AccidentRecordController.java | 15 ++++++++++++--- .../AnnualInspectionRecordController.java | 15 ++++++++++++--- .../transport/controller/EtcRecordController.java | 15 ++++++++++++--- .../controller/InsuranceRecordController.java | 15 ++++++++++++--- .../controller/MaintenanceRecordController.java | 15 ++++++++++++--- .../TireReplacementRecordController.java | 15 ++++++++++++--- .../service/impl/AccidentRecordServiceImpl.java | 5 +++-- .../impl/AnnualInspectionRecordServiceImpl.java | 5 +++-- .../service/impl/EtcRecordServiceImpl.java | 5 +++-- .../service/impl/InsuranceRecordServiceImpl.java | 5 +++-- .../impl/MaintenanceRecordServiceImpl.java | 5 +++-- .../impl/TireReplacementRecordServiceImpl.java | 5 +++-- 12 files changed, 90 insertions(+), 30 deletions(-) diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/AccidentRecordController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/AccidentRecordController.java index d28cbb12..7a6e7140 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/AccidentRecordController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/AccidentRecordController.java @@ -128,9 +128,18 @@ public class AccidentRecordController extends BladeController { @ApiOperationSupport(order = 5) @Operation(summary = "导入事故记录", description = "传入excel") public R importAccidentRecord(MultipartFile file, HttpServletResponse response) { - List failureList = accidentRecordService.importAccidentRecord(ExcelUtil.read(file, AccidentRecordExcel.class)); - if (Func.isNotEmpty(failureList)) { - org.springblade.common.excel.ImportFailureExcelUtil.export(response, "事故记录导入失败明细" + DateUtil.time(), "导入失败明细", failureList, AccidentRecordExcel.class); + if (file == null || file.isEmpty()) { + return R.fail("上传文件不能为空"); + } + String fileName = Func.toStrWithEmpty(file.getOriginalFilename(), "").toLowerCase(); + if (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx")) { + return R.fail("请上传 .xls,.xlsx 标准格式文件"); + } + try { + accidentRecordService.importAccidentRecord(ExcelUtil.read(file, AccidentRecordExcel.class)); + } catch (org.springblade.common.excel.ImportFailureException exception) { + // 任一行失败即整批回滚,导出原表全部数据并标注错误(含按列标红),用户修正后重新导入。 + org.springblade.common.excel.ImportFailureExcelUtil.export(response, "事故记录导入失败明细" + DateUtil.time(), "导入失败明细", exception.getFailureList(), AccidentRecordExcel.class); return null; } return R.success("操作成功"); diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/AnnualInspectionRecordController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/AnnualInspectionRecordController.java index e97fa2d1..1412b173 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/AnnualInspectionRecordController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/AnnualInspectionRecordController.java @@ -125,9 +125,18 @@ public class AnnualInspectionRecordController extends BladeController { @ApiOperationSupport(order = 6) @Operation(summary = "导入年检记录", description = "传入excel") public R importAnnualInspectionRecord(MultipartFile file, HttpServletResponse response) { - List failureList = annualInspectionRecordService.importAnnualInspectionRecord(ExcelUtil.read(file, AnnualInspectionRecordExcel.class)); - if (Func.isNotEmpty(failureList)) { - org.springblade.common.excel.ImportFailureExcelUtil.export(response, "年检记录导入失败明细" + DateUtil.time(), "导入失败明细", failureList, AnnualInspectionRecordExcel.class); + if (file == null || file.isEmpty()) { + return R.fail("上传文件不能为空"); + } + String fileName = Func.toStrWithEmpty(file.getOriginalFilename(), "").toLowerCase(); + if (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx")) { + return R.fail("请上传 .xls,.xlsx 标准格式文件"); + } + try { + annualInspectionRecordService.importAnnualInspectionRecord(ExcelUtil.read(file, AnnualInspectionRecordExcel.class)); + } catch (org.springblade.common.excel.ImportFailureException exception) { + // 任一行失败即整批回滚,导出原表全部数据并标注错误(含按列标红),用户修正后重新导入。 + org.springblade.common.excel.ImportFailureExcelUtil.export(response, "年检记录导入失败明细" + DateUtil.time(), "导入失败明细", exception.getFailureList(), AnnualInspectionRecordExcel.class); return null; } return R.success("操作成功"); diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/EtcRecordController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/EtcRecordController.java index 8258b7d1..fb3613cc 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/EtcRecordController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/EtcRecordController.java @@ -94,9 +94,18 @@ public class EtcRecordController extends BladeController { @ApiOperationSupport(order = 5) @Operation(summary = "导入ETC记录", description = "传入excel") public R importEtcRecord(MultipartFile file, HttpServletResponse response) { - List failureList = etcRecordService.importEtcRecord(ExcelUtil.read(file, EtcRecordExcel.class)); - if (Func.isNotEmpty(failureList)) { - org.springblade.common.excel.ImportFailureExcelUtil.export(response, "ETC记录导入失败明细" + DateUtil.time(), "导入失败明细", failureList, EtcRecordExcel.class); + if (file == null || file.isEmpty()) { + return R.fail("上传文件不能为空"); + } + String fileName = Func.toStrWithEmpty(file.getOriginalFilename(), "").toLowerCase(); + if (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx")) { + return R.fail("请上传 .xls,.xlsx 标准格式文件"); + } + try { + etcRecordService.importEtcRecord(ExcelUtil.read(file, EtcRecordExcel.class)); + } catch (org.springblade.common.excel.ImportFailureException exception) { + // 任一行失败即整批回滚,导出原表全部数据并标注错误(含按列标红),用户修正后重新导入。 + org.springblade.common.excel.ImportFailureExcelUtil.export(response, "ETC记录导入失败明细" + DateUtil.time(), "导入失败明细", exception.getFailureList(), EtcRecordExcel.class); return null; } return R.success("操作成功"); diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/InsuranceRecordController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/InsuranceRecordController.java index 4dc31536..4bf40c00 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/InsuranceRecordController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/InsuranceRecordController.java @@ -129,9 +129,18 @@ public class InsuranceRecordController extends BladeController { @ApiOperationSupport(order = 5) @Operation(summary = "导入保险记录", description = "传入excel") public R importInsuranceRecord(MultipartFile file, HttpServletResponse response) { - List failureList = insuranceRecordService.importInsuranceRecord(ExcelUtil.read(file, InsuranceRecordExcel.class)); - if (Func.isNotEmpty(failureList)) { - org.springblade.common.excel.ImportFailureExcelUtil.export(response, "保险记录导入失败明细" + DateUtil.time(), "导入失败明细", failureList, InsuranceRecordExcel.class); + if (file == null || file.isEmpty()) { + return R.fail("上传文件不能为空"); + } + String fileName = Func.toStrWithEmpty(file.getOriginalFilename(), "").toLowerCase(); + if (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx")) { + return R.fail("请上传 .xls,.xlsx 标准格式文件"); + } + try { + insuranceRecordService.importInsuranceRecord(ExcelUtil.read(file, InsuranceRecordExcel.class)); + } catch (org.springblade.common.excel.ImportFailureException exception) { + // 任一行失败即整批回滚,导出原表全部数据并标注错误(含按列标红),用户修正后重新导入。 + org.springblade.common.excel.ImportFailureExcelUtil.export(response, "保险记录导入失败明细" + DateUtil.time(), "导入失败明细", exception.getFailureList(), InsuranceRecordExcel.class); return null; } return R.success("操作成功"); diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/MaintenanceRecordController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/MaintenanceRecordController.java index e24f851f..51db7236 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/MaintenanceRecordController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/MaintenanceRecordController.java @@ -128,9 +128,18 @@ public class MaintenanceRecordController extends BladeController { @ApiOperationSupport(order = 5) @Operation(summary = "导入维修记录", description = "传入excel") public R importMaintenanceRecord(MultipartFile file, HttpServletResponse response) { - List failureList = maintenanceRecordService.importMaintenanceRecord(ExcelUtil.read(file, MaintenanceRecordExcel.class)); - if (Func.isNotEmpty(failureList)) { - org.springblade.common.excel.ImportFailureExcelUtil.export(response, "维修记录导入失败明细" + DateUtil.time(), "导入失败明细", failureList, MaintenanceRecordExcel.class); + if (file == null || file.isEmpty()) { + return R.fail("上传文件不能为空"); + } + String fileName = Func.toStrWithEmpty(file.getOriginalFilename(), "").toLowerCase(); + if (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx")) { + return R.fail("请上传 .xls,.xlsx 标准格式文件"); + } + try { + maintenanceRecordService.importMaintenanceRecord(ExcelUtil.read(file, MaintenanceRecordExcel.class)); + } catch (org.springblade.common.excel.ImportFailureException exception) { + // 任一行失败即整批回滚,导出原表全部数据并标注错误(含按列标红),用户修正后重新导入。 + org.springblade.common.excel.ImportFailureExcelUtil.export(response, "维修记录导入失败明细" + DateUtil.time(), "导入失败明细", exception.getFailureList(), MaintenanceRecordExcel.class); return null; } return R.success("操作成功"); diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/TireReplacementRecordController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/TireReplacementRecordController.java index d3d5741e..608d30ec 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/TireReplacementRecordController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/TireReplacementRecordController.java @@ -128,9 +128,18 @@ public class TireReplacementRecordController extends BladeController { @ApiOperationSupport(order = 5) @Operation(summary = "导入换胎记录", description = "传入excel") public R importTireReplacementRecord(MultipartFile file, HttpServletResponse response) { - List failureList = tireReplacementRecordService.importTireReplacementRecord(ExcelUtil.read(file, TireReplacementRecordExcel.class)); - if (Func.isNotEmpty(failureList)) { - org.springblade.common.excel.ImportFailureExcelUtil.export(response, "换胎记录导入失败明细" + DateUtil.time(), "导入失败明细", failureList, TireReplacementRecordExcel.class); + if (file == null || file.isEmpty()) { + return R.fail("上传文件不能为空"); + } + String fileName = Func.toStrWithEmpty(file.getOriginalFilename(), "").toLowerCase(); + if (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx")) { + return R.fail("请上传 .xls,.xlsx 标准格式文件"); + } + try { + tireReplacementRecordService.importTireReplacementRecord(ExcelUtil.read(file, TireReplacementRecordExcel.class)); + } catch (org.springblade.common.excel.ImportFailureException exception) { + // 任一行失败即整批回滚,导出原表全部数据并标注错误(含按列标红),用户修正后重新导入。 + org.springblade.common.excel.ImportFailureExcelUtil.export(response, "换胎记录导入失败明细" + DateUtil.time(), "导入失败明细", exception.getFailureList(), TireReplacementRecordExcel.class); return null; } return R.success("操作成功"); diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/AccidentRecordServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/AccidentRecordServiceImpl.java index 70b04017..b06948bb 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/AccidentRecordServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/AccidentRecordServiceImpl.java @@ -111,8 +111,9 @@ public class AccidentRecordServiceImpl extends BaseServiceImpl