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/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 ea55c4a..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
@@ -5,16 +5,24 @@ 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.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;
import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.IOException;
import java.util.Date;
import java.util.List;
+import java.util.UUID;
/**
*
@@ -29,18 +37,11 @@ public class FishDraftDataController {
@Resource
private IFishDraftDataService fishDraftDataService;
-// @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 IFishImportService fishImportService;
+
+ @Resource
+ private IImportTaskService importTaskService;
@PostMapping("/page")
@Operation(summary = "分页查询过鱼数据")
@@ -63,14 +64,14 @@ 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);
}
@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);
}
@@ -105,7 +106,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("删除失败");
@@ -113,7 +114,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("提交失败");
@@ -121,7 +122,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("提交失败");
@@ -129,14 +130,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("解锁失败");
}
@@ -144,8 +145,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,15 +152,100 @@ 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("修改失败");
}
@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("/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(".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.setImportNo(importNo);
+ request.setUploadUserId(uploadUserId);
+ request.setBizType("FISH");
+
+ 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 (Exception e) {
+ importTaskService.markFailed(taskId, "导入失败: " + e.getMessage());
+ return ResponseResult.error("导入失败: " + e.getMessage());
+ }
+ }
+
+ @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());
+ }
+ }
}
\ 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..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
@@ -41,6 +41,7 @@ public class FishDraftData implements Serializable {
*/
private String ftp;
+
/**
* 鱼类全长
*/
@@ -125,28 +126,10 @@ public class FishDraftData implements Serializable {
/**
* 水温
*/
- @TableField(exist = false)
+// @TableField(exist = false)
private BigDecimal wt;
- /**
- * 电站名称
- */
- @TableField(exist = false)
- private String engName;
-
- /**
- * 基地名称
- */
- @TableField(exist = false)
- private String baseName;
-
- /**
- * 设施名称
- */
- @TableField(exist = false)
- private String fPname;
-
/**
* 审批完成时间
@@ -177,6 +160,7 @@ public class FishDraftData implements Serializable {
/**
* 创建人
*/
+ @TableField(fill = FieldFill.INSERT)
private String createdBy;
/**
@@ -188,5 +172,44 @@ 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/domain/FishImportRequest.java b/backend/src/main/java/com/yfd/platform/data/domain/FishImportRequest.java
new file mode 100644
index 0000000..3d063da
--- /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 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
new file mode 100644
index 0000000..6a5ecaa
--- /dev/null
+++ b/backend/src/main/java/com/yfd/platform/data/domain/FishImportResult.java
@@ -0,0 +1,47 @@
+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 {
+
+ 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;
+ private String summary;
+
+ public FishImportResult() {
+ this.successRows = new ArrayList<>();
+ this.failedRows = new ArrayList<>();
+ this.unrecognizedFields = new ArrayList<>();
+ this.imageFiles = new LinkedHashMap<>();
+ this.videoFiles = new LinkedHashMap<>();
+ }
+
+ @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/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/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/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/IFishImportService.java b/backend/src/main/java/com/yfd/platform/data/service/IFishImportService.java
new file mode 100644
index 0000000..7a597ba
--- /dev/null
+++ b/backend/src/main/java/com/yfd/platform/data/service/IFishImportService.java
@@ -0,0 +1,21 @@
+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;
+
+/**
+ *
+ * 过鱼数据Excel导入服务接口
+ *
+ */
+public interface IFishImportService {
+
+ FishImportResult parseAndMapExcel(FishImportRequest request, InputStream inputStream);
+
+ 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/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 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
+ 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;
+ }
+
+ List unrecognizedHeaders = new ArrayList<>();
+ Map columnIndexMap = new HashMap<>(EXCEL_COLUMN_INDEX_MAPPING);
+
+ 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.getWarnings().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 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);
+ try {
+ switch (fieldName) {
+ 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());
+ }
+ }
+ break;
+ 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);
+ }
+ }
+ break;
+ case "tm":
+ if (!StringUtils.hasText(cellValue)) {
+ missingRequiredFields.add("过鱼时间");
+ } else {
+ Date tm = parseDate(cellValue);
+ if (tm == null) {
+ importRow.getWarnings().add("过鱼时间格式错误: " + cellValue);
+ }
+ data.setTm(tm);
+ }
+ break;
+ case "ftp":
+ 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":
+ 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());
+ break;
+ case "strdt":
+ data.setStrdt(parseDate(cellValue));
+ break;
+ case "enddt":
+ data.setEnddt(parseDate(cellValue));
+ break;
+ case "direction":
+ if (!StringUtils.hasText(cellValue)) {
+ missingRequiredFields.add("游向");
+ } else {
+ String direction = resolveDirection(cellValue.trim(), importRow);
+ data.setDirection(direction);
+ }
+ 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":
+ 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) {
+ e.printStackTrace();
+// importRow.getWarnings().add("字段[" + fieldName + "]解析异常: " + e.getMessage());
+ }
+ }
+ importRow.setData(data);
+ 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_NAME_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_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;
+ }
+ 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 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;
+ }
+ 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 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 "";
+ }
+ 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 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") || v.contains("采集")) {
+ return "AUTO";
+ } else if (v.contains("导入") || v.contains("import")) {
+ return "IMPORT";
+ }
+ 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 extends ZipEntry> 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/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..d7b4f68
--- /dev/null
+++ b/backend/src/main/java/com/yfd/platform/env/domain/SdFishDictoryB.java
@@ -0,0 +1,272 @@
+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;
+
+ /**
+ * 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
new file mode 100644
index 0000000..993b6c5
--- /dev/null
+++ b/backend/src/main/java/com/yfd/platform/env/domain/SdFpssBH.java
@@ -0,0 +1,382 @@
+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;
+
+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 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 fzrtdsz;
+
+ /**
+ * 仿自然通道运行水深,单位:m
+ */
+ private BigDecimal fzryxwdp;
+
+ /**
+ * 仿自然通道坡降
+ */
+ private BigDecimal fzrpj;
+
+ /**
+ * 集运鱼系统或升鱼机-上游码头位置
+ */
+ private String symtlc;
+
+ /**
+ * 集运鱼系统或升鱼机-上游码头型式
+ */
+ private String symtxs;
+
+ /**
+ * 集运鱼系统或升鱼机-下游码头位置
+ */
+ 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;
+
+ /**
+ * 主要过鱼对象{[code:鱼编码1,name:鱼名称1,数量],[code:鱼编码2,name:鱼名称2]...}
+ */
+ private String zygydx;
+
+ /**
+ * 主要过鱼对象描述
+ */
+ private String zygydxms;
+
+ /**
+ * 兼顾过鱼对象{[code:鱼编码1,name:鱼名称1,数量],[code:鱼编码2,name:鱼名称2]...}
+ */
+ private String jggydx;
+
+ /**
+ * 兼顾过鱼对象描述
+ */
+ 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
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
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);
+ }
+
}
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 /
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
# 登录相关配置