From a6fea9127adbf7c8d764f5e90405d9789912fe4b Mon Sep 17 00:00:00 2001 From: tangwei Date: Fri, 24 Apr 2026 17:58:18 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yfd/platform/config/JacksonConfig.java | 3 + .../controller/FishDraftDataController.java | 151 ++++++++++++++++-- .../data/domain/FishImportResult.java | 2 + .../yfd/platform/data/domain/ImportTask.java | 5 + .../data/mapper/ImportTaskMapper.java | 13 ++ .../data/service/IImportTaskService.java | 10 ++ .../service/impl/FishImportServiceImpl.java | 2 + .../service/impl/ImportTaskServiceImpl.java | 23 ++- .../yfd/platform/env/domain/SdEngInfoBH.java | 4 +- .../system/controller/UserController.java | 15 ++ .../platform/utils/DataSourceRequestUtil.java | 10 +- 11 files changed, 219 insertions(+), 19 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/config/JacksonConfig.java b/backend/src/main/java/com/yfd/platform/config/JacksonConfig.java index fdf579d..bb5c416 100644 --- a/backend/src/main/java/com/yfd/platform/config/JacksonConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/JacksonConfig.java @@ -6,6 +6,9 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + @Configuration public class JacksonConfig { 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 b718579..7197d40 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 @@ -1,6 +1,7 @@ package com.yfd.platform.data.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.fasterxml.jackson.databind.ObjectMapper; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.data.domain.FishDraftData; @@ -22,9 +23,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; -import java.util.Date; -import java.util.List; -import java.util.UUID; +import java.util.*; /** *

@@ -45,6 +44,9 @@ public class FishDraftDataController { @Resource private IImportTaskService importTaskService; + @Resource + private ObjectMapper objectMapper; + @PostMapping("/page") @Operation(summary = "分页查询过鱼数据(关联电站和设施)") public ResponseResult queryPageList(@RequestBody DataSourceRequest dataSourceRequest) { @@ -242,8 +244,14 @@ public class FishDraftDataController { importTaskService.updateStatus(taskId, "VALIDATED", null); importTaskService.updateProgress(taskId, result.getTotalCount(), result.getSuccessCount(), result.getFailedCount()); + try { + String resultJson = objectMapper.writeValueAsString(result); + importTaskService.saveResultJson(taskId, resultJson); + } catch (Exception e) { + // 忽略JSON序列化错误,不影响主流程 + e.printStackTrace(); + } return ResponseResult.successData(result); - } catch (Exception e) { importTaskService.markFailed(taskId, "导入失败: " + e.getMessage()); return ResponseResult.error("导入失败: " + e.getMessage()); @@ -259,15 +267,138 @@ public class FishDraftDataController { } @GetMapping("/checkImportStatus") - @Operation(summary = "检查用户导入状态") + @Operation(summary = "检查用户导入状态(用于前端轮询或页面加载时检查)") public ResponseResult checkImportStatus() { String uploadUserId = SecurityUtils.getUserId(); - boolean hasTask = importTaskService.hasImportingTask(uploadUserId); ImportTask currentTask = importTaskService.getCurrentTaskByUserId(uploadUserId); - return ResponseResult.successData(java.util.Map.of( - "hasImportingTask", hasTask, - "currentTask", currentTask - )); + Map result = new HashMap<>(); + if (currentTask == null) { + result.put("hasImportingTask", false); + result.put("canImport", true); + result.put("currentTask", null); + return ResponseResult.successData(result); + } + + int totalCount = currentTask.getTotalCount() != null ? currentTask.getTotalCount() : 0; + int successCount = currentTask.getSuccessCount() != null ? currentTask.getSuccessCount() : 0; + int failCount = currentTask.getFailCount() != null ? currentTask.getFailCount() : 0; + int progressPercent = totalCount > 0 ? (int) ((successCount + failCount) * 100.0 / totalCount) : 0; + + String statusText = getStatusText(currentTask.getStatus()); + boolean canImport = isTaskComplete(currentTask.getStatus()); + + Map taskInfo = new HashMap<>(); + taskInfo.put("id", currentTask.getId()); + taskInfo.put("importNo", currentTask.getImportNo()); + taskInfo.put("fileName", currentTask.getFileName()); + taskInfo.put("fileSize", currentTask.getFileSize()); + taskInfo.put("status", currentTask.getStatus()); + taskInfo.put("statusText", statusText); + taskInfo.put("totalCount", totalCount); + taskInfo.put("successCount", successCount); + taskInfo.put("failCount", failCount); + taskInfo.put("progressPercent", progressPercent); + taskInfo.put("errorMsg", currentTask.getErrorMsg() != null ? currentTask.getErrorMsg() : ""); + taskInfo.put("uploadTime", currentTask.getUploadTime()); + + result.put("hasImportingTask", true); + result.put("canImport", canImport); + result.put("currentTask", taskInfo); + + return ResponseResult.successData(result); + } + + private String getStatusText(String status) { + return switch (status) { + case "UPLOADED" -> "已上传,等待解析"; + case "PARSING" -> "解析中"; + case "VALIDATING" -> "校验中"; + case "VALIDATED" -> "已校验,待确认导入"; + case "FAILED" -> "导入失败"; + case "CONFIRMED" -> "已完成"; + case "CANCELLED" -> "已取消"; + default -> "未知状态"; + }; + } + + private boolean isTaskComplete(String status) { + return "CONFIRMED".equals(status) || "FAILED".equals(status) || "CANCELLED".equals(status); + } + + @GetMapping("/getLastImportResult") + @Operation(summary = "获取用户最后一次导入结果(包含校验详情)") + public ResponseResult getLastImportResult() { + String uploadUserId = SecurityUtils.getUserId(); + ImportTask lastTask = importTaskService.getLastImportResult(uploadUserId); + + if (lastTask == null) { + return ResponseResult.successData(java.util.Map.of( + "hasData", false, + "message", "暂无导入记录" + )); + } + + FishImportResult importResult = null; + if (lastTask.getResultJson() != null && !lastTask.getResultJson().isEmpty()) { + try { + importResult = objectMapper.readValue(lastTask.getResultJson(), FishImportResult.class); + } catch (Exception e) { + e.printStackTrace(); + // ignore parse error + } + } + + int totalCount = lastTask.getTotalCount() != null ? lastTask.getTotalCount() : 0; + int successCount = lastTask.getSuccessCount() != null ? lastTask.getSuccessCount() : 0; + int failCount = lastTask.getFailCount() != null ? lastTask.getFailCount() : 0; + int progressPercent = totalCount > 0 ? (int) ((successCount + failCount) * 100.0 / totalCount) : 0; + + Map taskInfo = buildTaskInfoMap(lastTask, getStatusText(lastTask.getStatus()), + totalCount, successCount, failCount, progressPercent); + Map resultInfo = buildResultInfoMap(importResult); + + Map result = new HashMap<>(); + result.put("task", taskInfo); + result.put("result", resultInfo); + result.put("hasData", true); + return ResponseResult.successData(result); + } + + private Map buildTaskInfoMap(ImportTask task, String statusText, + int totalCount, int successCount, + int failCount, int progressPercent) { + Map map = new HashMap<>(); + map.put("id", task.getId()); + map.put("importNo", task.getImportNo()); + map.put("fileName", task.getFileName()); + map.put("fileSize", task.getFileSize()); + map.put("status", task.getStatus()); + map.put("statusText", statusText); + map.put("totalCount", totalCount); + map.put("successCount", successCount); + map.put("failCount", failCount); + map.put("progressPercent", progressPercent); + map.put("errorMsg", task.getErrorMsg() != null ? task.getErrorMsg() : ""); + map.put("uploadTime", task.getUploadTime()); + return map; + } + + private Map buildResultInfoMap(FishImportResult importResult) { + if (importResult == null) { + return null; + } + + Map map = new HashMap<>(); + map.put("successRows", importResult.getSuccessRows() != null ? importResult.getSuccessRows().size() : 0); + map.put("failedRows", importResult.getFailedRows() != null ? importResult.getFailedRows().size() : 0); + map.put("unrecognizedFields", importResult.getUnrecognizedFields() != null ? + importResult.getUnrecognizedFields() : new ArrayList<>()); + map.put("tempDir", importResult.getTempDir() != null ? importResult.getTempDir() : ""); + map.put("excelFileName", importResult.getExcelFileName() != null ? + importResult.getExcelFileName() : ""); + map.put("failedRowDetails", importResult.getFailedRows() != null ? + importResult.getFailedRows() : new ArrayList<>()); + return map; } @PostMapping("/cleanupTemp") diff --git a/backend/src/main/java/com/yfd/platform/data/domain/FishImportResult.java b/backend/src/main/java/com/yfd/platform/data/domain/FishImportResult.java index 6a5ecaa..d466b44 100644 --- a/backend/src/main/java/com/yfd/platform/data/domain/FishImportResult.java +++ b/backend/src/main/java/com/yfd/platform/data/domain/FishImportResult.java @@ -22,6 +22,8 @@ public class FishImportResult { private int successCount; private int failedCount; private String summary; + private String code; + private String message; public FishImportResult() { this.successRows = new ArrayList<>(); diff --git a/backend/src/main/java/com/yfd/platform/data/domain/ImportTask.java b/backend/src/main/java/com/yfd/platform/data/domain/ImportTask.java index fe058ac..53b6311 100644 --- a/backend/src/main/java/com/yfd/platform/data/domain/ImportTask.java +++ b/backend/src/main/java/com/yfd/platform/data/domain/ImportTask.java @@ -95,6 +95,11 @@ public class ImportTask implements Serializable { */ private Date expireTime; + /** + * 导入结果JSON(存储校验后的数据) + */ + private String resultJson; + /** * 创建时间 */ diff --git a/backend/src/main/java/com/yfd/platform/data/mapper/ImportTaskMapper.java b/backend/src/main/java/com/yfd/platform/data/mapper/ImportTaskMapper.java index 5a45a82..e36f654 100644 --- a/backend/src/main/java/com/yfd/platform/data/mapper/ImportTaskMapper.java +++ b/backend/src/main/java/com/yfd/platform/data/mapper/ImportTaskMapper.java @@ -53,4 +53,17 @@ public interface ImportTaskMapper extends BaseMapper { */ @Select("SELECT * FROM IMPORT_TASK WHERE EXPIRE_TIME < SYSDATE AND EXPIRE_TIME IS NOT NULL") List selectExpiredTasks(); + + /** + * 获取用户最后一次导入结果(所有状态,按创建时间倒序取第一条) + */ + @Select("\n" + + "SELECT * FROM (\n" + + " SELECT * \n" + + " FROM IMPORT_TASK \n" + + " WHERE UPLOAD_USER_ID = #{uploadUserId} \n" + + " AND BIZ_TYPE = 'FISH' \n" + + " ORDER BY CREATED_AT DESC\n" + + ") WHERE ROWNUM = 1;") + ImportTask selectLastByUserId(@Param("uploadUserId") String uploadUserId); } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/service/IImportTaskService.java b/backend/src/main/java/com/yfd/platform/data/service/IImportTaskService.java index 5879bd5..901bf65 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/IImportTaskService.java +++ b/backend/src/main/java/com/yfd/platform/data/service/IImportTaskService.java @@ -77,4 +77,14 @@ public interface IImportTaskService extends IService { * 获取用户当前正在进行的导入任务 */ ImportTask getCurrentTaskByUserId(String uploadUserId); + + /** + * 保存导入结果JSON + */ + boolean saveResultJson(String taskId, String resultJson); + + /** + * 获取用户最后一次导入结果(用于断点续传或查看历史) + */ + ImportTask getLastImportResult(String uploadUserId); } \ 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 344f33f..338d3ce 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 @@ -731,6 +731,8 @@ public class FishImportServiceImpl implements IFishImportService { } catch (Exception e) { result.setSummary("ZIP文件解析失败: " + e.getMessage()); + result.setCode("1"); + result.setMessage("ZIP文件解析失败"); return result; } } diff --git a/backend/src/main/java/com/yfd/platform/data/service/impl/ImportTaskServiceImpl.java b/backend/src/main/java/com/yfd/platform/data/service/impl/ImportTaskServiceImpl.java index 3fdee2d..3d1a91a 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/impl/ImportTaskServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/data/service/impl/ImportTaskServiceImpl.java @@ -1,5 +1,6 @@ package com.yfd.platform.data.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yfd.platform.data.domain.ImportTask; @@ -164,11 +165,29 @@ public class ImportTaskServiceImpl extends ServiceImpl activeStatuses = List.of("UPLOADED", "PARSING", "VALIDATING"); + List activeStatuses = List.of("UPLOADED", "PARSING", "VALIDATED"); List tasks = importTaskMapper.selectByUserIdAndStatuses(uploadUserId, activeStatuses); if (tasks == null || tasks.isEmpty()) { return null; } - return tasks.get(0); + return tasks.getFirst(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean saveResultJson(String taskId, String resultJson) { + ImportTask importTask = this.getById(taskId); + if (importTask == null) { + return false; + } + importTask.setResultJson(resultJson); + importTask.setUpdatedAt(new Date()); + return this.updateById(importTask); + } + + @Override + public ImportTask getLastImportResult(String uploadUserId) { + ImportTask importTask = importTaskMapper.selectOne(new LambdaQueryWrapper().eq(ImportTask::getUploadUserId, uploadUserId).eq(ImportTask::getBizType, "FISH").orderByDesc(ImportTask::getCreatedAt)); + return importTask; } } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/domain/SdEngInfoBH.java b/backend/src/main/java/com/yfd/platform/env/domain/SdEngInfoBH.java index c4f393c..bb71e6b 100644 --- a/backend/src/main/java/com/yfd/platform/env/domain/SdEngInfoBH.java +++ b/backend/src/main/java/com/yfd/platform/env/domain/SdEngInfoBH.java @@ -247,12 +247,12 @@ public class SdEngInfoBH implements Serializable { /** * 电站-主要功能 1=发电 2=防洪 3=灌溉 4=供水 5=航运 6=旅游 7=环境 8=养殖 9=其他 */ - private Integer fn; + private String fn; /** * 地震基本烈度 字典编码:sd_enginfo_b_h.bsssin 5=<Ⅵ 6=Ⅵ 7=Ⅶ 8=Ⅷ 9=≥Ⅸ */ - private Integer bsssin; + private String bsssin; /** * 设防地震烈度 字典编码:sd_enginfo_b_h.frssin 0=未设防 6=Ⅵ 7=Ⅶ 8=Ⅷ 9=≥Ⅸ diff --git a/backend/src/main/java/com/yfd/platform/system/controller/UserController.java b/backend/src/main/java/com/yfd/platform/system/controller/UserController.java index ecf4003..914b8f7 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/UserController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/UserController.java @@ -88,6 +88,21 @@ public class UserController { } } + + /*********************************** + * 用途说明:根据id查询用户信息 + * 参数说明 + *id 用户id + * 返回值说明: 用户信息 + ************************************/ + @GetMapping("/queryUserById") + @Operation(summary = "根据id查询用户信息") + @ResponseBody + public ResponseResult queryUserById(String id) { + SysUser user = userService.getById(id); + return ResponseResult.successData(user); + } + /*********************************** * 用途说明:根据id删除用户 * 参数说明 diff --git a/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java b/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java index 08e156f..17197a2 100644 --- a/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java +++ b/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java @@ -153,7 +153,7 @@ public class DataSourceRequestUtil { } if (filters.size() == 1) { - applyFilters(filters.get(0), wrapper, entityClass, fieldMapping, excludeFields, parentLogic); + applyFilters(filters.getFirst(), wrapper, entityClass, fieldMapping, excludeFields, parentLogic); return; } @@ -164,10 +164,10 @@ public class DataSourceRequestUtil { List logics = new ArrayList<>(); for (int i = 0; i < filters.size(); i++) { - QueryWrapper subWrapper = new QueryWrapper<>(); - applyFilters(filters.get(i), subWrapper, entityClass, fieldMapping, excludeFields, logic); - if (hasConditions(subWrapper)) { - conditionGroups.add(subWrapper); +// QueryWrapper subWrapper = new QueryWrapper<>(); + applyFilters(filters.get(i), wrapper, entityClass, fieldMapping, excludeFields, logic); + if (hasConditions(wrapper)) { + conditionGroups.add(wrapper); if (i > 0) { logics.add(isAnd ? "and" : "or"); }