From d4469cb8942039fd6809fce612ad45d2defe9d94 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 29 Apr 2026 18:41:50 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E5=88=9D=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FishDraftDataController.java | 297 ++++++++++++++++++ .../data/domain/FishImportRowRequest.java | 9 + .../data/service/IFishImportService.java | 26 ++ .../service/impl/FishImportServiceImpl.java | 53 +++- 4 files changed, 377 insertions(+), 8 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/data/domain/FishImportRowRequest.java diff --git a/backend/src/main/java/com/yfd/platform/data/controller/FishDraftDataController.java b/backend/src/main/java/com/yfd/platform/data/controller/FishDraftDataController.java index 05a1810..cc53f4f 100644 --- a/backend/src/main/java/com/yfd/platform/data/controller/FishDraftDataController.java +++ b/backend/src/main/java/com/yfd/platform/data/controller/FishDraftDataController.java @@ -438,4 +438,301 @@ public class FishDraftDataController { } } + @PostMapping("/revalidateAndUpdateRow") + @Operation(summary = "重新校验并更新导入数据") + public ResponseResult revalidateAndUpdateRow(@RequestBody FishImportRowRequest request) { + String taskId = request.getTaskId(); + FishDraftData data = request.getData(); + + if (taskId == null || taskId.isEmpty()) { + return ResponseResult.error("任务ID不能为空"); + } + if (data == null || data.getId() == null || data.getId().isEmpty()) { + return ResponseResult.error("数据对象或其ID不能为空"); + } + + try { + ImportTask task = importTaskService.getById(taskId); + if (task == null) { + return ResponseResult.error("任务不存在"); + } + + String resultJson = task.getResultJson(); + if (resultJson == null || resultJson.isEmpty()) { + return ResponseResult.error("任务结果为空"); + } + + FishImportResult importResult = objectMapper.readValue(resultJson, FishImportResult.class); + + FishImportResult.FishImportRow targetRow = null; + int targetIndex = -1; + for (int i = 0; i < importResult.getRows().size(); i++) { + FishImportResult.FishImportRow row = importResult.getRows().get(i); + if (row.getData() != null && data.getId().equals(row.getData().getId())) { + targetRow = row; + targetIndex = i; + break; + } + } + + if (targetIndex == -1) { + return ResponseResult.error("未找到对应的数据行"); + } + + FishImportResult.FishImportRow newRow = new FishImportResult.FishImportRow(targetRow.getRowIndex()); + newRow.setData(data); + newRow.setVdpthList(targetRow.getVdpthList()); + newRow.setPicpthList(targetRow.getPicpthList()); + newRow.setVdpthsWarnings(targetRow.getVdpthsWarnings()); + newRow.setPicpthsWarnings(targetRow.getPicpthsWarnings()); + + List warnings = new ArrayList<>(); + validateAndNormalizeData(data, newRow, warnings); + newRow.setWarnings(warnings); + String newStatus; + if (warnings.isEmpty()) { + newStatus = FishImportResult.STATUS_SUCCESS; + } else { + newStatus = FishImportResult.STATUS_FAILED; + } + newRow.setStatus(newStatus); + + importResult.getRows().set(targetIndex, newRow); + + int successCount = 0; + int failedCount = 0; + for (FishImportResult.FishImportRow row : importResult.getRows()) { + if (FishImportResult.STATUS_SUCCESS.equals(row.getStatus())) { + successCount++; + } else if (FishImportResult.STATUS_FAILED.equals(row.getStatus())) { + failedCount++; + } + } + importResult.setSuccessCount(successCount); + importResult.setFailedCount(failedCount); + + String updatedJson = objectMapper.writeValueAsString(importResult); + importTaskService.saveResultJson(taskId, updatedJson); + + Map map = new HashMap<>(); + map.put("success", true); + map.put("row", newRow); + map.put("successCount", successCount); + map.put("failedCount", failedCount); + map.put("warnings", warnings); + return ResponseResult.successData(map); + + } catch (Exception e) { + log.error("重新校验数据失败: " + e.getMessage(), e); + return ResponseResult.error("重新校验失败: " + e.getMessage()); + } + } + + private void validateAndNormalizeData(FishDraftData data, FishImportResult.FishImportRow importRow, + List warnings) { + if (data.getStnm() == null || data.getStnm().isEmpty()) { + warnings.add("stcd"); + } else { + String stcd = fishImportService.resolveFpssCode(data.getStnm().trim()); + if (stcd == null) { + warnings.add("stcd"); + } else { + data.setStcd(stcd); + } + } + + if (data.getEnnm() != null && !data.getEnnm().isEmpty()) { + String stationCode = fishImportService.resolveStationCode(data.getEnnm().trim()); + if (stationCode == null) { + warnings.add("rstcd"); + } else { + data.setRstcd(stationCode); + } + } + + if (data.getBaseName() != null && !data.getBaseName().isEmpty()) { + String baseId = fishImportService.resolveBaseCode(data.getBaseName().trim()); + if (baseId == null) { + warnings.add("baseId"); + } else { + data.setBaseId(baseId); + } + } + + if (data.getRvcd() != null && !data.getRvcd().isEmpty()) { + String rvcd = fishImportService.resolveRiverCode(data.getRvcd().trim()); + if (rvcd == null) { + warnings.add("rvcd"); + } + } + + if (data.getTm() == null) { + warnings.add("tm"); + } + + if (data.getFtp() == null || data.getFtp().isEmpty()) { + warnings.add("ftp"); + } else { + String ftpCode = fishImportService.resolveFishDictCode(data.getFtp().trim()); + if (ftpCode == null) { + warnings.add("ftp"); + } else { + data.setFtp(ftpCode); + } + } + + if (data.getFsz() != null) { + data.setFsz(data.getFsz().trim()); + } + + if (data.getFcnt() == null) { + warnings.add("fcnt"); + } + + if (data.getStrdt() == null) { + warnings.add("strdt"); + } + + if (data.getEnddt() != null && data.getStrdt() != null && data.getEnddt().before(data.getStrdt())) { + warnings.add("enddt"); + } + + if (data.getDirection() == null || data.getDirection().isEmpty()) { + warnings.add("direction"); + } else { + String direction = fishImportService.resolveDirection(data.getDirection().trim(), importRow); + if (direction == null) { + warnings.add("direction"); + } else { + data.setDirection(direction); + } + } + + if (data.getIsfs() == null) { + warnings.add("isfs"); + } else { + String isfs = fishImportService.resolveIsfs(String.valueOf(data.getIsfs()), importRow); + if (isfs == null) { + warnings.add("isfs"); + } else { + data.setIsfs("1".equals(isfs) ? 1 : 0); + } + } + + if (data.getSourceType() != null && !data.getSourceType().isEmpty()) { + data.setSourceType(fishImportService.parseSourceType(data.getSourceType().trim())); + } + } + + @PostMapping("/validateAndMatchRow") + @Operation(summary = "校验数据并匹配到成功或失败列表") + public ResponseResult validateAndMatchRow(@RequestBody FishImportRowRequest request) { + String taskId = request.getTaskId(); + FishDraftData data = request.getData(); + + if (taskId == null || taskId.isEmpty()) { + return ResponseResult.error("任务ID不能为空"); + } + if (data == null || data.getId() == null || data.getId().isEmpty()) { + return ResponseResult.error("数据对象或其ID不能为空"); + } + + try { + ImportTask task = importTaskService.getById(taskId); + if (task == null) { + return ResponseResult.error("任务不存在"); + } + + String resultJson = task.getResultJson(); + if (resultJson == null || resultJson.isEmpty()) { + return ResponseResult.error("任务结果为空"); + } + + FishImportResult importResult = objectMapper.readValue(resultJson, FishImportResult.class); + + FishImportResult.FishImportRow matchedRow = findMatchingRow(importResult, data.getId()); + + FishImportResult.FishImportRow resultRow = new FishImportResult.FishImportRow(); + resultRow.setData(data); + + if (matchedRow != null) { + resultRow.setUnrecognizedFields(matchedRow.getUnrecognizedFields()); + resultRow.setWarnings(matchedRow.getWarnings()); + resultRow.setVdpthList(matchedRow.getVdpthList()); + resultRow.setPicpthList(matchedRow.getPicpthList()); + resultRow.setVdpthsWarnings(matchedRow.getVdpthsWarnings()); + resultRow.setPicpthsWarnings(matchedRow.getPicpthsWarnings()); + resultRow.setStatus(matchedRow.getStatus()); + } + + List validationErrors = validateFishDraftData(data); + + boolean originallySuccess = matchedRow != null && matchedRow.isSuccess(); + boolean originallyFailed = matchedRow != null && matchedRow.isFailed(); + boolean hasValidationErrors = !validationErrors.isEmpty(); + + boolean shouldBeSuccess = originallySuccess && !hasValidationErrors; + boolean shouldBeFailed = originallyFailed || hasValidationErrors; + + if (shouldBeSuccess) { + resultRow.setStatus(FishImportResult.STATUS_SUCCESS); + } else if (shouldBeFailed) { + resultRow.setStatus(FishImportResult.STATUS_FAILED); + } + + return ResponseResult.successData(java.util.Map.of( + "matched", matchedRow != null, + "originallySuccess", originallySuccess, + "originallyFailed", originallyFailed, + "hasValidationErrors", hasValidationErrors, + "shouldBeSuccess", shouldBeSuccess, + "shouldBeFailed", shouldBeFailed, + "row", resultRow, + "validationErrors", validationErrors + )); + + } catch (Exception e) { + log.error("校验数据失败: " + e.getMessage(), e); + return ResponseResult.error("校验失败: " + e.getMessage()); + } + } + + private FishImportResult.FishImportRow findMatchingRow(FishImportResult importResult, String dataId) { + if (importResult.getRows() != null) { + for (FishImportResult.FishImportRow row : importResult.getRows()) { + if (row.getData() != null && dataId.equals(row.getData().getId())) { + return row; + } + } + } + return null; + } + + private List validateFishDraftData(FishDraftData data) { + List errors = new ArrayList<>(); + + if (data.getStcd() == null || data.getStcd().isEmpty()) { + errors.add("电站编码不能为空"); + } + if (data.getTm() == null) { + errors.add("填报时间不能为空"); + } + if (data.getFtp() == null || data.getFtp().isEmpty()) { + errors.add("鱼类不能为空"); + } + if (data.getFcnt() == null || data.getFcnt() < 0) { + errors.add("过鱼数量不合法"); + } + if (data.getStrdt() == null) { + errors.add("开始日期不能为空"); + } + if (data.getEnddt() == null) { + errors.add("结束日期不能为空"); + } + if (data.getStrdt() != null && data.getEnddt() != null && data.getStrdt().after(data.getEnddt())) { + errors.add("开始日期不能晚于结束日期"); + } + + return errors; + } } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/domain/FishImportRowRequest.java b/backend/src/main/java/com/yfd/platform/data/domain/FishImportRowRequest.java new file mode 100644 index 0000000..3dedff7 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/data/domain/FishImportRowRequest.java @@ -0,0 +1,9 @@ +package com.yfd.platform.data.domain; + +import lombok.Data; + +@Data +public class FishImportRowRequest { + private String taskId; + private FishDraftData data; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/service/IFishImportService.java b/backend/src/main/java/com/yfd/platform/data/service/IFishImportService.java index 7a597ba..b77fe66 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/IFishImportService.java +++ b/backend/src/main/java/com/yfd/platform/data/service/IFishImportService.java @@ -18,4 +18,30 @@ public interface IFishImportService { FishImportResult parseAndMapExcelFromPath(FishImportRequest request); FishImportResult parseAndMapZip(MultipartFile file, String uploadUserId); + + String resolveStationCode(String stationName); + + String resolveFpssCode(String name); + + String resolveStationCode(String code,String stationName); + + String resolveFpssCode(String code,String name); + + String resolveFishDictCode(String name); + + String resolveFishDictCode(String code,String name); + + String resolveBaseCode(String baseName); + + String resolveBaseCode(String code,String baseName); + + String resolveRiverCode(String riverName); + + String resolveRiverCode(String code,String riverName); + + String resolveDirection(String direction, FishImportResult.FishImportRow importRow); + + String resolveIsfs(String value, FishImportResult.FishImportRow importRow); + + String parseSourceType(String value); } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/service/impl/FishImportServiceImpl.java b/backend/src/main/java/com/yfd/platform/data/service/impl/FishImportServiceImpl.java index 9dcdce8..cee4c0a 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/impl/FishImportServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/data/service/impl/FishImportServiceImpl.java @@ -432,7 +432,7 @@ public class FishImportServiceImpl implements IFishImportService { - private String resolveStationCode(String stationName) { + public String resolveStationCode(String stationName) { if (stationName == null) { return null; } @@ -448,7 +448,7 @@ public class FishImportServiceImpl implements IFishImportService { return null; } - private String resolveFpssCode(String name) { + public String resolveFpssCode(String name) { if (name == null) { return null; } @@ -464,7 +464,29 @@ public class FishImportServiceImpl implements IFishImportService { return null; } - private String resolveFishDictCode(String name) { + @Override + public String resolveStationCode(String code, String stationName) { + if (stationName == null) { + return null; + } + String lowerName = stationName.toLowerCase().trim(); + if (STATION_NAME_CACHE.containsKey(lowerName)) { + return STATION_NAME_CACHE.get(lowerName); + } + for (Map.Entry entry : STATION_NAME_CACHE.entrySet()) { + if (entry.getKey().contains(lowerName)) { + return entry.getValue(); + } + } + return null; + } + + @Override + public String resolveFpssCode(String code, String name) { + return ""; + } + + public String resolveFishDictCode(String name) { if (name == null) { return null; } @@ -480,7 +502,12 @@ public class FishImportServiceImpl implements IFishImportService { return null; } - private String resolveBaseCode(String baseName) { + @Override + public String resolveFishDictCode(String code, String name) { + return ""; + } + + public String resolveBaseCode(String baseName) { if (baseName == null) { return null; } @@ -496,7 +523,12 @@ public class FishImportServiceImpl implements IFishImportService { return null; } - private String resolveRiverCode(String riverName) { + @Override + public String resolveBaseCode(String code, String baseName) { + return ""; + } + + public String resolveRiverCode(String riverName) { if (riverName == null) { return null; } @@ -512,6 +544,11 @@ public class FishImportServiceImpl implements IFishImportService { return null; } + @Override + public String resolveRiverCode(String code, String riverName) { + return ""; + } + private String validateFishType(String fishName, FishImportResult.FishImportRow importRow) { if (fishName == null) { return null; @@ -543,7 +580,7 @@ public class FishImportServiceImpl implements IFishImportService { return facilityName; } - private String resolveDirection(String direction, FishImportResult.FishImportRow importRow) { + public String resolveDirection(String direction, FishImportResult.FishImportRow importRow) { if (direction == null) { return null; } @@ -562,7 +599,7 @@ public class FishImportServiceImpl implements IFishImportService { return direction; } - private String resolveIsfs(String value, FishImportResult.FishImportRow importRow) { + public String resolveIsfs(String value, FishImportResult.FishImportRow importRow) { if (value == null) { return null; } @@ -719,7 +756,7 @@ public class FishImportServiceImpl implements IFishImportService { } - private String parseSourceType(String value) { + public String parseSourceType(String value) { if (!StringUtils.hasText(value)) { return "IMPORT"; }