Merge branch 'dev-tw'

This commit is contained in:
tangwei 2026-04-24 18:26:15 +08:00
commit 8d4c3bcf96
12 changed files with 231 additions and 20 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.Configuration;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
@Configuration
public class JacksonConfig {

View File

@ -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.*;
/**
* <p>
@ -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<String, Object> 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<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")

View File

@ -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;

View File

@ -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<FishImportRow> 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<String> unrecognizedFields;
private List<String> warnings;
public FishImportRow() {
this.unrecognizedFields = new ArrayList<>();
this.warnings = new ArrayList<>();
}
public FishImportRow(int rowIndex) {
this.rowIndex = rowIndex;
this.unrecognizedFields = new ArrayList<>();

View File

@ -95,6 +95,11 @@ public class ImportTask implements Serializable {
*/
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")
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);
/**
* 保存导入结果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) {
result.setSummary("ZIP文件解析失败: " + e.getMessage());
result.setCode("1");
result.setMessage("ZIP文件解析失败");
return result;
}
}

View File

@ -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<ImportTaskMapper, ImportT
@Override
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);
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<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=其他
*/
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=

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删除用户
* 参数说明

View File

@ -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<String> logics = new ArrayList<>();
for (int i = 0; i < filters.size(); i++) {
QueryWrapper<T> subWrapper = new QueryWrapper<>();
applyFilters(filters.get(i), subWrapper, entityClass, fieldMapping, excludeFields, logic);
if (hasConditions(subWrapper)) {
conditionGroups.add(subWrapper);
// QueryWrapper<T> 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");
}