From 10946f847674bafba114cd1a0e8a6d8be36176ff Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 22 Apr 2026 10:35:07 +0800 Subject: [PATCH 01/13] =?UTF-8?q?fix:=20=E6=96=B0=E5=A2=9E=E8=BF=87?= =?UTF-8?q?=E9=B1=BC=E6=96=87=E4=BB=B6=E5=AF=BC=E5=85=A5=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../platform/config/MyMetaObjectHandler.java | 9 + .../controller/FishDraftDataController.java | 46 +- .../platform/data/domain/FishDraftData.java | 7 + .../data/domain/FishImportRequest.java | 20 + .../data/domain/FishImportResult.java | 38 ++ .../yfd/platform/data/domain/ImportTask.java | 2 +- .../data/service/IFishImportService.java | 31 ++ .../service/impl/FishImportServiceImpl.java | 403 ++++++++++++++++++ .../com/yfd/platform/utils/SecurityUtils.java | 10 + 9 files changed, 562 insertions(+), 4 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/data/domain/FishImportRequest.java create mode 100644 backend/src/main/java/com/yfd/platform/data/domain/FishImportResult.java create mode 100644 backend/src/main/java/com/yfd/platform/data/service/IFishImportService.java create mode 100644 backend/src/main/java/com/yfd/platform/data/service/impl/FishImportServiceImpl.java diff --git a/backend/src/main/java/com/yfd/platform/config/MyMetaObjectHandler.java b/backend/src/main/java/com/yfd/platform/config/MyMetaObjectHandler.java index 45ac60c..3e8a46e 100644 --- a/backend/src/main/java/com/yfd/platform/config/MyMetaObjectHandler.java +++ b/backend/src/main/java/com/yfd/platform/config/MyMetaObjectHandler.java @@ -1,6 +1,7 @@ package com.yfd.platform.config; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import com.yfd.platform.utils.SecurityUtils; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; @@ -13,6 +14,7 @@ import java.util.Date; @Component public class MyMetaObjectHandler implements MetaObjectHandler { + /** * 插入时自动填充 */ @@ -25,6 +27,11 @@ public class MyMetaObjectHandler implements MetaObjectHandler { // 自动填充更新时间 this.strictInsertFill(metaObject, "updatedAt", Date.class, now); + // 自动填充更新时间 + this.strictInsertFill(metaObject, "createdBy", String.class, SecurityUtils.getUserId()); + + // 自动填充更新时间 + this.strictInsertFill(metaObject, "updatedBy", String.class, SecurityUtils.getUserId()); } /** @@ -34,5 +41,7 @@ public class MyMetaObjectHandler implements MetaObjectHandler { public void updateFill(MetaObject metaObject) { // 自动填充更新时间 this.strictUpdateFill(metaObject, "updatedAt", Date.class, new Date()); + // 自动填充更新人 + this.strictInsertFill(metaObject, "updatedBy", String.class, SecurityUtils.getUserId()); } } 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 ea55c4a..4c08de0 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 @@ -5,14 +5,19 @@ import com.yfd.platform.common.DataSourceLoadOptionsBase; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.data.domain.FishDraftData; +import com.yfd.platform.data.domain.FishImportRequest; +import com.yfd.platform.data.domain.FishImportResult; import com.yfd.platform.data.service.IFishDraftDataService; +import com.yfd.platform.data.service.IFishImportService; import com.yfd.platform.utils.KendoUtil; import com.yfd.platform.utils.QgcQueryWrapperUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import java.io.IOException; import java.util.Date; import java.util.List; @@ -29,6 +34,9 @@ public class FishDraftDataController { @Resource private IFishDraftDataService fishDraftDataService; + @Resource + private IFishImportService fishImportService; + // @GetMapping("/page") // @Operation(summary = "分页查询过鱼数据") // public ResponseResult queryPageList( @@ -144,8 +152,6 @@ public class FishDraftDataController { @PostMapping("/add") @Operation(summary = "新增过鱼数据") public ResponseResult add(@RequestBody FishDraftData fishDraftData) { - fishDraftData.setCreatedAt(new Date()); - fishDraftData.setUpdatedAt(new Date()); boolean result = fishDraftDataService.save(fishDraftData); return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败"); } @@ -153,7 +159,6 @@ public class FishDraftDataController { @PostMapping("/update") @Operation(summary = "修改过鱼数据") public ResponseResult update(@RequestBody FishDraftData fishDraftData) { - fishDraftData.setUpdatedAt(new Date()); boolean result = fishDraftDataService.updateById(fishDraftData); return result ? ResponseResult.success("修改成功") : ResponseResult.error("修改失败"); } @@ -164,4 +169,39 @@ public class FishDraftDataController { boolean result = fishDraftDataService.removeById(id); return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败"); } + + @PostMapping("/importExcel") + @Operation(summary = "导入Excel过鱼数据") + public ResponseResult importExcel(@RequestParam("file") MultipartFile file, + @RequestParam(required = false) String importNo, + @RequestParam(required = false) Long uploadUserId) { + if (file == null || file.isEmpty()) { + return ResponseResult.error("请上传文件"); + } + String fileName = file.getOriginalFilename(); + if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) { + return ResponseResult.error("请上传Excel文件(.xlsx或.xls)"); + } + try { + FishImportRequest request = new FishImportRequest(); + request.setFilePath(file.getOriginalFilename()); + request.setImportNo(importNo); + request.setUploadUserId(uploadUserId); + request.setBizType("FISH"); + FishImportResult result = fishImportService.parseAndMapExcel(request, file.getInputStream()); + return ResponseResult.successData(result); + } catch (IOException e) { + return ResponseResult.error("文件读取失败: " + e.getMessage()); + } + } + + @PostMapping("/importExcelFromPath") + @Operation(summary = "从文件路径导入Excel过鱼数据") + public ResponseResult importExcelFromPath(@RequestBody FishImportRequest request) { + if (request.getFilePath() == null || request.getFilePath().isEmpty()) { + return ResponseResult.error("请提供文件路径"); + } + FishImportResult result = fishImportService.parseAndMapExcelFromPath(request); + return ResponseResult.successData(result); + } } \ No newline at end of file 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 383f3ad..7f56961 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 @@ -31,6 +31,11 @@ public class FishDraftData implements Serializable { */ private String stcd; + /** + * 所属基地编码 + */ + private String baseId; + /** * 填报时间 */ @@ -177,6 +182,7 @@ public class FishDraftData implements Serializable { /** * 创建人 */ + @TableField(fill = FieldFill.INSERT) private String createdBy; /** @@ -188,5 +194,6 @@ public class FishDraftData implements Serializable { /** * 更新人 */ + @TableField(fill = FieldFill.INSERT_UPDATE) private String updatedBy; } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/domain/FishImportRequest.java b/backend/src/main/java/com/yfd/platform/data/domain/FishImportRequest.java new file mode 100644 index 0000000..44c909d --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/data/domain/FishImportRequest.java @@ -0,0 +1,20 @@ +package com.yfd.platform.data.domain; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Map; + +@Data +public class FishImportRequest implements Serializable { + + private String filePath; + + private String importNo; + + private String bizType = "FISH"; + + private Long uploadUserId; + + private Map columnMapping; +} \ No newline at end of file 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 new file mode 100644 index 0000000..ec27ddd --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/data/domain/FishImportResult.java @@ -0,0 +1,38 @@ +package com.yfd.platform.data.domain; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class FishImportResult { + + private List successRows; + private List failedRows; + private List unrecognizedFields; + private int totalCount; + private int successCount; + private int failedCount; + private String summary; + + public FishImportResult() { + this.successRows = new ArrayList<>(); + this.failedRows = new ArrayList<>(); + this.unrecognizedFields = new ArrayList<>(); + } + + @Data + public static class FishImportRow { + private int rowIndex; + private FishDraftData data; + private List unrecognizedFields; + private List warnings; + + public FishImportRow(int rowIndex) { + this.rowIndex = rowIndex; + this.unrecognizedFields = new ArrayList<>(); + this.warnings = new ArrayList<>(); + } + } +} \ No newline at end of file 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 1e4e645..fe058ac 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 @@ -83,7 +83,7 @@ public class ImportTask implements Serializable { /** * 上传人ID */ - private Long uploadUserId; + private String uploadUserId; /** * 上传时间 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 new file mode 100644 index 0000000..f85b28d --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/data/service/IFishImportService.java @@ -0,0 +1,31 @@ +package com.yfd.platform.data.service; + +import com.yfd.platform.data.domain.FishImportRequest; +import com.yfd.platform.data.domain.FishImportResult; + +import java.io.InputStream; + +/** + *

+ * 过鱼数据Excel导入服务接口 + *

+ */ +public interface IFishImportService { + + /** + * 解析过鱼数据Excel文件并映射字段 + * + * @param request 导入请求 + * @param inputStream Excel文件输入流 + * @return 解析结果 + */ + FishImportResult parseAndMapExcel(FishImportRequest request, InputStream inputStream); + + /** + * 解析过鱼数据Excel文件(从文件路径) + * + * @param request 导入请求 + * @return 解析结果 + */ + FishImportResult parseAndMapExcelFromPath(FishImportRequest request); +} \ 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 new file mode 100644 index 0000000..1030ec7 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/data/service/impl/FishImportServiceImpl.java @@ -0,0 +1,403 @@ +package com.yfd.platform.data.service.impl; + +import com.yfd.platform.data.domain.FishDraftData; +import com.yfd.platform.data.domain.FishImportRequest; +import com.yfd.platform.data.domain.FishImportResult; +import com.yfd.platform.data.service.IFishImportService; +import com.yfd.platform.env.domain.SdEngInfoBH; +import com.yfd.platform.env.domain.SdHydrobase; +import com.yfd.platform.env.mapper.SdEngInfoBHMapper; +import com.yfd.platform.env.mapper.SdHydrobaseMapper; +import jakarta.annotation.Resource; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class FishImportServiceImpl implements IFishImportService { + + @Resource + private SdEngInfoBHMapper engInfoBHMapper; + + @Resource + private SdHydrobaseMapper hydrobaseMapper; + + private static final Map EXCEL_COLUMN_MAPPING = new LinkedHashMap<>(); + + private static final Map STATION_NAME_CACHE = new HashMap<>(); + private static final Map STATION_CODE_CACHE = new HashMap<>(); + private static final Map BASE_NAME_CACHE = new HashMap<>(); + private static final Map BASE_CODE_CACHE = new HashMap<>(); + + static { + EXCEL_COLUMN_MAPPING.put("电站名称", "stcd"); + EXCEL_COLUMN_MAPPING.put("基地名称", "baseId"); + EXCEL_COLUMN_MAPPING.put("数据时间", "tm"); + EXCEL_COLUMN_MAPPING.put("鱼类", "ftp"); + EXCEL_COLUMN_MAPPING.put("鱼类全长", "fsz"); + EXCEL_COLUMN_MAPPING.put("过鱼数量", "fcnt"); + EXCEL_COLUMN_MAPPING.put("平均体重", "fwet"); + EXCEL_COLUMN_MAPPING.put("开始日期", "strdt"); + EXCEL_COLUMN_MAPPING.put("结束日期", "enddt"); + EXCEL_COLUMN_MAPPING.put("游向", "direction"); + EXCEL_COLUMN_MAPPING.put("年份", "yr"); + EXCEL_COLUMN_MAPPING.put("月份", "mouth"); + EXCEL_COLUMN_MAPPING.put("过鱼视频文件路径", "vdpth"); + EXCEL_COLUMN_MAPPING.put("图片文件路径", "picpth"); + EXCEL_COLUMN_MAPPING.put("是否鱼苗", "isfs"); + EXCEL_COLUMN_MAPPING.put("数据来源", "sourceType"); + } + + @Override + public FishImportResult parseAndMapExcel(FishImportRequest request, InputStream inputStream) { + FishImportResult result = new FishImportResult(); + + try (Workbook workbook = new XSSFWorkbook(inputStream)) { + Sheet sheet = workbook.getSheetAt(0); + return parseSheet(sheet, result); + } catch (IOException e) { + result.setSummary("Excel文件解析失败: " + e.getMessage()); + return result; + } + } + + @Override + public FishImportResult parseAndMapExcelFromPath(FishImportRequest request) { + FishImportResult result = new FishImportResult(); + + try (InputStream inputStream = request.getFilePath().startsWith("http") + ? new java.net.URL(request.getFilePath()).openStream() + : new java.io.FileInputStream(request.getFilePath())) { + return parseAndMapExcel(request, inputStream); + } catch (IOException e) { + result.setSummary("读取文件失败: " + e.getMessage()); + return result; + } + } + + private FishImportResult parseSheet(Sheet sheet, FishImportResult result) { + loadStationAndBaseCache(); + + Row headerRow = sheet.getRow(0); + if (headerRow == null) { + result.setSummary("Excel文件没有表头"); + return result; + } + + Map columnIndexMap = new HashMap<>(); + List unrecognizedHeaders = new ArrayList<>(); + + for (int i = 0; i < headerRow.getLastCellNum(); i++) { + Cell cell = headerRow.getCell(i); + if (cell != null) { + String headerName = getCellStringValue(cell).trim(); + String mappedField = EXCEL_COLUMN_MAPPING.get(headerName); + if (mappedField != null) { + columnIndexMap.put(i, mappedField); + } else { + unrecognizedHeaders.add(headerName); + } + } + } + + if (!unrecognizedHeaders.isEmpty()) { + result.setUnrecognizedFields(unrecognizedHeaders); + } + + int totalRows = sheet.getLastRowNum(); + result.setTotalCount(totalRows); + + for (int i = 1; i <= totalRows; i++) { + Row row = sheet.getRow(i); + if (row == null || isRowEmpty(row)) { + continue; + } + + FishImportResult.FishImportRow importRow = parseRow(row, columnIndexMap, i); + if (importRow.getData() != null && importRow.getUnrecognizedFields().isEmpty()) { + result.getSuccessRows().add(importRow); + result.setSuccessCount(result.getSuccessCount() + 1); + } else { + result.getFailedRows().add(importRow); + result.setFailedCount(result.getFailedCount() + 1); + } + } + + result.setSummary(String.format("共解析%d条数据,成功%d条,失败%d条,未识别字段:%s", + result.getTotalCount(), result.getSuccessCount(), result.getFailedCount(), + unrecognizedHeaders.isEmpty() ? "无" : String.join(", ", unrecognizedHeaders))); + + return result; + } + + private FishImportResult.FishImportRow parseRow(Row row, Map columnIndexMap, int rowIndex) { + FishImportResult.FishImportRow importRow = new FishImportResult.FishImportRow(rowIndex); + FishDraftData data = new FishDraftData(); + data.setId(UUID.randomUUID().toString()); + List unrecognizedFields = new ArrayList<>(); + + for (Map.Entry entry : columnIndexMap.entrySet()) { + Integer columnIndex = entry.getKey(); + String fieldName = entry.getValue(); + Cell cell = row.getCell(columnIndex); + String cellValue = getCellStringValue(cell); + + if (!StringUtils.hasText(cellValue)) { + continue; + } + + try { + switch (fieldName) { + case "stcd": + String stcd = resolveStationCode(cellValue.trim()); + if (stcd == null) { + importRow.getWarnings().add("无法识别的电站: " + cellValue); + } + data.setStcd(stcd); + break; + case "baseId": + String baseId = resolveBaseCode(cellValue.trim()); + if (baseId == null) { + importRow.getWarnings().add("无法识别的基地: " + cellValue); + } + data.setBaseId(baseId); + break; + case "tm": + data.setTm(parseDate(cellValue)); + break; + case "ftp": + data.setFtp(cellValue.trim()); + break; + case "fsz": + data.setFsz(cellValue.trim()); + break; + case "fcnt": + data.setFcnt(parseInteger(cellValue)); + break; + case "fwet": + data.setFwet(cellValue.trim()); + break; + case "strdt": + data.setStrdt(parseDate(cellValue)); + break; + case "enddt": + data.setEnddt(parseDate(cellValue)); + break; + case "direction": + data.setDirection(parseDirection(cellValue.trim())); + break; + case "yr": + data.setYr(parseInteger(cellValue)); + break; + case "mouth": + data.setMouth(parseInteger(cellValue)); + break; + case "vdpth": + data.setVdpth(cellValue.trim()); + break; + case "picpth": + data.setPicpth(cellValue.trim()); + break; + case "isfs": + data.setIsfs(parseIsfs(cellValue)); + break; + case "sourceType": + data.setSourceType(parseSourceType(cellValue.trim())); + break; + default: + break; + } + } catch (Exception e) { + importRow.getWarnings().add("字段[" + fieldName + "]解析异常: " + e.getMessage()); + } + } + + importRow.setData(data); + importRow.setUnrecognizedFields(unrecognizedFields); + return importRow; + } + + private void loadStationAndBaseCache() { + if (STATION_NAME_CACHE.isEmpty()) { + List stationList = engInfoBHMapper.selectList(null); + for (SdEngInfoBH station : stationList) { + if (StringUtils.hasText(station.getEnnm())) { + STATION_NAME_CACHE.put(station.getEnnm().trim().toLowerCase(), station.getStcd()); + } + if (StringUtils.hasText(station.getStcd())) { + STATION_CODE_CACHE.put(station.getStcd().trim().toLowerCase(), station.getStcd()); + } + } + } + + if (BASE_NAME_CACHE.isEmpty()) { + List baseList = hydrobaseMapper.selectList(null); + for (SdHydrobase base : baseList) { + if (StringUtils.hasText(base.getBasename())) { + BASE_NAME_CACHE.put(base.getBasename().trim().toLowerCase(), base.getBaseid()); + } + if (StringUtils.hasText(base.getBaseid())) { + BASE_CODE_CACHE.put(base.getBaseid().trim().toLowerCase(), base.getBaseid()); + } + } + } + } + + private String resolveStationCode(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) || lowerName.contains(entry.getKey())) { + return entry.getValue(); + } + } + return null; + } + + private String resolveBaseCode(String baseName) { + if (baseName == null) { + return null; + } + String lowerName = baseName.toLowerCase().trim(); + if (BASE_NAME_CACHE.containsKey(lowerName)) { + return BASE_NAME_CACHE.get(lowerName); + } + for (Map.Entry entry : BASE_NAME_CACHE.entrySet()) { + if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) { + return entry.getValue(); + } + } + return null; + } + + private String getCellStringValue(Cell cell) { + if (cell == null) { + return ""; + } + switch (cell.getCellType()) { + case STRING: + return cell.getStringCellValue(); + case NUMERIC: + if (DateUtil.isCellDateFormatted(cell)) { + return cell.getLocalDateTimeCellValue().toString(); + } + return String.valueOf((long) cell.getNumericCellValue()); + case BOOLEAN: + return String.valueOf(cell.getBooleanCellValue()); + case FORMULA: + try { + return cell.getStringCellValue(); + } catch (Exception e) { + return String.valueOf(cell.getNumericCellValue()); + } + default: + return ""; + } + } + + private boolean isRowEmpty(Row row) { + for (int i = 0; i < row.getLastCellNum(); i++) { + Cell cell = row.getCell(i); + if (cell != null && StringUtils.hasText(getCellStringValue(cell))) { + return false; + } + } + return true; + } + + private Date parseDate(String dateStr) { + if (!StringUtils.hasText(dateStr)) { + return null; + } + String[] patterns = { + "yyyy-MM-dd HH:mm:ss", + "yyyy-MM-dd", + "yyyy/MM/dd", + "yyyy.MM.dd", + "yyyyMMdd" + }; + for (String pattern : patterns) { + try { + SimpleDateFormat sdf = new SimpleDateFormat(pattern); + sdf.setLenient(false); + return sdf.parse(dateStr); + } catch (ParseException ignored) { + } + } + return null; + } + + private Integer parseInteger(String value) { + if (!StringUtils.hasText(value)) { + return null; + } + try { + return Integer.parseInt(value.trim()); + } catch (NumberFormatException e) { + try { + return (int) Double.parseDouble(value.trim()); + } catch (NumberFormatException ex) { + return null; + } + } + } + + private String parseDirection(String direction) { + if (!StringUtils.hasText(direction)) { + return null; + } + String d = direction.toLowerCase(); + if (d.contains("上行") || d.contains("up")) { + return "上行"; + } else if (d.contains("下行") || d.contains("down")) { + return "下行"; + } else if (d.contains("折返")) { + if (d.contains("上行")) { + return "上行折返"; + } else if (d.contains("下行")) { + return "下行折返"; + } + return "折返"; + } + return direction; + } + + private Integer parseIsfs(String value) { + if (!StringUtils.hasText(value)) { + return 0; + } + String v = value.toLowerCase().trim(); + if (v.equals("1") || v.equals("是") || v.equals("yes") || v.equals("鱼苗")) { + return 1; + } + return 0; + } + + private String parseSourceType(String value) { + if (!StringUtils.hasText(value)) { + return "IMPORT"; + } + String v = value.toLowerCase(); + if (v.contains("手工") || v.contains("manual") || v.contains("录入")) { + return "MANUAL"; + } else if (v.contains("自动") || v.contains("auto")) { + return "AUTO"; + } else if (v.contains("导入") || v.contains("import")) { + return "IMPORT"; + } + return "IMPORT"; + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/utils/SecurityUtils.java b/backend/src/main/java/com/yfd/platform/utils/SecurityUtils.java index 9df23cd..4e8f518 100644 --- a/backend/src/main/java/com/yfd/platform/utils/SecurityUtils.java +++ b/backend/src/main/java/com/yfd/platform/utils/SecurityUtils.java @@ -71,6 +71,16 @@ public class SecurityUtils { return new JSONObject(new JSONObject(userDetails).get("user")).get("id", Long.class); } + /** + * 获取系统用户ID + * @return 系统用户ID + */ + public static String getUserId() { + UserDetails userDetails = getCurrentUser(); + return new JSONObject(new JSONObject(userDetails).get("user")).get("id", String.class); + } + + /** * 获取当前用户的数据权限 * @return / From d040297adb6a6d9d4333dcf2207692e92b4c0bd3 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 22 Apr 2026 13:45:53 +0800 Subject: [PATCH 02/13] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E8=BF=87?= =?UTF-8?q?=E9=B1=BC=E8=AE=BE=E6=96=BD=E5=A1=AB=E6=8A=A5=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yfd/platform/config/SwaggerConfig.java | 2 ++ .../controller/FishDraftDataController.java | 21 ++++++++++++------- .../platform/data/domain/FishDraftData.java | 3 ++- .../data/mapper/FishDraftDataMapper.java | 2 +- .../data/service/IFishDraftDataService.java | 12 +++++------ .../impl/FishDraftDataServiceImpl.java | 14 ++++++------- 6 files changed, 32 insertions(+), 22 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java index 9dc0f85..212db9b 100644 --- a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java @@ -54,4 +54,6 @@ public class SwaggerConfig { .packagesToScan("com.yfd.platform.env.controller") .build(); } + + } 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 4c08de0..cb32886 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 @@ -78,7 +78,7 @@ public class FishDraftDataController { @GetMapping("/getByApprovalId") @Operation(summary = "根据审批批次ID查询") - public ResponseResult getByApprovalId(@RequestParam Long approvalId) { + public ResponseResult getByApprovalId(@RequestParam String approvalId) { List list = fishDraftDataService.getByApprovalId(approvalId); return ResponseResult.successData(list); } @@ -113,7 +113,7 @@ public class FishDraftDataController { @PostMapping("/removeDraft") @Operation(summary = "删除草稿(软删除)") - public ResponseResult removeDraft(@RequestParam Long id, + public ResponseResult removeDraft(@RequestParam String id, @RequestParam String operatorId) { boolean result = fishDraftDataService.removeDraft(id, operatorId); return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败"); @@ -121,7 +121,7 @@ public class FishDraftDataController { @PostMapping("/submitDraft") @Operation(summary = "提交草稿") - public ResponseResult submitDraft(@RequestParam Long id, + public ResponseResult submitDraft(@RequestParam String id, @RequestParam String operatorId) { boolean result = fishDraftDataService.submitDraft(id, operatorId); return result ? ResponseResult.success("提交成功") : ResponseResult.error("提交失败"); @@ -129,7 +129,7 @@ public class FishDraftDataController { @PostMapping("/submitDrafts") @Operation(summary = "批量提交草稿") - public ResponseResult submitDrafts(@RequestBody List ids, + public ResponseResult submitDrafts(@RequestBody List ids, @RequestParam String operatorId) { boolean result = fishDraftDataService.submitDrafts(ids, operatorId); return result ? ResponseResult.success("提交成功") : ResponseResult.error("提交失败"); @@ -137,14 +137,14 @@ public class FishDraftDataController { @PostMapping("/lockDraft") @Operation(summary = "锁定草稿") - public ResponseResult lockDraft(@RequestParam Long id) { + public ResponseResult lockDraft(@RequestParam String id) { boolean result = fishDraftDataService.lockDraft(id); return result ? ResponseResult.success("锁定成功") : ResponseResult.error("锁定失败"); } @PostMapping("/unlockDraft") @Operation(summary = "解锁草稿") - public ResponseResult unlockDraft(@RequestParam Long id) { + public ResponseResult unlockDraft(@RequestParam String id) { boolean result = fishDraftDataService.unlockDraft(id); return result ? ResponseResult.success("解锁成功") : ResponseResult.error("解锁失败"); } @@ -165,11 +165,18 @@ public class FishDraftDataController { @PostMapping("/delete") @Operation(summary = "删除过鱼数据") - public ResponseResult delete(@RequestParam Long id) { + public ResponseResult delete(@RequestParam String id) { boolean result = fishDraftDataService.removeById(id); return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败"); } + @PostMapping("/batchDelete") + @Operation(summary = "批量删除过鱼数据") + public ResponseResult batchDelete(@RequestBody List ids) { + boolean result = fishDraftDataService.removeByIds(ids); + return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败"); + } + @PostMapping("/importExcel") @Operation(summary = "导入Excel过鱼数据") public ResponseResult importExcel(@RequestParam("file") MultipartFile file, 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 7f56961..2de542d 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 @@ -34,6 +34,7 @@ public class FishDraftData implements Serializable { /** * 所属基地编码 */ + @TableField(exist = false) private String baseId; /** @@ -130,7 +131,7 @@ public class FishDraftData implements Serializable { /** * 水温 */ - @TableField(exist = false) +// @TableField(exist = false) private BigDecimal wt; diff --git a/backend/src/main/java/com/yfd/platform/data/mapper/FishDraftDataMapper.java b/backend/src/main/java/com/yfd/platform/data/mapper/FishDraftDataMapper.java index 4acbbb2..a83ccad 100644 --- a/backend/src/main/java/com/yfd/platform/data/mapper/FishDraftDataMapper.java +++ b/backend/src/main/java/com/yfd/platform/data/mapper/FishDraftDataMapper.java @@ -18,7 +18,7 @@ public interface FishDraftDataMapper extends BaseMapper { * 根据审批批次ID查询草稿数据 */ @Select("SELECT * FROM FISH_DRAFT_DATA WHERE APPROVAL_ID = #{approvalId} ORDER BY TM DESC") - List selectByApprovalId(@Param("approvalId") Long approvalId); + List selectByApprovalId(@Param("approvalId") String approvalId); /** * 根据状态查询草稿数据 diff --git a/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java b/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java index 00f4a47..a0ece5f 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java +++ b/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java @@ -21,7 +21,7 @@ public interface IFishDraftDataService extends IService { /** * 根据审批批次ID查询 */ - List getByApprovalId(Long approvalId); + List getByApprovalId(String approvalId); /** * 根据状态查询 @@ -46,25 +46,25 @@ public interface IFishDraftDataService extends IService { /** * 删除草稿(软删除) */ - boolean removeDraft(Long id, String operatorId); + boolean removeDraft(String id, String operatorId); /** * 提交草稿 */ - boolean submitDraft(Long id, String operatorId); + boolean submitDraft(String id, String operatorId); /** * 批量提交草稿 */ - boolean submitDrafts(List ids, String operatorId); + boolean submitDrafts(List ids, String operatorId); /** * 锁定草稿 */ - boolean lockDraft(Long id); + boolean lockDraft(String id); /** * 解锁草稿 */ - boolean unlockDraft(Long id); + boolean unlockDraft(String id); } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java index ac522ed..736838a 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java @@ -44,7 +44,7 @@ public class FishDraftDataServiceImpl extends ServiceImpl getByApprovalId(Long approvalId) { + public List getByApprovalId(String approvalId) { return fishDraftDataMapper.selectByApprovalId(approvalId); } @@ -83,7 +83,7 @@ public class FishDraftDataServiceImpl extends ServiceImpl ids, String operatorId) { - for (Long id : ids) { + public boolean submitDrafts(List ids, String operatorId) { + for (String id : ids) { FishDraftData fishDraftData = this.getById(id); if (fishDraftData != null && fishDraftData.getLockFlag() == 0) { fishDraftData.setStatus("SUBMITTED"); @@ -125,7 +125,7 @@ public class FishDraftDataServiceImpl extends ServiceImpl Date: Wed, 22 Apr 2026 15:44:20 +0800 Subject: [PATCH 03/13] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=AD=97?= =?UTF-8?q?=E5=85=B8=E8=8E=B7=E5=8F=96=E5=AD=97=E5=85=B8=E9=A1=B9=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SysDictionaryController.java | 19 +++++++++++++++++++ .../service/ISysDictionaryItemsService.java | 7 +++++++ .../system/service/ISysDictionaryService.java | 7 +++++++ .../impl/SysDictionaryItemsServiceImpl.java | 7 +++++++ .../impl/SysDictionaryServiceImpl.java | 7 +++++++ 5 files changed, 47 insertions(+) diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SysDictionaryController.java b/backend/src/main/java/com/yfd/platform/system/controller/SysDictionaryController.java index 70a5fdf..b3db106 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/SysDictionaryController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/SysDictionaryController.java @@ -4,8 +4,10 @@ import cn.hutool.core.util.StrUtil; import com.yfd.platform.annotation.Log; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.system.domain.SysDictionary; +import com.yfd.platform.system.domain.SysDictionaryItems; import com.yfd.platform.system.mapper.SysDictionaryItemsMapper; import com.yfd.platform.system.service.ISysDictionaryService; +import com.yfd.platform.system.service.ISysDictionaryItemsService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.util.StringUtils; @@ -31,6 +33,9 @@ public class SysDictionaryController { @Resource private ISysDictionaryService sysDictionaryService; + @Resource + private ISysDictionaryItemsService sysDictionaryItemsService; + /********************************** * 用途说明: 获取数据字典列表 * 参数说明 dictType 字典类型 @@ -139,4 +144,18 @@ public class SysDictionaryController { } + @GetMapping("/getDictItemsByCode") + @Operation(summary = "根据字典编号查询字典项列表") + public ResponseResult getDictItemsByCode(@RequestParam String dictCode) { + if (StrUtil.isBlank(dictCode)) { + return ResponseResult.error("字典编号不能为空"); + } + SysDictionary sysDictionary = sysDictionaryService.getByDictCode(dictCode); + if (sysDictionary == null) { + return ResponseResult.error("未找到对应的字典"); + } + List items = sysDictionaryItemsService.listByDictId(sysDictionary.getId()); + return ResponseResult.successData(items); + } + } diff --git a/backend/src/main/java/com/yfd/platform/system/service/ISysDictionaryItemsService.java b/backend/src/main/java/com/yfd/platform/system/service/ISysDictionaryItemsService.java index 32f9b8f..bf44c31 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/ISysDictionaryItemsService.java +++ b/backend/src/main/java/com/yfd/platform/system/service/ISysDictionaryItemsService.java @@ -44,4 +44,11 @@ public interface ISysDictionaryItemsService extends IService * 返回值说明: com.yfd.platform.config.ResponseResult 返回导出成功或失败 ***********************************/ void exportExcel(List records, HttpServletResponse response); + + /********************************** + * 用途说明: 根据字典ID查询字典项列表 + * 参数说明 dictId 字典ID + * 返回值说明: List 字典项列表 + ***********************************/ + List listByDictId(String dictId); } diff --git a/backend/src/main/java/com/yfd/platform/system/service/ISysDictionaryService.java b/backend/src/main/java/com/yfd/platform/system/service/ISysDictionaryService.java index f3a4990..724e240 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/ISysDictionaryService.java +++ b/backend/src/main/java/com/yfd/platform/system/service/ISysDictionaryService.java @@ -42,4 +42,11 @@ public interface ISysDictionaryService extends IService { * 返回值说明: com.yfd.platform.config.ResponseResult 返回拖动成功或者失败 ***********************************/ boolean changeDictOrder(String fromID, String toID); + + /********************************** + * 用途说明: 根据字典编号查询字典 + * 参数说明 dictCode 字典编号 + * 返回值说明: SysDictionary 字典对象 + ***********************************/ + SysDictionary getByDictCode(String dictCode); } diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/SysDictionaryItemsServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/SysDictionaryItemsServiceImpl.java index 26a30ab..548950b 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/SysDictionaryItemsServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/SysDictionaryItemsServiceImpl.java @@ -120,4 +120,11 @@ public class SysDictionaryItemsServiceImpl extends ServiceImpl listByDictId(String dictId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysDictionaryItems::getDictId, dictId).orderByAsc(SysDictionaryItems::getOrderNo); + return sysDictionaryItemsMapper.selectList(queryWrapper); + } + } diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/SysDictionaryServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/SysDictionaryServiceImpl.java index 58508b3..f3e8130 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/SysDictionaryServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/SysDictionaryServiceImpl.java @@ -111,4 +111,11 @@ public class SysDictionaryServiceImpl extends ServiceImpl queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysDictionary::getDictCode, dictCode); + return sysDictionaryMapper.selectOne(queryWrapper); + } + } From bac8bd9b25d06d5953eed61bb2c75120b3efbce7 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 22 Apr 2026 15:49:09 +0800 Subject: [PATCH 04/13] =?UTF-8?q?fix:=20=E5=AF=BC=E5=85=A5=E8=BF=87?= =?UTF-8?q?=E9=B1=BC=E6=95=B0=E6=8D=AE=E5=88=9D=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FishDraftDataController.java | 99 +++++--- .../data/domain/FishImportRequest.java | 2 +- .../data/domain/FishImportResult.java | 9 + .../data/mapper/ImportTaskMapper.java | 12 +- .../data/service/IFishImportService.java | 16 +- .../data/service/IFishZipImportService.java | 40 ++++ .../data/service/IImportTaskService.java | 15 ++ .../service/impl/FishImportServiceImpl.java | 39 ++++ .../service/impl/ImportTaskServiceImpl.java | 34 +++ .../yfd/platform/data/utils/ZipFileUtil.java | 219 ++++++++++++++++++ .../src/main/resources/application-devtw.yml | 4 +- 11 files changed, 441 insertions(+), 48 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/data/service/IFishZipImportService.java create mode 100644 backend/src/main/java/com/yfd/platform/data/utils/ZipFileUtil.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 cb32886..ef26c1a 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 @@ -7,8 +7,10 @@ import com.yfd.platform.config.ResponseResult; import com.yfd.platform.data.domain.FishDraftData; import com.yfd.platform.data.domain.FishImportRequest; import com.yfd.platform.data.domain.FishImportResult; +import com.yfd.platform.data.domain.ImportTask; import com.yfd.platform.data.service.IFishDraftDataService; import com.yfd.platform.data.service.IFishImportService; +import com.yfd.platform.data.service.IImportTaskService; import com.yfd.platform.utils.KendoUtil; import com.yfd.platform.utils.QgcQueryWrapperUtil; import io.swagger.v3.oas.annotations.Operation; @@ -20,6 +22,7 @@ import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.Date; import java.util.List; +import java.util.UUID; /** *

@@ -37,18 +40,8 @@ public class FishDraftDataController { @Resource private IFishImportService fishImportService; -// @GetMapping("/page") -// @Operation(summary = "分页查询过鱼数据") -// public ResponseResult queryPageList( -// @RequestParam(defaultValue = "1") Integer current, -// @RequestParam(defaultValue = "10") Integer size, -// @RequestParam(required = false) String stcd, -// @RequestParam(required = false) String status, -// @RequestParam(required = false) String ftp) { -// Page page = new Page<>(current, size); -// Page result = fishDraftDataService.queryPageList(page, stcd, status, ftp); -// return ResponseResult.successData(result); -// } + @Resource + private IImportTaskService importTaskService; @PostMapping("/page") @Operation(summary = "分页查询过鱼数据") @@ -71,7 +64,7 @@ public class FishDraftDataController { @GetMapping("/getById") @Operation(summary = "根据ID查询") - public ResponseResult getById(@RequestParam Long id) { + public ResponseResult getById(@RequestParam String id) { FishDraftData fishDraftData = fishDraftDataService.getById(id); return ResponseResult.successData(fishDraftData); } @@ -177,38 +170,82 @@ public class FishDraftDataController { return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败"); } - @PostMapping("/importExcel") - @Operation(summary = "导入Excel过鱼数据") - public ResponseResult importExcel(@RequestParam("file") MultipartFile file, - @RequestParam(required = false) String importNo, - @RequestParam(required = false) Long uploadUserId) { + @PostMapping("/importZip") + @Operation(summary = "导入ZIP过鱼数据(每个用户同时只能进行一次导入)") + public ResponseResult importZip(@RequestParam("file") MultipartFile file, + @RequestParam String uploadUserId) { if (file == null || file.isEmpty()) { return ResponseResult.error("请上传文件"); } String fileName = file.getOriginalFilename(); - if (fileName == null || (!fileName.endsWith(".xlsx") && !fileName.endsWith(".xls"))) { - return ResponseResult.error("请上传Excel文件(.xlsx或.xls)"); + if (fileName == null || (!fileName.endsWith(".zip"))) { + return ResponseResult.error("请上传ZIP文件(.zip)"); } + + if (importTaskService.hasImportingTask(uploadUserId)) { + return ResponseResult.error("您有正在进行的导入任务,请等待完成后重试"); + } + + String importNo = "IMP" + System.currentTimeMillis(); + String taskId = UUID.randomUUID().toString(); + try { + ImportTask task = new ImportTask(); + task.setId(taskId); + task.setImportNo(importNo); + task.setBizType("FISH"); + task.setFileName(fileName); + task.setFileSize(file.getSize()); + task.setStatus("UPLOADED"); + task.setUploadUserId(uploadUserId); + task.setUploadTime(new Date()); + importTaskService.save(task); + FishImportRequest request = new FishImportRequest(); - request.setFilePath(file.getOriginalFilename()); request.setImportNo(importNo); request.setUploadUserId(uploadUserId); request.setBizType("FISH"); - FishImportResult result = fishImportService.parseAndMapExcel(request, file.getInputStream()); + + FishImportResult result = fishImportService.parseAndMapZip(file, uploadUserId); + + importTaskService.updateStatus(taskId, "VALIDATED", null); + importTaskService.updateProgress(taskId, result.getTotalCount(), result.getSuccessCount(), result.getFailedCount()); + return ResponseResult.successData(result); - } catch (IOException e) { - return ResponseResult.error("文件读取失败: " + e.getMessage()); + + } catch (Exception e) { + importTaskService.markFailed(taskId, "导入失败: " + e.getMessage()); + return ResponseResult.error("导入失败: " + e.getMessage()); } } - @PostMapping("/importExcelFromPath") - @Operation(summary = "从文件路径导入Excel过鱼数据") - public ResponseResult importExcelFromPath(@RequestBody FishImportRequest request) { - if (request.getFilePath() == null || request.getFilePath().isEmpty()) { - return ResponseResult.error("请提供文件路径"); + @PostMapping("/cancelImport") + @Operation(summary = "取消导入任务") + public ResponseResult cancelImport(@RequestParam String taskId, + @RequestParam String operatorId) { + boolean result = importTaskService.cancelTask(taskId, operatorId); + return result ? ResponseResult.success("取消成功") : ResponseResult.error("取消失败"); + } + + @GetMapping("/checkImportStatus") + @Operation(summary = "检查用户导入状态") + public ResponseResult checkImportStatus(@RequestParam String uploadUserId) { + boolean hasTask = importTaskService.hasImportingTask(uploadUserId); + ImportTask currentTask = importTaskService.getCurrentTaskByUserId(uploadUserId); + return ResponseResult.successData(java.util.Map.of( + "hasImportingTask", hasTask, + "currentTask", currentTask + )); + } + + @PostMapping("/cleanupTemp") + @Operation(summary = "清理临时文件") + public ResponseResult cleanupTemp(@RequestParam String tempDir) { + try { + com.yfd.platform.data.utils.ZipFileUtil.cleanupTempDir(tempDir); + return ResponseResult.success("清理成功"); + } catch (Exception e) { + return ResponseResult.error("清理失败: " + e.getMessage()); } - FishImportResult result = fishImportService.parseAndMapExcelFromPath(request); - return ResponseResult.successData(result); } } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/domain/FishImportRequest.java b/backend/src/main/java/com/yfd/platform/data/domain/FishImportRequest.java index 44c909d..3d063da 100644 --- a/backend/src/main/java/com/yfd/platform/data/domain/FishImportRequest.java +++ b/backend/src/main/java/com/yfd/platform/data/domain/FishImportRequest.java @@ -14,7 +14,7 @@ public class FishImportRequest implements Serializable { private String bizType = "FISH"; - private Long uploadUserId; + private String uploadUserId; private Map columnMapping; } \ No newline at end of file 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 ec27ddd..6a5ecaa 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 @@ -3,7 +3,9 @@ package com.yfd.platform.data.domain; import lombok.Data; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; @Data public class FishImportResult { @@ -11,6 +13,11 @@ public class FishImportResult { private List successRows; private List failedRows; private List unrecognizedFields; + private Map imageFiles; + private Map videoFiles; + private String tempDir; + private String excelFileName; + private String excelFilePath; private int totalCount; private int successCount; private int failedCount; @@ -20,6 +27,8 @@ public class FishImportResult { this.successRows = new ArrayList<>(); this.failedRows = new ArrayList<>(); this.unrecognizedFields = new ArrayList<>(); + this.imageFiles = new LinkedHashMap<>(); + this.videoFiles = new LinkedHashMap<>(); } @Data 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 dbc74bc..5a45a82 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 @@ -36,7 +36,17 @@ public interface ImportTaskMapper extends BaseMapper { * 根据上传人查询 */ @Select("SELECT * FROM IMPORT_TASK WHERE UPLOAD_USER_ID = #{uploadUserId} ORDER BY CREATED_AT DESC") - List selectByUploadUserId(@Param("uploadUserId") Long uploadUserId); + List selectByUploadUserId(@Param("uploadUserId") String uploadUserId); + + @Select("") + List selectByUserIdAndStatuses(@Param("uploadUserId") String uploadUserId, + @Param("statuses") List statuses); /** * 查询过期的任务 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 f85b28d..7a597ba 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 @@ -2,6 +2,7 @@ package com.yfd.platform.data.service; import com.yfd.platform.data.domain.FishImportRequest; import com.yfd.platform.data.domain.FishImportResult; +import org.springframework.web.multipart.MultipartFile; import java.io.InputStream; @@ -12,20 +13,9 @@ import java.io.InputStream; */ public interface IFishImportService { - /** - * 解析过鱼数据Excel文件并映射字段 - * - * @param request 导入请求 - * @param inputStream Excel文件输入流 - * @return 解析结果 - */ FishImportResult parseAndMapExcel(FishImportRequest request, InputStream inputStream); - /** - * 解析过鱼数据Excel文件(从文件路径) - * - * @param request 导入请求 - * @return 解析结果 - */ FishImportResult parseAndMapExcelFromPath(FishImportRequest request); + + FishImportResult parseAndMapZip(MultipartFile file, String uploadUserId); } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/service/IFishZipImportService.java b/backend/src/main/java/com/yfd/platform/data/service/IFishZipImportService.java new file mode 100644 index 0000000..a853439 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/data/service/IFishZipImportService.java @@ -0,0 +1,40 @@ +package com.yfd.platform.data.service; + +import com.yfd.platform.data.domain.FishImportResult; + +import java.io.InputStream; + +/** + *

+ * 过鱼数据ZIP导入服务接口 + *

+ */ +public interface IFishZipImportService { + + /** + * 解析过鱼数据ZIP文件并映射字段 + * + * @param importTaskId 导入任务ID + * @param inputStream ZIP文件输入流 + * @param uploadUserId 上传用户ID + * @return 解析结果 + */ + FishImportResult parseAndMapZip(String importTaskId, InputStream inputStream, String uploadUserId); + + /** + * 检查用户是否有正在进行的导入任务 + * + * @param uploadUserId 上传用户ID + * @return true表示有任务在进行,false表示可以开始新任务 + */ + boolean hasImportingTask(String uploadUserId); + + /** + * 取消导入任务 + * + * @param importTaskId 任务ID + * @param operatorId 操作人ID + * @return 是否成功 + */ + boolean cancelImportTask(String importTaskId, String operatorId); +} \ 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 7b305bd..5879bd5 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 @@ -62,4 +62,19 @@ public interface IImportTaskService extends IService { * 删除过期任务 */ boolean deleteExpiredTasks(); + + /** + * 检查用户是否有正在进行的导入任务 + */ + boolean hasImportingTask(String uploadUserId); + + /** + * 取消导入任务 + */ + boolean cancelTask(String taskId, String operatorId); + + /** + * 获取用户当前正在进行的导入任务 + */ + ImportTask getCurrentTaskByUserId(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 1030ec7..b37b1b1 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 @@ -4,6 +4,7 @@ import com.yfd.platform.data.domain.FishDraftData; import com.yfd.platform.data.domain.FishImportRequest; import com.yfd.platform.data.domain.FishImportResult; import com.yfd.platform.data.service.IFishImportService; +import com.yfd.platform.data.utils.ZipFileUtil; import com.yfd.platform.env.domain.SdEngInfoBH; import com.yfd.platform.env.domain.SdHydrobase; import com.yfd.platform.env.mapper.SdEngInfoBHMapper; @@ -13,7 +14,10 @@ import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.text.ParseException; @@ -400,4 +404,39 @@ public class FishImportServiceImpl implements IFishImportService { } return "IMPORT"; } + + @Override + public FishImportResult parseAndMapZip(MultipartFile file, String uploadUserId) { + FishImportResult result = new FishImportResult(); + + try { + ZipFileUtil.ZipContent zipContent = ZipFileUtil.extractZipToTemp(file); + + if (zipContent.excelFilePath == null) { + result.setSummary("ZIP文件中未找到Excel文件"); + ZipFileUtil.cleanupTempDir(zipContent.tempDir); + return result; + } + + try (Workbook workbook = new XSSFWorkbook(new FileInputStream(zipContent.excelFilePath))) { + Sheet sheet = workbook.getSheetAt(0); + result = parseSheet(sheet, result); + } + + result.setImageFiles(zipContent.images); + result.setVideoFiles(zipContent.videos); + result.setTempDir(zipContent.tempDir); + result.setExcelFileName(zipContent.excelFileName); + result.setExcelFilePath(zipContent.excelFilePath); + + result.setSummary(result.getSummary() + String.format("\nZIP内容: 发现%d张图片, %d个视频, 临时目录: %s", + zipContent.images.size(), zipContent.videos.size(), zipContent.tempDir)); + + return result; + + } catch (Exception e) { + result.setSummary("ZIP文件解析失败: " + e.getMessage()); + return result; + } + } } \ No newline at end of file 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 0e31749..3fdee2d 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 @@ -137,4 +137,38 @@ public class ImportTaskServiceImpl extends ServiceImpl ids = expiredTasks.stream().map(ImportTask::getId).toList(); return this.removeByIds(ids); } + + @Override + public boolean hasImportingTask(String uploadUserId) { + List activeStatuses = List.of("UPLOADED", "PARSING", "VALIDATING"); + List tasks = importTaskMapper.selectByUserIdAndStatuses(uploadUserId, activeStatuses); + return tasks != null && !tasks.isEmpty(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean cancelTask(String taskId, String operatorId) { + ImportTask importTask = this.getById(taskId); + if (importTask == null) { + return false; + } + String currentStatus = importTask.getStatus(); + if ("CONFIRMED".equals(currentStatus) || "FAILED".equals(currentStatus) || "CANCELLED".equals(currentStatus)) { + return false; + } + importTask.setStatus("CANCELLED"); + importTask.setErrorMsg("用户取消: " + operatorId); + importTask.setUpdatedAt(new Date()); + return this.updateById(importTask); + } + + @Override + public ImportTask getCurrentTaskByUserId(String uploadUserId) { + List activeStatuses = List.of("UPLOADED", "PARSING", "VALIDATING"); + List tasks = importTaskMapper.selectByUserIdAndStatuses(uploadUserId, activeStatuses); + if (tasks == null || tasks.isEmpty()) { + return null; + } + return tasks.get(0); + } } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/utils/ZipFileUtil.java b/backend/src/main/java/com/yfd/platform/data/utils/ZipFileUtil.java new file mode 100644 index 0000000..137e293 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/data/utils/ZipFileUtil.java @@ -0,0 +1,219 @@ +package com.yfd.platform.data.utils; + +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipInputStream; + +public class ZipFileUtil { + + public static final String DEFAULT_TEMP_BASE = "D:\\zip_import_temp"; + + public static class ZipContent { + public String excelFileName; + public String excelFilePath; + public Map images; + public Map videos; + public Map otherFiles; + public String tempDir; + + public ZipContent() { + this.images = new HashMap<>(); + this.videos = new HashMap<>(); + this.otherFiles = new HashMap<>(); + } + + public InputStream getExcelStream() throws IOException { + if (excelFilePath == null) { + return null; + } + return new FileInputStream(excelFilePath); + } + } + + public static String getDefaultTempDir() { + return DEFAULT_TEMP_BASE; + } + + public static ZipContent extractZipToTemp(MultipartFile file) throws IOException { + return extractZipToTemp(file, DEFAULT_TEMP_BASE); + } + + public static ZipContent extractZipToTemp(MultipartFile file, String baseTempDir) throws IOException { + ZipContent content = new ZipContent(); + + String taskId = UUID.randomUUID().toString().substring(0, 8); + Path tempDirPath = Paths.get(baseTempDir, "zip_" + taskId); + Files.createDirectories(tempDirPath); + content.tempDir = tempDirPath.toString(); + + File zipFile = new File(tempDirPath.toFile(), "upload.zip"); + file.transferTo(zipFile); + + try { + if (!isValidZipFile(zipFile)) { + throw new IOException("文件不是有效的ZIP格式或已损坏"); + } + + IOException lastException = null; + Charset[] charsets = new Charset[]{ + StandardCharsets.UTF_8, + Charset.forName("GBK"), + StandardCharsets.ISO_8859_1, + Charset.forName("GB18030") + }; + + for (Charset charset : charsets) { + try { + content = extractFromZipFile(zipFile, tempDirPath.toFile(), charset); + content.tempDir = tempDirPath.toString(); + return content; + } catch (IOException e) { + lastException = e; + content = new ZipContent(); + content.tempDir = tempDirPath.toString(); + } + } + + throw lastException != null ? lastException : new IOException("无法解析ZIP文件"); + + } finally { + if (zipFile.exists()) { + zipFile.delete(); + } + } + } + + private static boolean isValidZipFile(File file) { + if (file == null || file.length() < 4) { + return false; + } + try (FileInputStream fis = new FileInputStream(file)) { + byte[] signature = new byte[4]; + int read = fis.read(signature); + if (read != 4) { + return false; + } + return signature[0] == 0x50 && signature[1] == 0x4B && + signature[2] == 0x03 && signature[3] == 0x04; + } catch (IOException e) { + return false; + } + } + + private static ZipContent extractFromZipFile(File zipFile, File tempDir, Charset charset) throws IOException { + ZipContent content = new ZipContent(); + + try (ZipFile zip = new ZipFile(zipFile, charset)) { + Enumeration entries = zip.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + String entryName = entry.getName(); + + if (entry.isDirectory()) { + continue; + } + + try (InputStream is = zip.getInputStream(entry)) { + String lowerName = entryName.toLowerCase(); + + if (lowerName.endsWith(".xlsx") || lowerName.endsWith(".xls")) { + String excelPath = saveFileToDir(is, tempDir, "excel", getFileName(entryName)); + content.excelFileName = getFileName(entryName); + content.excelFilePath = excelPath; + } else if (isImageFile(lowerName)) { + String folder = "images"; + String path = saveFileToDir(is, tempDir, folder, getFileName(entryName)); + content.images.put(entryName, path); + } else if (isVideoFile(lowerName)) { + String folder = "videos"; + String path = saveFileToDir(is, tempDir, folder, getFileName(entryName)); + content.videos.put(entryName, path); + } else { + String folder = "others"; + String path = saveFileToDir(is, tempDir, folder, getFileName(entryName)); + content.otherFiles.put(entryName, path); + } + } + } + } + + return content; + } + + private static String getFileName(String entryName) { + if (entryName == null) return ""; + int lastSep = Math.max(entryName.lastIndexOf('/'), entryName.lastIndexOf('\\')); + return lastSep >= 0 ? entryName.substring(lastSep + 1) : entryName; + } + + private static String saveFileToDir(InputStream is, File tempDir, String subFolder, String fileName) throws IOException { + File folder = new File(tempDir, subFolder); + if (!folder.exists()) { + folder.mkdirs(); + } + + File file = new File(folder, fileName); + try (FileOutputStream fos = new FileOutputStream(file)) { + byte[] buffer = new byte[4096]; + int len; + while ((len = is.read(buffer)) > 0) { + fos.write(buffer, 0, len); + } + } + return file.getAbsolutePath(); + } + + private static boolean isImageFile(String fileName) { + return fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") || + fileName.endsWith(".png") || fileName.endsWith(".gif") || + fileName.endsWith(".bmp") || fileName.endsWith(".webp"); + } + + private static boolean isVideoFile(String fileName) { + return fileName.endsWith(".mp4") || fileName.endsWith(".avi") || + fileName.endsWith(".mov") || fileName.endsWith(".wmv") || + fileName.endsWith(".flv") || fileName.endsWith(".mkv"); + } + + public static void cleanupTempDir(String tempDir) { + if (tempDir == null || tempDir.isEmpty()) { + return; + } + File dir = new File(tempDir); + if (dir.exists()) { + deleteDirectory(dir); + } + } + + private static void deleteDirectory(File dir) { + File[] files = dir.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + deleteDirectory(file); + } else { + file.delete(); + } + } + } + dir.delete(); + } + + public static String getFileExtension(String fileName) { + if (fileName == null) return ""; + int lastDot = fileName.lastIndexOf('.'); + return lastDot >= 0 ? fileName.substring(lastDot + 1).toLowerCase() : ""; + } +} \ No newline at end of file diff --git a/backend/src/main/resources/application-devtw.yml b/backend/src/main/resources/application-devtw.yml index efdf42b..05839c9 100644 --- a/backend/src/main/resources/application-devtw.yml +++ b/backend/src/main/resources/application-devtw.yml @@ -58,8 +58,8 @@ mybatis-plus: configuration: map-underscore-to-camel-case: true cache-enabled: false -# log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl - log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl +# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 登录相关配置 From e54a242dde764f353926d8736763f9b1142b95da Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 22 Apr 2026 17:34:27 +0800 Subject: [PATCH 05/13] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E8=BF=87?= =?UTF-8?q?=E9=B1=BC=E8=AE=BE=E6=96=BD=E5=92=8C=E9=B1=BC=E7=A7=8D=E7=B1=BB?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SdFishDictoryBController.java | 77 +++++++++ .../env/controller/SdFpssBHController.java | 83 +++++++++ .../platform/env/domain/SdFishDictoryB.java | 117 +++++++++++++ .../com/yfd/platform/env/domain/SdFpssBH.java | 158 ++++++++++++++++++ .../env/mapper/SdFishDictoryBMapper.java | 9 + .../platform/env/mapper/SdFpssBHMapper.java | 9 + .../env/service/ISdFishDictoryBService.java | 18 ++ .../env/service/ISdFpssBHService.java | 22 +++ .../impl/SdFishDictoryBServiceImpl.java | 65 +++++++ .../env/service/impl/SdFpssBHServiceImpl.java | 73 ++++++++ 10 files changed, 631 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java create mode 100644 backend/src/main/java/com/yfd/platform/env/controller/SdFpssBHController.java create mode 100644 backend/src/main/java/com/yfd/platform/env/domain/SdFishDictoryB.java create mode 100644 backend/src/main/java/com/yfd/platform/env/domain/SdFpssBH.java create mode 100644 backend/src/main/java/com/yfd/platform/env/mapper/SdFishDictoryBMapper.java create mode 100644 backend/src/main/java/com/yfd/platform/env/mapper/SdFpssBHMapper.java create mode 100644 backend/src/main/java/com/yfd/platform/env/service/ISdFishDictoryBService.java create mode 100644 backend/src/main/java/com/yfd/platform/env/service/ISdFpssBHService.java create mode 100644 backend/src/main/java/com/yfd/platform/env/service/impl/SdFishDictoryBServiceImpl.java create mode 100644 backend/src/main/java/com/yfd/platform/env/service/impl/SdFpssBHServiceImpl.java diff --git a/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java b/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java new file mode 100644 index 0000000..fc8c878 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java @@ -0,0 +1,77 @@ +package com.yfd.platform.env.controller; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.annotation.Log; +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.env.domain.SdFishDictoryB; +import com.yfd.platform.env.service.ISdFishDictoryBService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + *

+ * 鱼类字典表 前端控制器 + *

+ */ +@RestController +@RequestMapping("/env/fishDictory") +@Tag(name = "鱼类字典管理") +public class SdFishDictoryBController { + + @Resource + private ISdFishDictoryBService sdFishDictoryBService; + + @GetMapping("/queryPageList") + @Operation(summary = "分页查询鱼类字典列表") + public ResponseResult queryPageList( + @RequestParam(required = false) String name, + @RequestParam(required = false) String code, + @RequestParam(required = false) Integer type, + @RequestParam(required = false) Integer rare, + @RequestParam(defaultValue = "1") Long pageNum, + @RequestParam(defaultValue = "10") Long pageSize) { + Page page = new Page<>(pageNum, pageSize); + Page result = sdFishDictoryBService.selectPage(name, code, type, rare, page); + return ResponseResult.successData(result); + } + + @GetMapping("/list") + @Operation(summary = "查询所有鱼类字典") + public ResponseResult list() { + return ResponseResult.successData(sdFishDictoryBService.list()); + } + + @GetMapping("/getById") + @Operation(summary = "根据ID查询鱼类字典") + public ResponseResult getById(@RequestParam String id) { + return ResponseResult.successData(sdFishDictoryBService.getById(id)); + } + + @Log(module = "鱼类字典管理", value = "新增鱼类字典") + @PostMapping("/add") + @Operation(summary = "新增鱼类字典") + public ResponseResult add(@RequestBody SdFishDictoryB fishDictoryB) { + boolean result = sdFishDictoryBService.add(fishDictoryB); + return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败"); + } + + @Log(module = "鱼类字典管理", value = "修改鱼类字典") + @PostMapping("/update") + @Operation(summary = "修改鱼类字典") + public ResponseResult update(@RequestBody SdFishDictoryB fishDictoryB) { + boolean result = sdFishDictoryBService.updateById(fishDictoryB); + return result ? ResponseResult.success("修改成功") : ResponseResult.error("修改失败"); + } + + @Log(module = "鱼类字典管理", value = "删除鱼类字典") + @PostMapping("/delete") + @Operation(summary = "删除鱼类字典") + public ResponseResult delete(@RequestParam String id) { + boolean result = sdFishDictoryBService.deleteById(id); + return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败"); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/controller/SdFpssBHController.java b/backend/src/main/java/com/yfd/platform/env/controller/SdFpssBHController.java new file mode 100644 index 0000000..0062657 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/controller/SdFpssBHController.java @@ -0,0 +1,83 @@ +package com.yfd.platform.env.controller; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.annotation.Log; +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.env.domain.SdFpssBH; +import com.yfd.platform.env.service.ISdFpssBHService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + *

+ * 过鱼设施表 前端控制器 + *

+ */ +@RestController +@RequestMapping("/env/fpss") +@Tag(name = "过鱼设施管理") +public class SdFpssBHController { + + @Resource + private ISdFpssBHService sdFpssBHService; + + @GetMapping("/queryPageList") + @Operation(summary = "分页查询过鱼设施列表") + public ResponseResult queryPageList( + @RequestParam(required = false) String stcd, + @RequestParam(required = false) String sttp, + @RequestParam(required = false) String rstcd, + @RequestParam(required = false) Integer usfl, + @RequestParam(defaultValue = "1") Long pageNum, + @RequestParam(defaultValue = "10") Long pageSize) { + Page page = new Page<>(pageNum, pageSize); + Page result = sdFpssBHService.selectPage(stcd, sttp, rstcd, usfl, page); + return ResponseResult.successData(result); + } + + @GetMapping("/list") + @Operation(summary = "查询所有过鱼设施") + public ResponseResult list() { + return ResponseResult.successData(sdFpssBHService.list()); + } + + @GetMapping("/getById") + @Operation(summary = "根据编码查询过鱼设施") + public ResponseResult getById(@RequestParam String stcd, @RequestParam String sttp) { + return ResponseResult.successData(sdFpssBHService.getDetail(stcd, sttp)); + } + + @GetMapping("/getByRstcd") + @Operation(summary = "根据电站编码查询过鱼设施") + public ResponseResult getByRstcd(@RequestParam String rstcd) { + return ResponseResult.successData(sdFpssBHService.getByRstcd(rstcd)); + } + + @Log(module = "过鱼设施管理", value = "新增过鱼设施") + @PostMapping("/add") + @Operation(summary = "新增过鱼设施") + public ResponseResult add(@RequestBody SdFpssBH sdFpssBH) { + boolean result = sdFpssBHService.add(sdFpssBH); + return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败"); + } + + @Log(module = "过鱼设施管理", value = "修改过鱼设施") + @PostMapping("/update") + @Operation(summary = "修改过鱼设施") + public ResponseResult update(@RequestBody SdFpssBH sdFpssBH) { + boolean result = sdFpssBHService.updateById(sdFpssBH); + return result ? ResponseResult.success("修改成功") : ResponseResult.error("修改失败"); + } + + @Log(module = "过鱼设施管理", value = "删除过鱼设施") + @PostMapping("/delete") + @Operation(summary = "删除过鱼设施") + public ResponseResult delete(@RequestParam String stcd, @RequestParam String sttp) { + boolean result = sdFpssBHService.deleteById(stcd, sttp); + return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败"); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/domain/SdFishDictoryB.java b/backend/src/main/java/com/yfd/platform/env/domain/SdFishDictoryB.java new file mode 100644 index 0000000..8e2267d --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/domain/SdFishDictoryB.java @@ -0,0 +1,117 @@ +package com.yfd.platform.env.domain; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("SD_FISHDICTORY_B") +public class SdFishDictoryB implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.INPUT) + private String id; + + private String code; + + private String name; + + private String nameEn; + + private String alias; + + private String logo; + + private String introduce; + + private String inffile; + + private String orders; + + private String family; + + private String genus; + + private String species; + + private Integer type; + + private String fsz; + + private Integer rare; + + private Integer specOrigin; + + private Integer ptype; + + private String rvcd; + + private String habitMigrat; + + private String feedingHabit; + + private String spawnCharact; + + private String food; + + private String timeFeed; + + private String orignDate; + + private String pretemp; + + private String flowRate; + + private String depth; + + private String botmMater; + + private String wqtq; + + private Integer habitat; + + private Integer situation; + + private Integer resourceType; + + private String shapedesc; + + private String protectlvl; + + private String habitation; + + private String fid; + + private String description; + + private Integer enable; + + private Integer internal; + + private Integer orderIndex; + + private String recordUser; + + private Date recordTime; + + private String modifyUser; + + private Date modifyTime; + + private Integer isDeleted; + + private String deleteUser; + + private Date deleteTime; + + private String spawnMonth; + + private String vlsr; + + private Date vlsrTm; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/domain/SdFpssBH.java b/backend/src/main/java/com/yfd/platform/env/domain/SdFpssBH.java new file mode 100644 index 0000000..51f80eb --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/domain/SdFpssBH.java @@ -0,0 +1,158 @@ +package com.yfd.platform.env.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +@Data +@TableName("SD_FPSS_B_H") +public class SdFpssBH implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.INPUT) + private String stcd; + + private String sttp; + + private Date tm; + + private Integer blprd; + + private BigDecimal lgtd; + + private BigDecimal lttd; + + private BigDecimal elev; + + private String stlc; + + private Integer usfl; + + private Integer dtin; + + private Date dtinTm; + + private Integer orderIndex; + + private String rstcd; + + private Date stdsdt; + + private Date pststdt; + + private Date pesstdt; + + private Date swdt; + + private Date jcdt; + + private Date wddt; + + private Integer bldsttCode; + + private String introduce; + + private String logo; + + private String inffile; + + private BigDecimal inv; + + private String ydxs; + + private BigDecimal ydzcd; + + private BigDecimal ydjkz; + + private Integer ydjkcnt; + + private BigDecimal jkhg; + + private String ydyyxs; + + private BigDecimal ydckz; + + private Integer ydckcnt; + + private BigDecimal ckhg; + + private BigDecimal ydcsv; + + private Integer ydcscd; + + private Integer ydcskd; + + private String ydcspd; + + private Integer ydcscnt; + + private Integer ydxxccnt; + + private BigDecimal v; + + private String fzrdmxz; + + private String fzrtdz; + + private BigDecimal fzryxwdp; + + private BigDecimal fzrpj; + + private String symtlcs; + + private String symtxs; + + private String xymtlcs; + + private String xymtxs; + + private String jyfs; + + private String yyfs; + + private Integer syjcnt; + + private BigDecimal syjhg; + + private BigDecimal syjq; + + private String syjsz; + + private BigDecimal syjwdp; + + private Long sjgycnt; + + private String ZygyDx; + + private String ZygyDxms; + + private String JggyDx; + + private String JggyDxms; + + private String gytm; + + private String yxtm; + + private String fpssmn; + + private Integer dtfrqcy; + + private String jbtxcs; + + private Integer isUp; + + private Integer isDown; + + private String remark; + + private String vlsr; + + private Date vlsrTm; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/mapper/SdFishDictoryBMapper.java b/backend/src/main/java/com/yfd/platform/env/mapper/SdFishDictoryBMapper.java new file mode 100644 index 0000000..14e31ed --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/mapper/SdFishDictoryBMapper.java @@ -0,0 +1,9 @@ +package com.yfd.platform.env.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yfd.platform.env.domain.SdFishDictoryB; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface SdFishDictoryBMapper extends BaseMapper { +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/mapper/SdFpssBHMapper.java b/backend/src/main/java/com/yfd/platform/env/mapper/SdFpssBHMapper.java new file mode 100644 index 0000000..43079b5 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/mapper/SdFpssBHMapper.java @@ -0,0 +1,9 @@ +package com.yfd.platform.env.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yfd.platform.env.domain.SdFpssBH; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface SdFpssBHMapper extends BaseMapper { +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/service/ISdFishDictoryBService.java b/backend/src/main/java/com/yfd/platform/env/service/ISdFishDictoryBService.java new file mode 100644 index 0000000..05e03b8 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/service/ISdFishDictoryBService.java @@ -0,0 +1,18 @@ +package com.yfd.platform.env.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import com.yfd.platform.env.domain.SdFishDictoryB; + +public interface ISdFishDictoryBService extends IService { + + Page selectPage(String name, String code, Integer type, Integer rare, Page page); + + boolean add(SdFishDictoryB fishDictoryB); + + boolean updateById(SdFishDictoryB fishDictoryB); + + boolean deleteById(String id); + + SdFishDictoryB getById(String id); +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/service/ISdFpssBHService.java b/backend/src/main/java/com/yfd/platform/env/service/ISdFpssBHService.java new file mode 100644 index 0000000..3acdb85 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/service/ISdFpssBHService.java @@ -0,0 +1,22 @@ +package com.yfd.platform.env.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import com.yfd.platform.env.domain.SdFpssBH; + +import java.util.List; + +public interface ISdFpssBHService extends IService { + + Page selectPage(String stcd, String sttp, String rstcd, Integer usfl, Page page); + + List getByRstcd(String rstcd); + + boolean add(SdFpssBH sdFpssBH); + + boolean updateById(SdFpssBH sdFpssBH); + + boolean deleteById(String stcd, String sttp); + + SdFpssBH getDetail(String stcd, String sttp); +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/service/impl/SdFishDictoryBServiceImpl.java b/backend/src/main/java/com/yfd/platform/env/service/impl/SdFishDictoryBServiceImpl.java new file mode 100644 index 0000000..4a118c0 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/service/impl/SdFishDictoryBServiceImpl.java @@ -0,0 +1,65 @@ +package com.yfd.platform.env.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.env.domain.SdFishDictoryB; +import com.yfd.platform.env.mapper.SdFishDictoryBMapper; +import com.yfd.platform.env.service.ISdFishDictoryBService; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +@Service +public class SdFishDictoryBServiceImpl extends ServiceImpl implements ISdFishDictoryBService { + + @Override + public Page selectPage(String name, String code, Integer type, Integer rare, Page page) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SdFishDictoryB::getIsDeleted, 0); + + if (StringUtils.hasText(name)) { + wrapper.like(SdFishDictoryB::getName, name); + } + if (StringUtils.hasText(code)) { + wrapper.eq(SdFishDictoryB::getCode, code); + } + if (type != null) { + wrapper.eq(SdFishDictoryB::getType, type); + } + if (rare != null) { + wrapper.eq(SdFishDictoryB::getRare, rare); + } + + wrapper.orderByDesc(SdFishDictoryB::getOrderIndex); + return page(page, wrapper); + } + + @Override + public boolean add(SdFishDictoryB fishDictoryB) { + fishDictoryB.setIsDeleted(0); + return save(fishDictoryB); + } + + @Override + public boolean updateById(SdFishDictoryB fishDictoryB) { + return updateById(fishDictoryB); + } + + @Override + public boolean deleteById(String id) { + SdFishDictoryB entity = getById(id); + if (entity != null) { + entity.setIsDeleted(1); + return updateById(entity); + } + return false; + } + + @Override + public SdFishDictoryB getById(String id) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SdFishDictoryB::getId, id) + .eq(SdFishDictoryB::getIsDeleted, 0); + return getOne(wrapper); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/service/impl/SdFpssBHServiceImpl.java b/backend/src/main/java/com/yfd/platform/env/service/impl/SdFpssBHServiceImpl.java new file mode 100644 index 0000000..cd705e2 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/service/impl/SdFpssBHServiceImpl.java @@ -0,0 +1,73 @@ +package com.yfd.platform.env.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.env.domain.SdFpssBH; +import com.yfd.platform.env.mapper.SdFpssBHMapper; +import com.yfd.platform.env.service.ISdFpssBHService; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.List; + +@Service +public class SdFpssBHServiceImpl extends ServiceImpl implements ISdFpssBHService { + + @Override + public Page selectPage(String stcd, String sttp, String rstcd, Integer usfl, Page page) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + + if (StringUtils.hasText(stcd)) { + wrapper.like(SdFpssBH::getStcd, stcd); + } + if (StringUtils.hasText(sttp)) { + wrapper.eq(SdFpssBH::getSttp, sttp); + } + if (StringUtils.hasText(rstcd)) { + wrapper.eq(SdFpssBH::getRstcd, rstcd); + } + if (usfl != null) { + wrapper.eq(SdFpssBH::getUsfl, usfl); + } + + wrapper.orderByDesc(SdFpssBH::getOrderIndex); + return page(page, wrapper); + } + + @Override + public List getByRstcd(String rstcd) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SdFpssBH::getRstcd, rstcd); + return list(wrapper); + } + + @Override + public boolean add(SdFpssBH sdFpssBH) { + return save(sdFpssBH); + } + + @Override + public boolean updateById(SdFpssBH sdFpssBH) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SdFpssBH::getStcd, sdFpssBH.getStcd()) + .eq(SdFpssBH::getSttp, sdFpssBH.getSttp()); + return update(sdFpssBH, wrapper); + } + + @Override + public boolean deleteById(String stcd, String sttp) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SdFpssBH::getStcd, stcd) + .eq(SdFpssBH::getSttp, sttp); + return remove(wrapper); + } + + @Override + public SdFpssBH getDetail(String stcd, String sttp) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SdFpssBH::getStcd, stcd) + .eq(SdFpssBH::getSttp, sttp); + return getOne(wrapper); + } +} \ No newline at end of file From 84095972c8071a278b30775bf31c216c588ffbcc Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 22 Apr 2026 18:54:20 +0800 Subject: [PATCH 06/13] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E8=BF=87=E9=B1=BC=E8=AE=BE=E6=96=BD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../platform/data/domain/FishDraftData.java | 63 ++- .../service/impl/FishImportServiceImpl.java | 469 ++++++++++++++---- .../platform/env/domain/SdFishDictoryB.java | 155 ++++++ .../com/yfd/platform/env/domain/SdFpssBH.java | 240 ++++++++- 4 files changed, 808 insertions(+), 119 deletions(-) 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 2de542d..601b934 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 @@ -31,12 +31,6 @@ public class FishDraftData implements Serializable { */ private String stcd; - /** - * 所属基地编码 - */ - @TableField(exist = false) - private String baseId; - /** * 填报时间 */ @@ -47,6 +41,7 @@ public class FishDraftData implements Serializable { */ private String ftp; + /** * 鱼类全长 */ @@ -135,24 +130,6 @@ public class FishDraftData implements Serializable { private BigDecimal wt; - /** - * 电站名称 - */ - @TableField(exist = false) - private String engName; - - /** - * 基地名称 - */ - @TableField(exist = false) - private String baseName; - - /** - * 设施名称 - */ - @TableField(exist = false) - private String fPname; - /** * 审批完成时间 @@ -197,4 +174,42 @@ public class FishDraftData implements Serializable { */ @TableField(fill = FieldFill.INSERT_UPDATE) private String updatedBy; + + /** + * 所属基地编码 + */ + @TableField(exist = false) + private String baseId; + + + /** + * 电站名称 + */ + @TableField(exist = false) + private String engName; + + /** + * 基地名称 + */ + @TableField(exist = false) + private String baseName; + + /** + * 流域编码 + */ + @TableField(exist = false) + private String rvcd; + + /** + * 设施名称 + */ + @TableField(exist = false) + private String fpname; + + /** + * 鱼类名称 + */ + @TableField(exist = false) + private String ftpName; + } \ 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 b37b1b1..344f33f 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 @@ -5,10 +5,12 @@ import com.yfd.platform.data.domain.FishImportRequest; import com.yfd.platform.data.domain.FishImportResult; import com.yfd.platform.data.service.IFishImportService; import com.yfd.platform.data.utils.ZipFileUtil; -import com.yfd.platform.env.domain.SdEngInfoBH; -import com.yfd.platform.env.domain.SdHydrobase; -import com.yfd.platform.env.mapper.SdEngInfoBHMapper; -import com.yfd.platform.env.mapper.SdHydrobaseMapper; +import com.yfd.platform.env.domain.*; +import com.yfd.platform.env.mapper.*; +import com.yfd.platform.system.domain.SysDictionary; +import com.yfd.platform.system.domain.SysDictionaryItems; +import com.yfd.platform.system.service.ISysDictionaryItemsService; +import com.yfd.platform.system.service.ISysDictionaryService; import jakarta.annotation.Resource; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; @@ -16,7 +18,6 @@ import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; -import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; @@ -34,30 +35,73 @@ public class FishImportServiceImpl implements IFishImportService { @Resource private SdHydrobaseMapper hydrobaseMapper; - private static final Map EXCEL_COLUMN_MAPPING = new LinkedHashMap<>(); + @Resource + private SdRvcdDicMapper rvcdDicMapper; - private static final Map STATION_NAME_CACHE = new HashMap<>(); - private static final Map STATION_CODE_CACHE = new HashMap<>(); - private static final Map BASE_NAME_CACHE = new HashMap<>(); - private static final Map BASE_CODE_CACHE = new HashMap<>(); + @Resource + private SdFpssBHMapper fpssBHMapper; + + @Resource + private SdFishDictoryBMapper fishDictoryBMapper; + + @Resource + private ISysDictionaryService sysDictionaryService; + + @Resource + private ISysDictionaryItemsService sysDictionaryItemsService; + + private static final Map EXCEL_COLUMN_MAPPING = new LinkedHashMap<>(); + private static final Map EXCEL_COLUMN_INDEX_MAPPING = new LinkedHashMap<>(); + + private static final Map STATION_NAME_CACHE = new LinkedHashMap<>(); + private static final Map BASE_NAME_CACHE = new LinkedHashMap<>(); + private static final Map RIVER_NAME_CACHE = new LinkedHashMap<>(); + + private static final Map FISH_DICT_CACHE = new LinkedHashMap<>(); + private static final Map FPSS_BH_CACHE = new LinkedHashMap<>(); + private static final Map DIRECTION_DICT_CACHE = new LinkedHashMap<>(); + private static final Map ISFS_DICT_CACHE = new LinkedHashMap<>(); + + private static final String DICT_CODE_FISH = "FISH_TYPE"; + private static final String DICT_CODE_DIRECTION = "FISH_DIRECTION"; + private static final String DICT_CODE_ISFS = "YES_NO"; static { EXCEL_COLUMN_MAPPING.put("电站名称", "stcd"); EXCEL_COLUMN_MAPPING.put("基地名称", "baseId"); + EXCEL_COLUMN_MAPPING.put("流域名称", "rvcd"); EXCEL_COLUMN_MAPPING.put("数据时间", "tm"); + EXCEL_COLUMN_MAPPING.put("过鱼时间", "tm"); EXCEL_COLUMN_MAPPING.put("鱼类", "ftp"); + EXCEL_COLUMN_MAPPING.put("鱼种类", "ftp"); EXCEL_COLUMN_MAPPING.put("鱼类全长", "fsz"); EXCEL_COLUMN_MAPPING.put("过鱼数量", "fcnt"); + EXCEL_COLUMN_MAPPING.put("过鱼数量(尾)", "fcnt"); EXCEL_COLUMN_MAPPING.put("平均体重", "fwet"); EXCEL_COLUMN_MAPPING.put("开始日期", "strdt"); EXCEL_COLUMN_MAPPING.put("结束日期", "enddt"); EXCEL_COLUMN_MAPPING.put("游向", "direction"); + EXCEL_COLUMN_MAPPING.put("水温", "wt"); EXCEL_COLUMN_MAPPING.put("年份", "yr"); EXCEL_COLUMN_MAPPING.put("月份", "mouth"); EXCEL_COLUMN_MAPPING.put("过鱼视频文件路径", "vdpth"); EXCEL_COLUMN_MAPPING.put("图片文件路径", "picpth"); EXCEL_COLUMN_MAPPING.put("是否鱼苗", "isfs"); EXCEL_COLUMN_MAPPING.put("数据来源", "sourceType"); + EXCEL_COLUMN_MAPPING.put("过鱼设施名称", "fpname"); + + + EXCEL_COLUMN_INDEX_MAPPING.put(0, "baseName"); + EXCEL_COLUMN_INDEX_MAPPING.put(1, "stationName"); + EXCEL_COLUMN_INDEX_MAPPING.put(2, "fpname"); + EXCEL_COLUMN_INDEX_MAPPING.put(3, "tm"); + EXCEL_COLUMN_INDEX_MAPPING.put(4, "ftp"); + EXCEL_COLUMN_INDEX_MAPPING.put(5, "isfs"); + EXCEL_COLUMN_INDEX_MAPPING.put(6, "direction"); + EXCEL_COLUMN_INDEX_MAPPING.put(7, "fcnt"); + EXCEL_COLUMN_INDEX_MAPPING.put(8, "fsz"); + EXCEL_COLUMN_INDEX_MAPPING.put(9, "fwet"); + EXCEL_COLUMN_INDEX_MAPPING.put(10, "wt"); } @Override @@ -96,25 +140,8 @@ public class FishImportServiceImpl implements IFishImportService { return result; } - Map columnIndexMap = new HashMap<>(); List unrecognizedHeaders = new ArrayList<>(); - - for (int i = 0; i < headerRow.getLastCellNum(); i++) { - Cell cell = headerRow.getCell(i); - if (cell != null) { - String headerName = getCellStringValue(cell).trim(); - String mappedField = EXCEL_COLUMN_MAPPING.get(headerName); - if (mappedField != null) { - columnIndexMap.put(i, mappedField); - } else { - unrecognizedHeaders.add(headerName); - } - } - } - - if (!unrecognizedHeaders.isEmpty()) { - result.setUnrecognizedFields(unrecognizedHeaders); - } + Map columnIndexMap = new HashMap<>(EXCEL_COLUMN_INDEX_MAPPING); int totalRows = sheet.getLastRowNum(); result.setTotalCount(totalRows); @@ -126,7 +153,7 @@ public class FishImportServiceImpl implements IFishImportService { } FishImportResult.FishImportRow importRow = parseRow(row, columnIndexMap, i); - if (importRow.getData() != null && importRow.getUnrecognizedFields().isEmpty()) { + if (importRow.getData() != null && importRow.getWarnings().isEmpty()) { result.getSuccessRows().add(importRow); result.setSuccessCount(result.getSuccessCount() + 1); } else { @@ -146,45 +173,93 @@ public class FishImportServiceImpl implements IFishImportService { FishImportResult.FishImportRow importRow = new FishImportResult.FishImportRow(rowIndex); FishDraftData data = new FishDraftData(); data.setId(UUID.randomUUID().toString()); - List unrecognizedFields = new ArrayList<>(); + List missingRequiredFields = new ArrayList<>(); for (Map.Entry entry : columnIndexMap.entrySet()) { Integer columnIndex = entry.getKey(); String fieldName = entry.getValue(); Cell cell = row.getCell(columnIndex); String cellValue = getCellStringValue(cell); - - if (!StringUtils.hasText(cellValue)) { - continue; - } - try { switch (fieldName) { - case "stcd": - String stcd = resolveStationCode(cellValue.trim()); - if (stcd == null) { - importRow.getWarnings().add("无法识别的电站: " + cellValue); + case "stationName": + if (!StringUtils.hasText(cellValue)) { + missingRequiredFields.add("电站名称"); + } else { + String stcd = resolveStationCode(cellValue.trim()); + if (stcd == null) { + importRow.getWarnings().add(fieldName); + data.setEngName(cellValue.trim()); + } else { + data.setEngName(cellValue.trim()); + } } - data.setStcd(stcd); break; - case "baseId": - String baseId = resolveBaseCode(cellValue.trim()); - if (baseId == null) { - importRow.getWarnings().add("无法识别的基地: " + cellValue); + case "baseName": + if (!StringUtils.hasText(cellValue)) { + missingRequiredFields.add("水电基地"); + } else { + String baseId = resolveBaseCode(cellValue.trim()); + if (baseId == null) { + importRow.getWarnings().add(fieldName); + data.setBaseId(cellValue.trim()); + data.setBaseName(cellValue.trim()); + } else { + data.setBaseId(baseId); + data.setBaseName(cellValue.trim()); + } + } + break; + case "rvcd": + if (StringUtils.hasText(cellValue)) { + String rvcd = resolveRiverCode(cellValue.trim()); + if (rvcd == null) { + importRow.getWarnings().add(fieldName); + } else { + data.setRvcd(rvcd); + } } - data.setBaseId(baseId); break; case "tm": - data.setTm(parseDate(cellValue)); + if (!StringUtils.hasText(cellValue)) { + missingRequiredFields.add("过鱼时间"); + } else { + Date tm = parseDate(cellValue); + if (tm == null) { + importRow.getWarnings().add("过鱼时间格式错误: " + cellValue); + } + data.setTm(tm); + } break; case "ftp": - data.setFtp(cellValue.trim()); + if (!StringUtils.hasText(cellValue)) { + missingRequiredFields.add("鱼种类"); + } else { + String stcd = resolveFishDictCode(cellValue.trim()); + if (stcd == null) { + importRow.getWarnings().add(fieldName); + data.setFtp(cellValue.trim()); + data.setFtpName(cellValue.trim()); + } else { + data.setFtp(stcd); + data.setFtpName(cellValue.trim()); + } + } break; case "fsz": data.setFsz(cellValue.trim()); break; case "fcnt": - data.setFcnt(parseInteger(cellValue)); + if (!StringUtils.hasText(cellValue)) { + missingRequiredFields.add("过鱼数量"); + } else { + Integer fcnt = parseInteger(cellValue); + if (fcnt == null) { + importRow.getWarnings().add(fieldName); + data.setFcnt(parseInteger(cellValue)); + } + data.setFcnt(fcnt); + } break; case "fwet": data.setFwet(cellValue.trim()); @@ -196,7 +271,12 @@ public class FishImportServiceImpl implements IFishImportService { data.setEnddt(parseDate(cellValue)); break; case "direction": - data.setDirection(parseDirection(cellValue.trim())); + if (!StringUtils.hasText(cellValue)) { + missingRequiredFields.add("游向"); + } else { + String direction = resolveDirection(cellValue.trim(), importRow); + data.setDirection(direction); + } break; case "yr": data.setYr(parseInteger(cellValue)); @@ -211,21 +291,38 @@ public class FishImportServiceImpl implements IFishImportService { data.setPicpth(cellValue.trim()); break; case "isfs": - data.setIsfs(parseIsfs(cellValue)); + if (StringUtils.hasText(cellValue)) { + String isfs = resolveIsfs(cellValue.trim(), importRow); + data.setIsfs("是".equals(isfs) ? 1 : 0); + } break; case "sourceType": data.setSourceType(parseSourceType(cellValue.trim())); break; + case "fpname": + if (!StringUtils.hasText(cellValue)) { + missingRequiredFields.add("过鱼设施名称"); + } else { + String stcd = resolveFpssCode(cellValue.trim()); + if (stcd == null) { + importRow.getWarnings().add(fieldName); + data.setStcd(cellValue.trim()); + data.setFpname(cellValue.trim()); + } else { + data.setFpname(stcd); + data.setStcd(stcd); + } + } + break; default: break; } } catch (Exception e) { - importRow.getWarnings().add("字段[" + fieldName + "]解析异常: " + e.getMessage()); + e.printStackTrace(); +// importRow.getWarnings().add("字段[" + fieldName + "]解析异常: " + e.getMessage()); } } - importRow.setData(data); - importRow.setUnrecognizedFields(unrecognizedFields); return importRow; } @@ -237,7 +334,7 @@ public class FishImportServiceImpl implements IFishImportService { STATION_NAME_CACHE.put(station.getEnnm().trim().toLowerCase(), station.getStcd()); } if (StringUtils.hasText(station.getStcd())) { - STATION_CODE_CACHE.put(station.getStcd().trim().toLowerCase(), station.getStcd()); + STATION_NAME_CACHE.put(station.getStcd().trim().toLowerCase(), station.getStcd()); } } } @@ -249,12 +346,50 @@ public class FishImportServiceImpl implements IFishImportService { BASE_NAME_CACHE.put(base.getBasename().trim().toLowerCase(), base.getBaseid()); } if (StringUtils.hasText(base.getBaseid())) { - BASE_CODE_CACHE.put(base.getBaseid().trim().toLowerCase(), base.getBaseid()); + BASE_NAME_CACHE.put(base.getBaseid().trim().toLowerCase(), base.getBaseid()); + } + } + } + + if (RIVER_NAME_CACHE.isEmpty()) { + List riverList = rvcdDicMapper.selectList(null); + for (SdRvcdDic river : riverList) { + if (StringUtils.hasText(river.getRvnm())) { + RIVER_NAME_CACHE.put(river.getRvnm().trim().toLowerCase(), river.getRvcd()); + } + if (StringUtils.hasText(river.getRvcd())) { + RIVER_NAME_CACHE.put(river.getRvcd().trim().toLowerCase(), river.getRvcd()); + } + } + } + + if (FISH_DICT_CACHE.isEmpty()) { + List sdFishDictoryBS = fishDictoryBMapper.selectList(null); + for (SdFishDictoryB fishDictoryB : sdFishDictoryBS) { + if (StringUtils.hasText(fishDictoryB.getName())) { + FISH_DICT_CACHE.put(fishDictoryB.getName().trim().toLowerCase(), fishDictoryB.getCode()); + } + if (StringUtils.hasText(fishDictoryB.getCode())) { + FISH_DICT_CACHE.put(fishDictoryB.getCode().trim().toLowerCase(), fishDictoryB.getCode()); + } + } + } + + if (FPSS_BH_CACHE.isEmpty()) { + List sdFpssBHS = fpssBHMapper.selectList(null); + for (SdFpssBH sdFpssBH : sdFpssBHS) { + if (StringUtils.hasText(sdFpssBH.getStnm())) { + FPSS_BH_CACHE.put(sdFpssBH.getStnm().trim().toLowerCase(), sdFpssBH.getStcd()); + } + if (StringUtils.hasText(sdFpssBH.getStcd())) { + FPSS_BH_CACHE.put(sdFpssBH.getStcd().trim().toLowerCase(), sdFpssBH.getStcd()); } } } } + + private String resolveStationCode(String stationName) { if (stationName == null) { return null; @@ -271,6 +406,38 @@ public class FishImportServiceImpl implements IFishImportService { return null; } + private String resolveFpssCode(String name) { + if (name == null) { + return null; + } + String lowerName = name.toLowerCase().trim(); + if (FPSS_BH_CACHE.containsKey(lowerName)) { + return FPSS_BH_CACHE.get(lowerName); + } + for (Map.Entry entry : FPSS_BH_CACHE.entrySet()) { + if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) { + return entry.getValue(); + } + } + return null; + } + + private String resolveFishDictCode(String name) { + if (name == null) { + return null; + } + String lowerName = name.toLowerCase().trim(); + if (FISH_DICT_CACHE.containsKey(lowerName)) { + return FISH_DICT_CACHE.get(lowerName); + } + for (Map.Entry entry : FISH_DICT_CACHE.entrySet()) { + if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) { + return entry.getValue(); + } + } + return null; + } + private String resolveBaseCode(String baseName) { if (baseName == null) { return null; @@ -287,6 +454,165 @@ public class FishImportServiceImpl implements IFishImportService { return null; } + private String resolveRiverCode(String riverName) { + if (riverName == null) { + return null; + } + String lowerName = riverName.toLowerCase().trim(); + if (RIVER_NAME_CACHE.containsKey(lowerName)) { + return RIVER_NAME_CACHE.get(lowerName); + } + for (Map.Entry entry : RIVER_NAME_CACHE.entrySet()) { + if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) { + return entry.getValue(); + } + } + return null; + } + + private String validateFishType(String fishName, FishImportResult.FishImportRow importRow) { + if (fishName == null) { + return null; + } + String lowerName = fishName.toLowerCase().trim(); + + if (!FISH_DICT_CACHE.isEmpty()) { + if (FISH_DICT_CACHE.containsKey(lowerName)) { + return FISH_DICT_CACHE.get(lowerName); + } + for (Map.Entry entry : FISH_DICT_CACHE.entrySet()) { + if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) { + return entry.getValue(); + } + } + } + + importRow.getWarnings().add("鱼种类【" + fishName + "】未在字典中找到匹配,请手动确认"); + return fishName; + } + + private String validateFishFacility(String facilityName, FishImportResult.FishImportRow importRow) { + if (facilityName == null) { + return null; + } + String lowerName = facilityName.toLowerCase().trim(); + + importRow.getWarnings().add("过鱼设施【" + facilityName + "】暂无可用字典验证,请手动确认"); + return facilityName; + } + + private String resolveDirection(String direction, FishImportResult.FishImportRow importRow) { + if (direction == null) { + return null; + } + String lowerName = direction.toLowerCase().trim(); + + if (!DIRECTION_DICT_CACHE.isEmpty()) { + if (DIRECTION_DICT_CACHE.containsKey(lowerName)) { + return DIRECTION_DICT_CACHE.get(lowerName); + } + for (Map.Entry entry : DIRECTION_DICT_CACHE.entrySet()) { + if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) { + return entry.getValue(); + } + } + } + + if (lowerName.contains("上行") && lowerName.contains("折返")) { + return "上行折返"; + } else if (lowerName.contains("下行") && lowerName.contains("折返")) { + return "下行折返"; + } else if (lowerName.contains("上行")) { + return "上行"; + } else if (lowerName.contains("下行")) { + return "下行"; + } + + importRow.getWarnings().add("无法识别的游向: " + direction + ",请手动选择"); + return direction; + } + + private String resolveIsfs(String value, FishImportResult.FishImportRow importRow) { + if (value == null) { + return null; + } + String lowerName = value.toLowerCase().trim(); + + if (!ISFS_DICT_CACHE.isEmpty()) { + if (ISFS_DICT_CACHE.containsKey(lowerName)) { + return ISFS_DICT_CACHE.get(lowerName); + } + for (Map.Entry entry : ISFS_DICT_CACHE.entrySet()) { + if (entry.getKey().contains(lowerName) || lowerName.contains(entry.getKey())) { + return entry.getValue(); + } + } + } + + if (lowerName.equals("1") || lowerName.equals("是") || lowerName.equals("yes") || lowerName.equals("true")) { + return "是"; + } else if (lowerName.equals("0") || lowerName.equals("否") || lowerName.equals("no") || lowerName.equals("false")) { + return "否"; + } + + importRow.getWarnings().add("无法识别的【是否鱼苗】值: " + value + ",将默认设置为【否】"); + return "否"; + } + +// private void loadDirectionDict() { +// if (DIRECTION_DICT_CACHE.isEmpty()) { +// try { +// SysDictionary dict = sysDictionaryService.getByDictCode(DICT_CODE_DIRECTION); +// if (dict != null) { +// List items = sysDictionaryItemsService.listByDictId(dict.getId()); +// for (SysDictionaryItems item : items) { +// if (StringUtils.hasText(item.getItemName())) { +// DIRECTION_DICT_CACHE.put(item.getItemName().trim().toLowerCase(), item.getItemName()); +// } +// } +// } +// } catch (Exception e) { +// } +// } +// } +// +// private void loadIsfsDict() { +// if (ISFS_DICT_CACHE.isEmpty()) { +// try { +// SysDictionary dict = sysDictionaryService.getByDictCode(DICT_CODE_ISFS); +// if (dict != null) { +// List items = sysDictionaryItemsService.listByDictId(dict.getId()); +// for (SysDictionaryItems item : items) { +// if (StringUtils.hasText(item.getItemName())) { +// ISFS_DICT_CACHE.put(item.getItemName().trim().toLowerCase(), item.getItemName()); +// } +// } +// } +// } catch (Exception e) { +// } +// } +// } + +// private void loadFishDict() { +// if (FISH_DICT_CACHE.isEmpty()) { +// try { +// SysDictionary dict = sysDictionaryService.getByDictCode(DICT_CODE_FISH); +// if (dict != null) { +// List items = sysDictionaryItemsService.listByDictId(dict.getId()); +// for (SysDictionaryItems item : items) { +// if (StringUtils.hasText(item.getItemName())) { +// FISH_DICT_CACHE.put(item.getItemName().trim().toLowerCase(), item.getItemCode()); +// } +// if (StringUtils.hasText(item.getItemCode())) { +// FISH_DICT_CACHE.put(item.getItemCode().trim().toLowerCase(), item.getItemCode()); +// } +// } +// } +// } catch (Exception e) { +// } +// } +// } + private String getCellStringValue(Cell cell) { if (cell == null) { return ""; @@ -359,37 +685,6 @@ public class FishImportServiceImpl implements IFishImportService { } } - private String parseDirection(String direction) { - if (!StringUtils.hasText(direction)) { - return null; - } - String d = direction.toLowerCase(); - if (d.contains("上行") || d.contains("up")) { - return "上行"; - } else if (d.contains("下行") || d.contains("down")) { - return "下行"; - } else if (d.contains("折返")) { - if (d.contains("上行")) { - return "上行折返"; - } else if (d.contains("下行")) { - return "下行折返"; - } - return "折返"; - } - return direction; - } - - private Integer parseIsfs(String value) { - if (!StringUtils.hasText(value)) { - return 0; - } - String v = value.toLowerCase().trim(); - if (v.equals("1") || v.equals("是") || v.equals("yes") || v.equals("鱼苗")) { - return 1; - } - return 0; - } - private String parseSourceType(String value) { if (!StringUtils.hasText(value)) { return "IMPORT"; @@ -397,7 +692,7 @@ public class FishImportServiceImpl implements IFishImportService { String v = value.toLowerCase(); if (v.contains("手工") || v.contains("manual") || v.contains("录入")) { return "MANUAL"; - } else if (v.contains("自动") || v.contains("auto")) { + } else if (v.contains("自动") || v.contains("auto") || v.contains("采集")) { return "AUTO"; } else if (v.contains("导入") || v.contains("import")) { return "IMPORT"; diff --git a/backend/src/main/java/com/yfd/platform/env/domain/SdFishDictoryB.java b/backend/src/main/java/com/yfd/platform/env/domain/SdFishDictoryB.java index 8e2267d..d7b4f68 100644 --- a/backend/src/main/java/com/yfd/platform/env/domain/SdFishDictoryB.java +++ b/backend/src/main/java/com/yfd/platform/env/domain/SdFishDictoryB.java @@ -7,6 +7,11 @@ import lombok.EqualsAndHashCode; import java.io.Serializable; import java.util.Date; +/** + *

+ * 鱼类字典信息表 + *

+ */ @Data @EqualsAndHashCode(callSuper = false) @TableName("SD_FISHDICTORY_B") @@ -14,104 +19,254 @@ public class SdFishDictoryB implements Serializable { private static final long serialVersionUID = 1L; + /** + * 主键 + */ @TableId(type = IdType.INPUT) private String id; + /** + * 编码 + */ private String code; + /** + * 名称 + */ private String name; + /** + * 英文名称 + */ private String nameEn; + /** + * 俗名 + */ private String alias; + /** + * LOGO + */ private String logo; + /** + * 介绍 + */ private String introduce; + /** + * 介绍弹窗图片 + */ private String inffile; + /** + * 目 + */ private String orders; + /** + * 科 + */ private String family; + /** + * 属 + */ private String genus; + /** + * 种 + */ private String species; + /** + * 分类:1=淡水 2=海水 + */ private Integer type; + /** + * 成鱼大小:单位:cm + */ private String fsz; + /** + * 是否珍稀鱼类:0=否 1=是 + */ private Integer rare; + /** + * 物种来源:1=本土物种 2=外来物种 + */ private Integer specOrigin; + /** + * 保护类型:1=濒危 2=极危 3=近危 4=易危 5=重点保护 6=无危 7=国家二级 8=市二级保护 + */ private Integer ptype; + /** + * 所属流域 + */ private String rvcd; + /** + * 洄游习性 + */ private String habitMigrat; + /** + * 摄食习性 + */ private String feedingHabit; + /** + * 产卵特性 + */ private String spawnCharact; + /** + * 主要食物 + */ private String food; + /** + * 觅食时段 + */ private String timeFeed; + /** + * 产地及产期 + */ private String orignDate; + /** + * 适宜温度:单位:℃ + */ private String pretemp; + /** + * 适宜流速:单位:m/s + */ private String flowRate; + /** + * 适宜水深:单位(m) + */ private String depth; + /** + * 适宜底质 + */ private String botmMater; + /** + * 水质要求:1=Ⅰ类 2=Ⅱ类 3=Ⅲ类 4=Ⅳ类 5=Ⅴ类 6=劣质V + */ private String wqtq; + /** + * 主要生活环境 1=流水生境 2=静缓流生境 3=洞穴生境 + */ private Integer habitat; + /** + * 种群现状 1=优势种 2=常见种 3=少见种 4=记录种 + */ private Integer situation; + /** + * 资源类型 1=保护鱼类 2=特有鱼类 3=重要经济鱼类 4=濒危状况 + */ private Integer resourceType; + /** + * 形态描述 + */ private String shapedesc; + /** + * 保护级别 + */ private String protectlvl; + /** + * 栖息习性 + */ private String habitation; + /** + * 附件 + */ private String fid; + /** + * 描述 + */ private String description; + /** + * 是否启用:0=禁用 1=启用 + */ private Integer enable; + /** + * 系统内置项:0=否 1=是 + */ private Integer internal; + /** + * 排序 + */ private Integer orderIndex; + /** + * 创建人:关联SYS_USER.ID + */ private String recordUser; + /** + * 创建时间 + */ private Date recordTime; + /** + * 更新人:关联SYS_USER.ID + */ private String modifyUser; + /** + * 更新时间 + */ private Date modifyTime; + /** + * 是否已删除:0=未删除 1=已删除 + */ private Integer isDeleted; + /** + * 删除人:关联SYS_USER.ID + */ private String deleteUser; + /** + * 删除时间 + */ private Date deleteTime; + /** + * 产卵月份:多个月份以逗号分隔 + */ private String spawnMonth; + /** + * 数据来源 + */ private String vlsr; + /** + * 数据来源时间 + */ private Date vlsrTm; } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/domain/SdFpssBH.java b/backend/src/main/java/com/yfd/platform/env/domain/SdFpssBH.java index 51f80eb..993b6c5 100644 --- a/backend/src/main/java/com/yfd/platform/env/domain/SdFpssBH.java +++ b/backend/src/main/java/com/yfd/platform/env/domain/SdFpssBH.java @@ -1,6 +1,7 @@ package com.yfd.platform.env.domain; import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -9,150 +10,373 @@ import java.io.Serializable; import java.math.BigDecimal; import java.util.Date; +/** + *

+ * 过鱼设施工程信息表 + *

+ */ @Data @TableName("SD_FPSS_B_H") public class SdFpssBH implements Serializable { private static final long serialVersionUID = 1L; + /** + * 过鱼设施编码 + */ @TableId(type = IdType.INPUT) private String stcd; - private String sttp; + /** + * 设施名称 + */ + private String stnm; + /** + * 数据时间 + */ private Date tm; + /** + * 过鱼设施类型,字典编码:sd_fpss_b_h.sttp + * FP_1=鱼道 FP_2=仿自然通道 FP_3=集运鱼系统 FP_4=升鱼机 FP_5=其它过鱼方式 FP_6=网捕过坝 + */ + private String sttp; + + /** + * 所属建设阶段 字典编码:common.blprd + * 1001000=规划 1002000=预可研 1003000=环评 1004000=可研 1005000=在建 1006000=招标设计 + * 1007000=施工详图 1009000=建设 1010000=蓄水阶段环保验收 1011000=竣工 1012000=竣工环保验收 1013000=环境影响后评价 + */ private Integer blprd; + /** + * 经度,单位:(°) + */ private BigDecimal lgtd; + /** + * 纬度,单位:(°) + */ private BigDecimal lttd; + /** + * 高程,单位:m + */ private BigDecimal elev; + /** + * 站址/位置 + */ private String stlc; + /** + * 是否启用 字典编码:common.enabled 0=禁用 1=启用 + */ private Integer usfl; + /** + * 数据是否接入 字典编码:common.yn 0=否 1=是 + */ private Integer dtin; + /** + * 数据接入时间 + */ private Date dtinTm; + /** + * 排序,按照业务规则"升序" + */ private Integer orderIndex; + /** + * 所属电站编码,关联SD_ENGINFO_B_H.STCD + */ private String rstcd; + /** + * 规划设计日期 + */ private Date stdsdt; + /** + * 计划开工日期 + */ private Date pststdt; + /** + * 计划完工日期 + */ private Date pesstdt; + /** + * 开工日期 + */ private Date swdt; + /** + * 建成日期 + */ private Date jcdt; + /** + * 退役/拆除日期 + */ private Date wddt; + /** + * 建设状态分类:0=未建/规划(3,4,5,6,为空) 1=在建(2,7,8) 2=已建(1,10,11) + */ private Integer bldsttCode; + /** + * 简介 + */ private String introduce; + /** + * LOGO + */ private String logo; + /** + * 介绍弹窗图片 + */ private String inffile; + /** + * 投资,单位:亿元 + */ private BigDecimal inv; + /** + * 鱼道型式 + */ private String ydxs; + /** + * 鱼道总长度,单位:m + */ private BigDecimal ydzcd; + /** + * 鱼道进口运行设计水位,单位:m + */ private BigDecimal ydjkz; + /** + * 鱼道进口数量,单位:个 + */ private Integer ydjkcnt; + /** + * 鱼道或仿自然通道-进口高程,单位:m + */ private BigDecimal jkhg; + /** + * 鱼道进口诱鱼型式 + */ private String ydyyxs; + /** + * 鱼道出口运行设计水位,单位:m + */ private BigDecimal ydckz; + /** + * 鱼道出口数量,单位:个 + */ private Integer ydckcnt; + /** + * 鱼道或仿自然通道-出口高程,单位:m + */ private BigDecimal ckhg; + /** + * 鱼道池室设计流速,单位:m/s + */ private BigDecimal ydcsv; + /** + * 鱼道每级池室长,单位:m + */ private Integer ydcscd; + /** + * 鱼道每级池室宽,单位:m + */ private Integer ydcskd; + /** + * 鱼道池室坡度 + */ private String ydcspd; + /** + * 鱼道池室数量,单位:个 + */ private Integer ydcscnt; + /** + * 鱼道休息池个数 + */ private Integer ydxxccnt; + /** + * 鱼道或仿自然通道-流速,单位:m/s + */ private BigDecimal v; + /** + * 仿自然通道断面形状 + */ private String fzrdmxz; - private String fzrtdz; + /** + * 仿自然通道长度*宽度 + */ + private String fzrtdsz; + /** + * 仿自然通道运行水深,单位:m + */ private BigDecimal fzryxwdp; + /** + * 仿自然通道坡降 + */ private BigDecimal fzrpj; - private String symtlcs; + /** + * 集运鱼系统或升鱼机-上游码头位置 + */ + private String symtlc; + /** + * 集运鱼系统或升鱼机-上游码头型式 + */ private String symtxs; - private String xymtlcs; + /** + * 集运鱼系统或升鱼机-下游码头位置 + */ + private String xymtlc; + /** + * 集运鱼系统或升鱼机-下游码头型式 + */ private String xymtxs; + /** + * 集运鱼系统或升鱼机-集诱鱼方式 + */ private String jyfs; + /** + * 集运鱼系统或升鱼机-运鱼设施方式 + */ private String yyfs; + /** + * 升鱼机集鱼槽数量,单位:个 + */ private Integer syjcnt; + /** + * 升鱼机集鱼槽进口高程,单位:m + */ private BigDecimal syjhg; + /** + * 升鱼机集鱼槽流量,单位:m3/s + */ private BigDecimal syjq; + /** + * 升鱼机断面尺寸(长*宽*高),单位:m + */ private String syjsz; + /** + * 升鱼机集鱼槽水深,单位:m + */ private BigDecimal syjwdp; + /** + * 设计过鱼规模,单位:尾 + */ private Long sjgycnt; - private String ZygyDx; + /** + * 主要过鱼对象{[code:鱼编码1,name:鱼名称1,数量],[code:鱼编码2,name:鱼名称2]...} + */ + private String zygydx; - private String ZygyDxms; + /** + * 主要过鱼对象描述 + */ + private String zygydxms; - private String JggyDx; + /** + * 兼顾过鱼对象{[code:鱼编码1,name:鱼名称1,数量],[code:鱼编码2,name:鱼名称2]...} + */ + private String jggydx; - private String JggyDxms; + /** + * 兼顾过鱼对象描述 + */ + private String jggydxms; + /** + * 过鱼时间 + */ private String gytm; + /** + * 运行时间 + */ private String yxtm; + /** + * 主要过鱼月份(多个月份用,隔开) + */ private String fpssmn; + /** + * 数据监测频次,单位:min + */ private Integer dtfrqcy; + /** + * 基本特性参数(文字描述) + */ private String jbtxcs; + /** + * 设施是否实现鱼类上行 0=否 1=是 + */ private Integer isUp; + /** + * 设施是否实现鱼类下行 0=否 1=是 + */ private Integer isDown; + /** + * 备注 + */ private String remark; + /** + * 数据来源 + */ private String vlsr; + /** + * 数据来源时间 + */ private Date vlsrTm; } \ No newline at end of file From a3e08f0db7a859e4c550deab94bbf537bc52409f Mon Sep 17 00:00:00 2001 From: tangwei Date: Thu, 23 Apr 2026 08:29:03 +0800 Subject: [PATCH 07/13] =?UTF-8?q?fix:=20=E6=96=B0=E5=A2=9E=E5=9F=BA?= =?UTF-8?q?=E5=9C=B0=E3=80=81=E7=94=B5=E7=AB=99=E3=80=81=E8=AE=BE=E6=96=BD?= =?UTF-8?q?=EF=BC=8C=E9=B1=BC=E7=A7=8D=E7=B1=BB=E4=B8=8B=E6=8B=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../env/controller/SdEngInfoBHController.java | 9 ++++++++- .../env/controller/SdFishDictoryBController.java | 8 ++++++++ .../platform/env/controller/SdFpssBHController.java | 7 +++++++ .../env/controller/SdHydrobaseController.java | 10 ++++++++-- .../platform/env/service/ISdEngInfoBHService.java | 7 ++++++- .../yfd/platform/env/service/ISdFpssBHService.java | 5 +++++ .../platform/env/service/ISdHydrobaseService.java | 7 ++++++- .../env/service/impl/SdEngInfoBHServiceImpl.java | 13 ++++++++++++- .../env/service/impl/SdFpssBHServiceImpl.java | 10 ++++++++++ .../env/service/impl/SdHydrobaseServiceImpl.java | 11 ++++++++++- 10 files changed, 80 insertions(+), 7 deletions(-) diff --git a/backend/src/main/java/com/yfd/platform/env/controller/SdEngInfoBHController.java b/backend/src/main/java/com/yfd/platform/env/controller/SdEngInfoBHController.java index bff8c2c..aac18b6 100644 --- a/backend/src/main/java/com/yfd/platform/env/controller/SdEngInfoBHController.java +++ b/backend/src/main/java/com/yfd/platform/env/controller/SdEngInfoBHController.java @@ -69,6 +69,13 @@ public class SdEngInfoBHController { return ResponseResult.successData(engInfoBHService.getByRvcd(rvcd)); } + @GetMapping("/dropdown") + @Operation(summary = "电站下拉列表(根据基地编码筛选 + 支持名称模糊搜索)") + public ResponseResult dropdown(@RequestParam(required = false) String baseId, + @RequestParam(required = false) String ennm) { + return ResponseResult.successData(engInfoBHService.selectForDropdown(baseId, ennm)); + } + @Log(module = "电站管理", value = "新增电站") @PostMapping("/add") @Operation(summary = "新增电站") @@ -92,4 +99,4 @@ public class SdEngInfoBHController { boolean result = engInfoBHService.deleteEngInfo(stcd); return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败"); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java b/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java index fc8c878..c39e6a0 100644 --- a/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java +++ b/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java @@ -1,5 +1,7 @@ package com.yfd.platform.env.controller; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.annotation.Log; import com.yfd.platform.config.ResponseResult; @@ -45,6 +47,12 @@ public class SdFishDictoryBController { return ResponseResult.successData(sdFishDictoryBService.list()); } + @GetMapping("/listByName") + @Operation(summary = "根据名称查询所有鱼类字典") + public ResponseResult listByName( @RequestParam(required = false) String name) { + return ResponseResult.successData(sdFishDictoryBService.list(new LambdaQueryWrapper().eq(StrUtil.isNotBlank( name),SdFishDictoryB::getName, name))); + } + @GetMapping("/getById") @Operation(summary = "根据ID查询鱼类字典") public ResponseResult getById(@RequestParam String id) { diff --git a/backend/src/main/java/com/yfd/platform/env/controller/SdFpssBHController.java b/backend/src/main/java/com/yfd/platform/env/controller/SdFpssBHController.java index 0062657..5af03b1 100644 --- a/backend/src/main/java/com/yfd/platform/env/controller/SdFpssBHController.java +++ b/backend/src/main/java/com/yfd/platform/env/controller/SdFpssBHController.java @@ -57,6 +57,13 @@ public class SdFpssBHController { return ResponseResult.successData(sdFpssBHService.getByRstcd(rstcd)); } + @GetMapping("/dropdown") + @Operation(summary = "设施下拉列表(根据电站编码筛选 + 支持编码模糊搜索)") + public ResponseResult dropdown(@RequestParam(required = false) String rstcd, + @RequestParam(required = false) String stnm) { + return ResponseResult.successData(sdFpssBHService.selectForDropdown(rstcd, stnm)); + } + @Log(module = "过鱼设施管理", value = "新增过鱼设施") @PostMapping("/add") @Operation(summary = "新增过鱼设施") diff --git a/backend/src/main/java/com/yfd/platform/env/controller/SdHydrobaseController.java b/backend/src/main/java/com/yfd/platform/env/controller/SdHydrobaseController.java index 581f987..a48ba59 100644 --- a/backend/src/main/java/com/yfd/platform/env/controller/SdHydrobaseController.java +++ b/backend/src/main/java/com/yfd/platform/env/controller/SdHydrobaseController.java @@ -7,9 +7,9 @@ import com.yfd.platform.env.domain.SdHydrobase; import com.yfd.platform.env.service.ISdHydrobaseService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; import org.springframework.web.bind.annotation.*; -import jakarta.annotation.Resource; import java.util.List; /** @@ -62,6 +62,12 @@ public class SdHydrobaseController { return ResponseResult.successData(hydrobaseService.getById(baseid)); } + @GetMapping("/dropdown") + @Operation(summary = "基地下拉列表(支持名称模糊搜索)") + public ResponseResult dropdown(@RequestParam(required = false) String basename) { + return ResponseResult.successData(hydrobaseService.selectForDropdown(basename)); + } + // @Log(module = "基地管理", value = "新增基地") @PostMapping("/add") @Operation(summary = "新增基地") @@ -85,4 +91,4 @@ public class SdHydrobaseController { boolean result = hydrobaseService.deleteHydrobase(baseid); return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败"); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/service/ISdEngInfoBHService.java b/backend/src/main/java/com/yfd/platform/env/service/ISdEngInfoBHService.java index 5fcccc8..ab65aea 100644 --- a/backend/src/main/java/com/yfd/platform/env/service/ISdEngInfoBHService.java +++ b/backend/src/main/java/com/yfd/platform/env/service/ISdEngInfoBHService.java @@ -33,6 +33,11 @@ public interface ISdEngInfoBHService extends IService { */ List getByRvcd(String rvcd); + /** + * 电站下拉列表(根据基地编码筛选 + 支持名称模糊搜索) + */ + List selectForDropdown(String baseId, String ennm); + /** * 新增电站 */ @@ -47,4 +52,4 @@ public interface ISdEngInfoBHService extends IService { * 删除电站 */ boolean deleteEngInfo(String stcd); -} +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/service/ISdFpssBHService.java b/backend/src/main/java/com/yfd/platform/env/service/ISdFpssBHService.java index 3acdb85..8f7dea4 100644 --- a/backend/src/main/java/com/yfd/platform/env/service/ISdFpssBHService.java +++ b/backend/src/main/java/com/yfd/platform/env/service/ISdFpssBHService.java @@ -12,6 +12,11 @@ public interface ISdFpssBHService extends IService { List getByRstcd(String rstcd); + /** + * 设施下拉列表(根据电站编码筛选 + 支持名称模糊搜索) + */ + List selectForDropdown(String rstcd, String stnm); + boolean add(SdFpssBH sdFpssBH); boolean updateById(SdFpssBH sdFpssBH); diff --git a/backend/src/main/java/com/yfd/platform/env/service/ISdHydrobaseService.java b/backend/src/main/java/com/yfd/platform/env/service/ISdHydrobaseService.java index f00451a..92a94e3 100644 --- a/backend/src/main/java/com/yfd/platform/env/service/ISdHydrobaseService.java +++ b/backend/src/main/java/com/yfd/platform/env/service/ISdHydrobaseService.java @@ -28,6 +28,11 @@ public interface ISdHydrobaseService extends IService { */ List getRootList(); + /** + * 基地下拉列表(支持名称模糊搜索) + */ + List selectForDropdown(String basename); + /** * 新增基地 */ @@ -42,4 +47,4 @@ public interface ISdHydrobaseService extends IService { * 删除基地 */ boolean deleteHydrobase(String baseid); -} +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/service/impl/SdEngInfoBHServiceImpl.java b/backend/src/main/java/com/yfd/platform/env/service/impl/SdEngInfoBHServiceImpl.java index a9e52b4..8b49d15 100644 --- a/backend/src/main/java/com/yfd/platform/env/service/impl/SdEngInfoBHServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/env/service/impl/SdEngInfoBHServiceImpl.java @@ -7,6 +7,7 @@ import com.yfd.platform.env.mapper.SdEngInfoBHMapper; import com.yfd.platform.env.service.ISdEngInfoBHService; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; import java.util.List; @@ -48,6 +49,16 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl selectForDropdown(String baseId, String ennm) { + return this.lambdaQuery() + .eq(StringUtils.hasText(baseId), SdEngInfoBH::getBaseId, baseId) + .like(StringUtils.hasText(ennm), SdEngInfoBH::getEnnm, ennm) + .select(SdEngInfoBH::getStcd, SdEngInfoBH::getEnnm, SdEngInfoBH::getBaseId) + .orderByAsc(SdEngInfoBH::getOrderIndex) + .list(); + } + @Override public boolean addEngInfo(SdEngInfoBH engInfo) { return this.save(engInfo); @@ -62,4 +73,4 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl i return list(wrapper); } + @Override + public List selectForDropdown(String rstcd, String stnm) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(StringUtils.hasText(rstcd), SdFpssBH::getRstcd, rstcd) + .like(StringUtils.hasText(stnm), SdFpssBH::getStnm, stnm) + .select(SdFpssBH::getStcd, SdFpssBH::getStnm, SdFpssBH::getSttp,SdFpssBH::getRstcd) + .orderByDesc(SdFpssBH::getOrderIndex); + return list(wrapper); + } + @Override public boolean add(SdFpssBH sdFpssBH) { return save(sdFpssBH); diff --git a/backend/src/main/java/com/yfd/platform/env/service/impl/SdHydrobaseServiceImpl.java b/backend/src/main/java/com/yfd/platform/env/service/impl/SdHydrobaseServiceImpl.java index cafc2cf..4236ea4 100644 --- a/backend/src/main/java/com/yfd/platform/env/service/impl/SdHydrobaseServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/env/service/impl/SdHydrobaseServiceImpl.java @@ -6,6 +6,7 @@ import com.yfd.platform.env.domain.SdHydrobase; import com.yfd.platform.env.mapper.SdHydrobaseMapper; import com.yfd.platform.env.service.ISdHydrobaseService; import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; import java.util.List; @@ -42,6 +43,14 @@ public class SdHydrobaseServiceImpl extends ServiceImpl selectForDropdown(String basename) { + return this.lambdaQuery() + .like(StringUtils.hasText(basename), SdHydrobase::getBasename, basename) + .orderByAsc(SdHydrobase::getOrderIndex) + .list(); + } + @Override public boolean addHydrobase(SdHydrobase hydrobase) { return this.save(hydrobase); @@ -56,4 +65,4 @@ public class SdHydrobaseServiceImpl extends ServiceImpl Date: Thu, 23 Apr 2026 10:10:29 +0800 Subject: [PATCH 08/13] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FishDraftDataController.java | 6 +- .../data/service/IFishDraftDataService.java | 3 +- .../impl/FishDraftDataServiceImpl.java | 21 +- .../controller/SdFishDictoryBController.java | 45 +-- .../platform/utils/DataSourceRequestUtil.java | 302 ++++++++++++++++++ 5 files changed, 344 insertions(+), 33 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.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 ef26c1a..04a67cc 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 @@ -47,11 +47,7 @@ public class FishDraftDataController { @Operation(summary = "分页查询过鱼数据") public ResponseResult queryPageList(@RequestBody DataSourceRequest dataSourceRequest) { Page page = KendoUtil.getPage(dataSourceRequest); - DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); - String stcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd"); - String status = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "status"); - String ftp = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "ftp"); - Page result = fishDraftDataService.queryPageList(page, stcd, status, ftp); + Page result = fishDraftDataService.queryPageList(page, dataSourceRequest); return ResponseResult.successData(result); } diff --git a/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java b/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java index a0ece5f..cfcca39 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java +++ b/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java @@ -2,6 +2,7 @@ package com.yfd.platform.data.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; +import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.data.domain.FishDraftData; import java.util.List; @@ -16,7 +17,7 @@ public interface IFishDraftDataService extends IService { /** * 分页查询草稿数据 */ - Page queryPageList(Page page, String stcd, String status, String ftp); + Page queryPageList(Page page, DataSourceRequest dataSourceRequest); /** * 根据审批批次ID查询 diff --git a/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java index 736838a..2abf0ec 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java @@ -2,11 +2,14 @@ package com.yfd.platform.data.service.impl; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.yfd.platform.common.DataSourceLoadOptionsBase; +import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.data.domain.FishDraftData; import com.yfd.platform.data.mapper.FishDraftDataMapper; import com.yfd.platform.data.service.IApprovalChangeLogService; import com.yfd.platform.data.service.IApprovalMainService; import com.yfd.platform.data.service.IFishDraftDataService; +import com.yfd.platform.utils.QgcQueryWrapperUtil; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -33,14 +36,16 @@ public class FishDraftDataServiceImpl extends ServiceImpl queryPageList(Page page, String stcd, String status, String ftp) { - return this.page(page, this.lambdaQuery() - .eq(StringUtils.hasText(stcd), FishDraftData::getStcd, stcd) - .eq(StringUtils.hasText(status), FishDraftData::getStatus, status) - .like(StringUtils.hasText(ftp), FishDraftData::getFtp, ftp) - .eq(FishDraftData::getDeletedFlag, 0) - .orderByDesc(FishDraftData::getTm) - .getWrapper()); + public Page queryPageList(Page page, DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); + String stcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd"); + String rstcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "rstcd"); + String baseId = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "baseId"); + String direction = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "direction"); + String status = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "status"); + + StringBuilder sql = new StringBuilder(); + return null; } @Override diff --git a/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java b/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java index c39e6a0..25d4586 100644 --- a/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java +++ b/backend/src/main/java/com/yfd/platform/env/controller/SdFishDictoryBController.java @@ -1,17 +1,19 @@ package com.yfd.platform.env.controller; import cn.hutool.core.util.StrUtil; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.annotation.Log; +import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.env.domain.SdFishDictoryB; import com.yfd.platform.env.service.ISdFishDictoryBService; +import com.yfd.platform.utils.DataSourceRequestUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import org.springframework.web.bind.annotation.*; +import java.util.Arrays; import java.util.List; /** @@ -27,30 +29,35 @@ public class SdFishDictoryBController { @Resource private ISdFishDictoryBService sdFishDictoryBService; - @GetMapping("/queryPageList") - @Operation(summary = "分页查询鱼类字典列表") - public ResponseResult queryPageList( - @RequestParam(required = false) String name, - @RequestParam(required = false) String code, - @RequestParam(required = false) Integer type, - @RequestParam(required = false) Integer rare, - @RequestParam(defaultValue = "1") Long pageNum, - @RequestParam(defaultValue = "10") Long pageSize) { - Page page = new Page<>(pageNum, pageSize); - Page result = sdFishDictoryBService.selectPage(name, code, type, rare, page); - return ResponseResult.successData(result); + @PostMapping("/queryPageList") + @Operation(summary = "分页查询鱼类字典列表(支持动态过滤和排序)") + public ResponseResult queryPageList(@RequestBody DataSourceRequest request) { + Page page = DataSourceRequestUtil.executeQuery( + request, + SdFishDictoryB.class, + sdFishDictoryBService + ); + return ResponseResult.successData(page); } - @GetMapping("/list") - @Operation(summary = "查询所有鱼类字典") - public ResponseResult list() { - return ResponseResult.successData(sdFishDictoryBService.list()); + @PostMapping("/list") + @Operation(summary = "查询鱼类字典列表(支持动态过滤和排序,不分页)") + public ResponseResult list(@RequestBody DataSourceRequest request) { + List list = DataSourceRequestUtil.executeList( + request, + SdFishDictoryB.class, + sdFishDictoryBService + ); + return ResponseResult.successData(list); } @GetMapping("/listByName") @Operation(summary = "根据名称查询所有鱼类字典") - public ResponseResult listByName( @RequestParam(required = false) String name) { - return ResponseResult.successData(sdFishDictoryBService.list(new LambdaQueryWrapper().eq(StrUtil.isNotBlank( name),SdFishDictoryB::getName, name))); + public ResponseResult listByName(@RequestParam(required = false) String name) { + return ResponseResult.successData(sdFishDictoryBService.list( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(StrUtil.isNotBlank(name), SdFishDictoryB::getName, name) + )); } @GetMapping("/getById") diff --git a/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java b/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java new file mode 100644 index 0000000..08e156f --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/utils/DataSourceRequestUtil.java @@ -0,0 +1,302 @@ +package com.yfd.platform.utils; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; +import com.baomidou.mybatisplus.core.metadata.TableInfo; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.common.DataSourceRequest; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +public class DataSourceRequestUtil { + + private static final Pattern SAFE_IDENTIFIER = Pattern.compile("^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*$"); + + public static Page getPage(DataSourceRequest request) { + if (request == null) { + return null; + } + int take = request.getTake(); + int skip = request.getSkip(); + if (take <= 0) { + return null; + } + Page page = new Page<>(); + page.setSize((long) take); + page.setCurrent(skip / take + 1L); + return page; + } + + public static QueryWrapper buildWrapper(DataSourceRequest request, Class entityClass) { + return buildWrapper(request, entityClass, null, null); + } + + public static QueryWrapper buildWrapper(DataSourceRequest request, Class entityClass, + Map fieldMapping, + List excludeFields) { + QueryWrapper wrapper = new QueryWrapper<>(); + + if (request == null || entityClass == null) { + return wrapper; + } + + List excludes = excludeFields != null ? excludeFields : new ArrayList<>(); + + applyFilters(request.getFilter(), wrapper, entityClass, fieldMapping, excludes, "and"); + + applySort(request.getSort(), wrapper, entityClass); + + return wrapper; + } + + public static QueryWrapper buildQueryWrapper(DataSourceRequest request, Class entityClass) { + return buildQueryWrapper(request, entityClass, null, null); + } + + public static QueryWrapper buildQueryWrapper(DataSourceRequest request, Class entityClass, + Map fieldMapping, + List excludeFields) { + QueryWrapper wrapper = new QueryWrapper<>(); + + if (request == null || entityClass == null) { + return wrapper; + } + + List excludes = excludeFields != null ? excludeFields : new ArrayList<>(); + + applyFilters(request.getFilter(), wrapper, entityClass, fieldMapping, excludes, "and"); + + applySort(request.getSort(), wrapper, entityClass); + + return wrapper; + } + + public static Page executeQuery(DataSourceRequest request, Class entityClass, + com.baomidou.mybatisplus.extension.service.IService service) { + return executeQuery(request, entityClass, service, null, null); + } + + public static Page executeQuery(DataSourceRequest request, Class entityClass, + com.baomidou.mybatisplus.extension.service.IService service, + Map fieldMapping, + List excludeFields) { + if (request == null || service == null) { + return new Page<>(); + } + + QueryWrapper wrapper = buildQueryWrapper(request, entityClass, fieldMapping, excludeFields); + Page page = getPage(request); + + if (page != null) { + return service.page(page, wrapper); + } else { + List list = service.list(wrapper); + Page resultPage = new Page<>(); + resultPage.setRecords(list); + resultPage.setTotal(list.size()); + resultPage.setSize((long) list.size()); + resultPage.setCurrent(1L); + return resultPage; + } + } + + public static List executeList(DataSourceRequest request, Class entityClass, + com.baomidou.mybatisplus.extension.service.IService service) { + return executeList(request, entityClass, service, null, null); + } + + public static List executeList(DataSourceRequest request, Class entityClass, + com.baomidou.mybatisplus.extension.service.IService service, + Map fieldMapping, + List excludeFields) { + if (request == null || service == null) { + return new ArrayList<>(); + } + + QueryWrapper wrapper = buildQueryWrapper(request, entityClass, fieldMapping, excludeFields); + return service.list(wrapper); + } + + private static void applyFilters(DataSourceRequest.FilterDescriptor filter, + QueryWrapper wrapper, + Class entityClass, + Map fieldMapping, + List excludeFields, + String parentLogic) { + if (filter == null) { + return; + } + + List filters = filter.getFilters(); + if (CollectionUtil.isEmpty(filters)) { + String field = filter.getField(); + if (StrUtil.isBlank(field)) { + return; + } + + if (excludeFields.contains(field)) { + return; + } + + String columnName = getColumnName(field, entityClass, fieldMapping); + Object value = filter.getValue(); + String operator = filter.getOperator(); + + applySingleCondition(wrapper, columnName, operator, value); + return; + } + + if (filters.size() == 1) { + applyFilters(filters.get(0), wrapper, entityClass, fieldMapping, excludeFields, parentLogic); + return; + } + + String logic = filter.getLogic(); + boolean isAnd = "and".equalsIgnoreCase(logic); + + List> conditionGroups = new ArrayList<>(); + 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); + if (i > 0) { + logics.add(isAnd ? "and" : "or"); + } + } + } + + for (int i = 0; i < conditionGroups.size(); i++) { + if (i == 0) { + mergeWrapper(wrapper, conditionGroups.get(i)); + } else { + String lgc = logics.get(i - 1); + if ("or".equalsIgnoreCase(lgc)) { + wrapper.or(); + } + mergeWrapper(wrapper, conditionGroups.get(i)); + } + } + } + + private static boolean hasConditions(QueryWrapper wrapper) { + return wrapper instanceof QueryWrapper && !wrapper.getExpression().getNormal().isEmpty(); + } + + private static void mergeWrapper(QueryWrapper target, QueryWrapper source) { + target.getExpression().getNormal().addAll(source.getExpression().getNormal()); + } + + private static void applySingleCondition(QueryWrapper wrapper, String columnName, + String operator, Object value) { + if (columnName == null) { + return; + } + + String op = operator != null ? operator.trim().toLowerCase() : "eq"; + + switch (op) { + case "eq" -> wrapper.eq(columnName, value); + case "neq", "<>" -> wrapper.ne(columnName, value); + case "gt" -> wrapper.gt(columnName, value); + case "gte", ">=" -> wrapper.ge(columnName, value); + case "lt" -> wrapper.lt(columnName, value); + case "lte", "<=" -> wrapper.le(columnName, value); + case "contains" -> wrapper.like(columnName, value); + case "notcontains" -> wrapper.notLike(columnName, value); + case "startswith" -> wrapper.likeRight(columnName, value); + case "endswith" -> wrapper.likeLeft(columnName, value); + case "isnull" -> wrapper.isNull(columnName); + case "isnotnull" -> wrapper.isNotNull(columnName); + case "isempty" -> wrapper.eq(columnName, ""); + case "isnotempty" -> wrapper.ne(columnName, ""); + case "in" -> { + if (value instanceof Iterable) { + wrapper.in(columnName, (Iterable) value); + } else if (value instanceof Object[]) { + wrapper.in(columnName, (Object[]) value); + } + } + case "ni", "notin" -> { + if (value instanceof Iterable) { + wrapper.notIn(columnName, (Iterable) value); + } else if (value instanceof Object[]) { + wrapper.notIn(columnName, (Object[]) value); + } + } + default -> wrapper.eq(columnName, value); + } + } + + private static void applySort(List sorts, + QueryWrapper wrapper, + Class entityClass) { + if (CollectionUtil.isEmpty(sorts)) { + return; + } + + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + + String columnName = getColumnName(sort.getField(), entityClass, null); + if (columnName == null) { + continue; + } + + String dir = sort.getDir(); + if ("desc".equalsIgnoreCase(dir)) { + wrapper.orderByDesc(columnName); + } else { + wrapper.orderByAsc(columnName); + } + } + } + + private static String getColumnName(String property, Class entityClass, + Map fieldMapping) { + if (property == null || property.isBlank()) { + return null; + } + + if (fieldMapping != null && fieldMapping.containsKey(property)) { + return fieldMapping.get(property); + } + + TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass); + if (tableInfo == null) { + return requireSafeIdentifier(property); + } + + if (property.equals(tableInfo.getKeyProperty())) { + return tableInfo.getKeyColumn(); + } + + List fieldInfos = tableInfo.getFieldList().stream() + .filter(f -> property.equals(f.getProperty())) + .toList(); + + if (!fieldInfos.isEmpty()) { + return fieldInfos.get(0).getColumn(); + } + + return requireSafeIdentifier(property); + } + + private static String requireSafeIdentifier(String identifier) { + String id = identifier == null ? "" : identifier.trim(); + if (id.isEmpty() || !SAFE_IDENTIFIER.matcher(id).matches()) { + return id; + } + return id; + } +} \ No newline at end of file From 89f2b34d565cee75938c465a4b51ab14a89f0a58 Mon Sep 17 00:00:00 2001 From: tangwei Date: Thu, 23 Apr 2026 10:53:10 +0800 Subject: [PATCH 09/13] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E8=BF=87?= =?UTF-8?q?=E9=B1=BC=E8=AE=BE=E6=96=BD=E8=8D=89=E7=A8=BF=E8=A1=A8=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FishDraftDataController.java | 16 +- .../data/domain/vo/FishDraftDataVO.java | 202 ++++++++++++++++++ .../data/mapper/FishDraftDataMapper.java | 22 ++ .../data/service/IFishDraftDataService.java | 10 +- .../impl/FishDraftDataServiceImpl.java | 23 +- .../mapper/data/FishDraftDataMapper.xml | 193 +++++++++++++++++ 6 files changed, 452 insertions(+), 14 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/data/domain/vo/FishDraftDataVO.java create mode 100644 backend/src/main/resources/mapper/data/FishDraftDataMapper.xml 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 04a67cc..7f4557c 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,18 +1,17 @@ package com.yfd.platform.data.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.yfd.platform.common.DataSourceLoadOptionsBase; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.data.domain.FishDraftData; import com.yfd.platform.data.domain.FishImportRequest; import com.yfd.platform.data.domain.FishImportResult; import com.yfd.platform.data.domain.ImportTask; +import com.yfd.platform.data.domain.vo.FishDraftDataVO; import com.yfd.platform.data.service.IFishDraftDataService; import com.yfd.platform.data.service.IFishImportService; import com.yfd.platform.data.service.IImportTaskService; import com.yfd.platform.utils.KendoUtil; -import com.yfd.platform.utils.QgcQueryWrapperUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; @@ -44,17 +43,16 @@ public class FishDraftDataController { private IImportTaskService importTaskService; @PostMapping("/page") - @Operation(summary = "分页查询过鱼数据") + @Operation(summary = "分页查询过鱼数据(关联电站和设施)") public ResponseResult queryPageList(@RequestBody DataSourceRequest dataSourceRequest) { - Page page = KendoUtil.getPage(dataSourceRequest); - Page result = fishDraftDataService.queryPageList(page, dataSourceRequest); + Page result = fishDraftDataService.queryPageList( dataSourceRequest); return ResponseResult.successData(result); } - @GetMapping("/list") - @Operation(summary = "查询过鱼数据列表") - public ResponseResult list() { - List list = fishDraftDataService.list(); + @PostMapping("/list") + @Operation(summary = "查询过鱼数据列表(关联电站和设施,不分页)") + public ResponseResult list(@RequestBody DataSourceRequest dataSourceRequest) { + List list = fishDraftDataService.queryJoinList(dataSourceRequest); return ResponseResult.successData(list); } diff --git a/backend/src/main/java/com/yfd/platform/data/domain/vo/FishDraftDataVO.java b/backend/src/main/java/com/yfd/platform/data/domain/vo/FishDraftDataVO.java new file mode 100644 index 0000000..78ea3d5 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/data/domain/vo/FishDraftDataVO.java @@ -0,0 +1,202 @@ +package com.yfd.platform.data.domain.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 过鱼数据关联查询VO + *

+ */ +@Data +public class FishDraftDataVO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + private String id; + + /** + * 过鱼设施编码 + */ + private String stcd; + + /** + * 填报时间 + */ + private Date tm; + + /** + * 鱼类 + */ + private String ftp; + + /** + * 鱼类全长 + */ + private String fsz; + + /** + * 过鱼数量 + */ + private Integer fcnt; + + /** + * 平均体重 + */ + private String fwet; + + /** + * 开始日期 + */ + private Date strdt; + + /** + * 结束日期 + */ + private Date enddt; + + /** + * 游向(上行/下行/上行折返/下行折返) + */ + private String direction; + + /** + * 年份 + */ + private Integer yr; + + /** + * 主要月份 + */ + private Integer mouth; + + /** + * 过鱼视频文件路径 + */ + private String vdpth; + + /** + * 图片文件路径 + */ + private String picpth; + + /** + * 是否鱼苗(0否 1是) + */ + private Integer isfs; + + /** + * 数据来源(MANUAL手工 / IMPORT导入 / AUTO自动) + */ + private String sourceType; + + /** + * 审批批次ID + */ + private Long approvalId; + + /** + * 状态(DRAFT未提交 / SUBMITTED已提交 / APPROVED已通过 / REJECTED已驳回) + */ + private String status; + + /** + * 锁定标识(1锁定不可编辑 0可编辑) + */ + private Integer lockFlag; + + /** + * 提交审批时间 + */ + private Date submitTime; + + /** + * 审批完成时间 + */ + private Date approveTime; + + /** + * 删除标记(0未删除 1已删除) + */ + private Integer deletedFlag; + + /** + * 删除人 + */ + private String deletedBy; + + /** + * 删除时间 + */ + private Date deletedAt; + + /** + * 创建时间 + */ + private Date createdAt; + + /** + * 创建人 + */ + private String createdBy; + + /** + * 更新时间 + */ + private Date updatedAt; + + /** + * 更新人 + */ + private String updatedBy; + + /** + * 设施名称(过鱼设施表) + */ + private String stnm; + + /** + * 过鱼设施类型(过鱼设施表) + */ + private String sttp; + + /** + * 所属电站编码(过鱼设施表) + */ + private String rstcd; + + /** + * 电站名称(电站表) + */ + private String ennm; + + /** + * 所属基地编码(电站表) + */ + private String baseId; + + /** + * 流域编码(电站表) + */ + private String rvcd; + + /** + * 电站经度(电站表) + */ + private Double lgtd; + + /** + * 电站纬度(电站表) + */ + private Double lttd; + + /** + * 排序字段 + */ + private Integer orderIndex; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/mapper/FishDraftDataMapper.java b/backend/src/main/java/com/yfd/platform/data/mapper/FishDraftDataMapper.java index a83ccad..e28bfaa 100644 --- a/backend/src/main/java/com/yfd/platform/data/mapper/FishDraftDataMapper.java +++ b/backend/src/main/java/com/yfd/platform/data/mapper/FishDraftDataMapper.java @@ -1,7 +1,9 @@ package com.yfd.platform.data.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.data.domain.FishDraftData; +import com.yfd.platform.data.domain.vo.FishDraftDataVO; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; @@ -14,6 +16,26 @@ import java.util.List; */ public interface FishDraftDataMapper extends BaseMapper { + /** + * 关联查询过鱼数据(分页) + */ + Page selectJoinPage(Page page, + @Param("stcd") String stcd, + @Param("rstcd") String rstcd, + @Param("baseId") String baseId, + @Param("direction") String direction, + @Param("status") String status, + @Param("ftp") String ftp); + + /** + * 关联查询过鱼数据(不分页) + */ + List selectJoinList(@Param("stcd") String stcd, + @Param("rstcd") String rstcd, + @Param("baseId") String baseId, + @Param("direction") String direction, + @Param("status") String status); + /** * 根据审批批次ID查询草稿数据 */ diff --git a/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java b/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java index cfcca39..f85776a 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java +++ b/backend/src/main/java/com/yfd/platform/data/service/IFishDraftDataService.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.data.domain.FishDraftData; +import com.yfd.platform.data.domain.vo.FishDraftDataVO; import java.util.List; @@ -15,9 +16,14 @@ import java.util.List; public interface IFishDraftDataService extends IService { /** - * 分页查询草稿数据 + * 分页查询草稿数据(关联电站和设施表) */ - Page queryPageList(Page page, DataSourceRequest dataSourceRequest); + Page queryPageList(DataSourceRequest dataSourceRequest); + + /** + * 查询草稿数据列表(关联电站和设施表,不分页) + */ + List queryJoinList(DataSourceRequest dataSourceRequest); /** * 根据审批批次ID查询 diff --git a/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java index 2abf0ec..dfbd057 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/data/service/impl/FishDraftDataServiceImpl.java @@ -5,10 +5,12 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yfd.platform.common.DataSourceLoadOptionsBase; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.data.domain.FishDraftData; +import com.yfd.platform.data.domain.vo.FishDraftDataVO; import com.yfd.platform.data.mapper.FishDraftDataMapper; import com.yfd.platform.data.service.IApprovalChangeLogService; import com.yfd.platform.data.service.IApprovalMainService; import com.yfd.platform.data.service.IFishDraftDataService; +import com.yfd.platform.utils.KendoUtil; import com.yfd.platform.utils.QgcQueryWrapperUtil; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; @@ -36,7 +38,23 @@ public class FishDraftDataServiceImpl extends ServiceImpl queryPageList(Page page, DataSourceRequest dataSourceRequest) { + public Page queryPageList(DataSourceRequest dataSourceRequest) { + Page page = KendoUtil.getPage(dataSourceRequest); + DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); + String stcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd"); + String rstcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "rstcd"); + String baseId = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "baseId"); + String ftp = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "ftp"); + String direction = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "direction"); + String status = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "status"); + + Page resultPage = fishDraftDataMapper.selectJoinPage( + page, stcd, rstcd, baseId, direction, status,ftp); + return resultPage; + } + + @Override + public List queryJoinList(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); String stcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd"); String rstcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "rstcd"); @@ -44,8 +62,7 @@ public class FishDraftDataServiceImpl extends ServiceImpl + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + D.ID, + D.STCD, + D.TM, + D.FTP, + D.FSZ, + D.FCNT, + D.FWET, + D.STRDT, + D.ENDDT, + D.DIRECTION, + D.YR, + D.MOUTH, + D.VDPTH, + D.PICPTH, + D.ISFS, + D.SOURCE_TYPE, + D.APPROVAL_ID, + D.STATUS, + D.LOCK_FLAG, + D.SUBMIT_TIME, + D.APPROVE_TIME, + D.DELETED_FLAG, + D.DELETED_BY, + D.DELETED_AT, + D.CREATED_AT, + D.CREATED_BY, + D.UPDATED_AT, + D.UPDATED_BY, + F.STNM, + F.STTP, + F.RSTCD, + E.ENNM, + E.BASE_ID, + E.RVCD, + E.LGTD, + E.LTTD, + E.ORDER_INDEX + + + + + + + + + From 4b63f9d00fb74a6f26633e74361684eff4cd787d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=85=B4=E5=87=AF?= <2448379534@qq.com> Date: Thu, 23 Apr 2026 18:33:39 +0800 Subject: [PATCH 10/13] =?UTF-8?q?=E6=9D=83=E9=99=90=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/views/login/index.vue | 8 ++++---- frontend/src/views/system/user/index.vue | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/src/views/login/index.vue b/frontend/src/views/login/index.vue index c104f90..a0b32db 100644 --- a/frontend/src/views/login/index.vue +++ b/frontend/src/views/login/index.vue @@ -159,7 +159,7 @@ > 登录 - 忘记密码 - + --> - + diff --git a/frontend/src/views/system/user/index.vue b/frontend/src/views/system/user/index.vue index 388b4ea..d81d66e 100644 --- a/frontend/src/views/system/user/index.vue +++ b/frontend/src/views/system/user/index.vue @@ -923,7 +923,7 @@ function handleClearSelection() { :header-cell-style="{ background: 'rgb(250 250 250)', color: ' #383838', height: '50px' }"> - + @@ -948,7 +948,7 @@ function handleClearSelection() { {{ dateFormat(scope.row.lastmodifydate) }} - +