diff --git a/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelExcelServiceImpl.java b/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelExcelServiceImpl.java index b0541409..56d8b05a 100644 --- a/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelExcelServiceImpl.java +++ b/src/main/java/com/xujie/sys/modules/ecss/service/impl/CoDelExcelServiceImpl.java @@ -86,6 +86,11 @@ public class CoDelExcelServiceImpl implements CoDelExcelService { */ private static final int NOTIFY_DETAIL_BATCH_SIZE = Math.max(1, SQL_SERVER_PARAM_SAFE_LIMIT / NOTIFY_DETAIL_PARAM_COUNT_PER_ROW); + /** + * 统一维护 Cargo Ready Date 相关错误文案,避免前后端匹配漂移 + */ + private static final String CARGO_READY_DATE_EMPTY_ERROR_DETAIL = "[Cargo Ready Date] 列不能为空"; + private static final String CARGO_READY_DATE_PARSE_ERROR_DETAIL = "[Cargo Ready Date] 列格式有误"; private static final XSSFColor PART_ARCHIVE_LIGHT_TURQUOISE = new XSSFColor(new byte[]{(byte) 0x92, (byte) 0xCD, (byte) 0xDC}, new DefaultIndexedColorMap()); private static final XSSFColor PART_ARCHIVE_ORANGE = @@ -196,6 +201,13 @@ public class CoDelExcelServiceImpl implements CoDelExcelService { throw new RuntimeException("导入失败:" + e.getMessage()); } + // 业务规则:只要存在 Cargo Ready Date 为空的Sheet,就必须阻断提交,避免“预览告警但可提交”的数据不一致 + List readyDateEmptySheets = collectReadyDateEmptySheets(sheetErrors); + if (!readyDateEmptySheets.isEmpty()) { + throw new RuntimeException("提交失败:Sheet [" + String.join("、", readyDateEmptySheets) + + "] 存在 Cargo Ready Date 为空,请补充后重新上传"); + } + // 处理删除的发票号 if (deletedInvoices != null && !deletedInvoices.trim().isEmpty()) { try { @@ -678,12 +690,21 @@ public class CoDelExcelServiceImpl implements CoDelExcelService { // 解析日期 Date readDate; + String cargoReadyDateValue = getStringCellValue(row, cargoReadyDateIdx); + if (StringUtils.isBlank(cargoReadyDateValue)) { + currentSheetError.addErrorDetail("第" + (j + 1) + "行的 " + CARGO_READY_DATE_EMPTY_ERROR_DETAIL); + hasRowError = true; + continue; + } try { LocalDate localDate = parseDateCell(row.getCell(cargoReadyDateIdx)); + if (localDate == null) { + throw new RuntimeException(CARGO_READY_DATE_PARSE_ERROR_DETAIL); + } String formatted = localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); readDate = DateUtils.getDateByParten(formatted, "yyyy-MM-dd"); } catch (Exception e) { - currentSheetError.addErrorDetail("第" + (j+1) + "行的 [Cargo Ready Date] 列格式有误"); + currentSheetError.addErrorDetail("第" + (j + 1) + "行的 " + CARGO_READY_DATE_PARSE_ERROR_DETAIL); hasRowError = true; continue; } @@ -905,6 +926,32 @@ public class CoDelExcelServiceImpl implements CoDelExcelService { log.info("=== Excel导入完成 === 成功处理 {} 条数据,发现 {} 个Sheet存在问题", excelList.size(), sheetErrors.size()); } + /** + * 识别包含 Cargo Ready Date 为空错误的Sheet,用于提交阶段阻断。 + */ + private List collectReadyDateEmptySheets(List sheetErrors) { + if (sheetErrors == null || sheetErrors.isEmpty()) { + return Collections.emptyList(); + } + return sheetErrors.stream() + .filter(Objects::nonNull) + .filter(this::hasCargoReadyDateEmptyError) + .map(SheetErrorInfo::getSheetName) + .filter(StringUtils::isNotBlank) + .distinct() + .collect(Collectors.toList()); + } + + private boolean hasCargoReadyDateEmptyError(SheetErrorInfo sheetError) { + List errorDetails = sheetError.getErrorDetails(); + if (errorDetails == null || errorDetails.isEmpty()) { + return false; + } + return errorDetails.stream() + .filter(StringUtils::isNotBlank) + .anyMatch(detail -> detail.contains(CARGO_READY_DATE_EMPTY_ERROR_DETAIL)); + } + public static LocalDate parseDateCell(Cell cell) { if (cell == null) return null;