fix: 优化逻辑

This commit is contained in:
tangwei 2026-04-24 17:58:18 +08:00
parent a163b4377f
commit a6fea9127a
11 changed files with 219 additions and 19 deletions

View File

@ -6,6 +6,9 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
@Configuration @Configuration
public class JacksonConfig { public class JacksonConfig {

View File

@ -1,6 +1,7 @@
package com.yfd.platform.data.controller; package com.yfd.platform.data.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceRequest;
import com.yfd.platform.config.ResponseResult; import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.data.domain.FishDraftData; import com.yfd.platform.data.domain.FishDraftData;
@ -22,9 +23,7 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.IOException; import java.io.IOException;
import java.util.Date; import java.util.*;
import java.util.List;
import java.util.UUID;
/** /**
* <p> * <p>
@ -45,6 +44,9 @@ public class FishDraftDataController {
@Resource @Resource
private IImportTaskService importTaskService; private IImportTaskService importTaskService;
@Resource
private ObjectMapper objectMapper;
@PostMapping("/page") @PostMapping("/page")
@Operation(summary = "分页查询过鱼数据(关联电站和设施)") @Operation(summary = "分页查询过鱼数据(关联电站和设施)")
public ResponseResult queryPageList(@RequestBody DataSourceRequest dataSourceRequest) { public ResponseResult queryPageList(@RequestBody DataSourceRequest dataSourceRequest) {
@ -242,8 +244,14 @@ public class FishDraftDataController {
importTaskService.updateStatus(taskId, "VALIDATED", null); importTaskService.updateStatus(taskId, "VALIDATED", null);
importTaskService.updateProgress(taskId, result.getTotalCount(), result.getSuccessCount(), result.getFailedCount()); 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); return ResponseResult.successData(result);
} catch (Exception e) { } catch (Exception e) {
importTaskService.markFailed(taskId, "导入失败: " + e.getMessage()); importTaskService.markFailed(taskId, "导入失败: " + e.getMessage());
return ResponseResult.error("导入失败: " + e.getMessage()); return ResponseResult.error("导入失败: " + e.getMessage());
@ -259,15 +267,138 @@ public class FishDraftDataController {
} }
@GetMapping("/checkImportStatus") @GetMapping("/checkImportStatus")
@Operation(summary = "检查用户导入状态") @Operation(summary = "检查用户导入状态(用于前端轮询或页面加载时检查)")
public ResponseResult checkImportStatus() { public ResponseResult checkImportStatus() {
String uploadUserId = SecurityUtils.getUserId(); String uploadUserId = SecurityUtils.getUserId();
boolean hasTask = importTaskService.hasImportingTask(uploadUserId);
ImportTask currentTask = importTaskService.getCurrentTaskByUserId(uploadUserId); ImportTask currentTask = importTaskService.getCurrentTaskByUserId(uploadUserId);
return ResponseResult.successData(java.util.Map.of( Map<String, Object> result = new HashMap<>();
"hasImportingTask", hasTask, if (currentTask == null) {
"currentTask", currentTask 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<String, Object> 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<String, Object> taskInfo = buildTaskInfoMap(lastTask, getStatusText(lastTask.getStatus()),
totalCount, successCount, failCount, progressPercent);
Map<String, Object> resultInfo = buildResultInfoMap(importResult);
Map<String, Object> result = new HashMap<>();
result.put("task", taskInfo);
result.put("result", resultInfo);
result.put("hasData", true);
return ResponseResult.successData(result);
}
private Map<String, Object> buildTaskInfoMap(ImportTask task, String statusText,
int totalCount, int successCount,
int failCount, int progressPercent) {
Map<String, Object> 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<String, Object> buildResultInfoMap(FishImportResult importResult) {
if (importResult == null) {
return null;
}
Map<String, Object> 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") @PostMapping("/cleanupTemp")

View File

@ -22,6 +22,8 @@ public class FishImportResult {
private int successCount; private int successCount;
private int failedCount; private int failedCount;
private String summary; private String summary;
private String code;
private String message;
public FishImportResult() { public FishImportResult() {
this.successRows = new ArrayList<>(); this.successRows = new ArrayList<>();

View File

@ -95,6 +95,11 @@ public class ImportTask implements Serializable {
*/ */
private Date expireTime; private Date expireTime;
/**
* 导入结果JSON存储校验后的数据
*/
private String resultJson;
/** /**
* 创建时间 * 创建时间
*/ */

View File

@ -53,4 +53,17 @@ public interface ImportTaskMapper extends BaseMapper<ImportTask> {
*/ */
@Select("SELECT * FROM IMPORT_TASK WHERE EXPIRE_TIME < SYSDATE AND EXPIRE_TIME IS NOT NULL") @Select("SELECT * FROM IMPORT_TASK WHERE EXPIRE_TIME < SYSDATE AND EXPIRE_TIME IS NOT NULL")
List<ImportTask> selectExpiredTasks(); List<ImportTask> 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);
} }

View File

@ -77,4 +77,14 @@ public interface IImportTaskService extends IService<ImportTask> {
* 获取用户当前正在进行的导入任务 * 获取用户当前正在进行的导入任务
*/ */
ImportTask getCurrentTaskByUserId(String uploadUserId); ImportTask getCurrentTaskByUserId(String uploadUserId);
/**
* 保存导入结果JSON
*/
boolean saveResultJson(String taskId, String resultJson);
/**
* 获取用户最后一次导入结果用于断点续传或查看历史
*/
ImportTask getLastImportResult(String uploadUserId);
} }

View File

@ -731,6 +731,8 @@ public class FishImportServiceImpl implements IFishImportService {
} catch (Exception e) { } catch (Exception e) {
result.setSummary("ZIP文件解析失败: " + e.getMessage()); result.setSummary("ZIP文件解析失败: " + e.getMessage());
result.setCode("1");
result.setMessage("ZIP文件解析失败");
return result; return result;
} }
} }

View File

@ -1,5 +1,6 @@
package com.yfd.platform.data.service.impl; 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.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.data.domain.ImportTask; import com.yfd.platform.data.domain.ImportTask;
@ -164,11 +165,29 @@ public class ImportTaskServiceImpl extends ServiceImpl<ImportTaskMapper, ImportT
@Override @Override
public ImportTask getCurrentTaskByUserId(String uploadUserId) { public ImportTask getCurrentTaskByUserId(String uploadUserId) {
List<String> activeStatuses = List.of("UPLOADED", "PARSING", "VALIDATING"); List<String> activeStatuses = List.of("UPLOADED", "PARSING", "VALIDATED");
List<ImportTask> tasks = importTaskMapper.selectByUserIdAndStatuses(uploadUserId, activeStatuses); List<ImportTask> tasks = importTaskMapper.selectByUserIdAndStatuses(uploadUserId, activeStatuses);
if (tasks == null || tasks.isEmpty()) { if (tasks == null || tasks.isEmpty()) {
return null; 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<ImportTask>().eq(ImportTask::getUploadUserId, uploadUserId).eq(ImportTask::getBizType, "FISH").orderByDesc(ImportTask::getCreatedAt));
return importTask;
} }
} }

View File

@ -247,12 +247,12 @@ public class SdEngInfoBH implements Serializable {
/** /**
* 电站-主要功能 1=发电 2=防洪 3=灌溉 4=供水 5=航运 6=旅游 7=环境 8=养殖 9=其他 * 电站-主要功能 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= * 地震基本烈度 字典编码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= * 设防地震烈度 字典编码sd_enginfo_b_h.frssin 0=未设防 6= 7= 8= 9=

View File

@ -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删除用户 * 用途说明根据id删除用户
* 参数说明 * 参数说明

View File

@ -153,7 +153,7 @@ public class DataSourceRequestUtil {
} }
if (filters.size() == 1) { if (filters.size() == 1) {
applyFilters(filters.get(0), wrapper, entityClass, fieldMapping, excludeFields, parentLogic); applyFilters(filters.getFirst(), wrapper, entityClass, fieldMapping, excludeFields, parentLogic);
return; return;
} }
@ -164,10 +164,10 @@ public class DataSourceRequestUtil {
List<String> logics = new ArrayList<>(); List<String> logics = new ArrayList<>();
for (int i = 0; i < filters.size(); i++) { for (int i = 0; i < filters.size(); i++) {
QueryWrapper<T> subWrapper = new QueryWrapper<>(); // QueryWrapper<T> subWrapper = new QueryWrapper<>();
applyFilters(filters.get(i), subWrapper, entityClass, fieldMapping, excludeFields, logic); applyFilters(filters.get(i), wrapper, entityClass, fieldMapping, excludeFields, logic);
if (hasConditions(subWrapper)) { if (hasConditions(wrapper)) {
conditionGroups.add(subWrapper); conditionGroups.add(wrapper);
if (i > 0) { if (i > 0) {
logics.add(isAnd ? "and" : "or"); logics.add(isAnd ? "and" : "or");
} }