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 93f1d16..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,14 +267,138 @@ public class FishDraftDataController {
}
@GetMapping("/checkImportStatus")
- @Operation(summary = "检查用户导入状态")
- public ResponseResult checkImportStatus(@RequestParam String uploadUserId) {
- boolean hasTask = importTaskService.hasImportingTask(uploadUserId);
+ @Operation(summary = "检查用户导入状态(用于前端轮询或页面加载时检查)")
+ public ResponseResult checkImportStatus() {
+ String uploadUserId = SecurityUtils.getUserId();
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/FishDraftData.java b/backend/src/main/java/com/yfd/platform/data/domain/FishDraftData.java
index b78bee5..90085ef 100644
--- a/backend/src/main/java/com/yfd/platform/data/domain/FishDraftData.java
+++ b/backend/src/main/java/com/yfd/platform/data/domain/FishDraftData.java
@@ -1,6 +1,7 @@
package com.yfd.platform.data.domain;
import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -16,6 +17,7 @@ import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("FISH_DRAFT_DATA")
+@JsonIgnoreProperties(ignoreUnknown = true)
public class FishDraftData implements Serializable {
private static final long serialVersionUID = 1L;
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..b0ffa2a 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
@@ -1,5 +1,6 @@
package com.yfd.platform.data.domain;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import java.util.ArrayList;
@@ -8,6 +9,7 @@ import java.util.List;
import java.util.Map;
@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
public class FishImportResult {
private List successRows;
@@ -22,6 +24,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<>();
@@ -32,12 +36,18 @@ public class FishImportResult {
}
@Data
+ @JsonIgnoreProperties(ignoreUnknown = true)
public static class FishImportRow {
private int rowIndex;
private FishDraftData data;
private List unrecognizedFields;
private List warnings;
+ public FishImportRow() {
+ this.unrecognizedFields = new ArrayList<>();
+ this.warnings = new ArrayList<>();
+ }
+
public FishImportRow(int rowIndex) {
this.rowIndex = rowIndex;
this.unrecognizedFields = 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");
}