diff --git a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java index 1558260..2bcef19 100644 --- a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java @@ -57,6 +57,7 @@ public class SecurityConfig { .requestMatchers("/env/**").permitAll() .requestMatchers("/sw/**").permitAll() .requestMatchers("/data/**").permitAll() + .requestMatchers("/sms/**").permitAll() .requestMatchers(HttpMethod.GET, "/").permitAll() .requestMatchers(HttpMethod.GET, "/*.html", diff --git a/backend/src/main/java/com/yfd/platform/data/controller/ApprovalChangeLogController.java b/backend/src/main/java/com/yfd/platform/data/controller/ApprovalChangeLogController.java index e01f191..26e019f 100644 --- a/backend/src/main/java/com/yfd/platform/data/controller/ApprovalChangeLogController.java +++ b/backend/src/main/java/com/yfd/platform/data/controller/ApprovalChangeLogController.java @@ -39,6 +39,7 @@ public class ApprovalChangeLogController { @Operation(summary = "分页查询变更记录列表(通用)") public ResponseResult queryPageList(@RequestBody DataSourceRequest request) { Page approvalChangeLogPage = DataSourceRequestUtil.executeQuery(request, ApprovalChangeLog.class, approvalChangeLogService); + approvalChangeLogService.fillUserNames(approvalChangeLogPage.getRecords()); return ResponseResult.successData(approvalChangeLogPage); } diff --git a/backend/src/main/java/com/yfd/platform/data/controller/ApprovalLogController.java b/backend/src/main/java/com/yfd/platform/data/controller/ApprovalLogController.java index eb0ff5f..b367361 100644 --- a/backend/src/main/java/com/yfd/platform/data/controller/ApprovalLogController.java +++ b/backend/src/main/java/com/yfd/platform/data/controller/ApprovalLogController.java @@ -39,6 +39,7 @@ public class ApprovalLogController { @Operation(summary = "分页查询审批日志列表(通用)") public ResponseResult queryPageList(@RequestBody DataSourceRequest request) { Page approvalLogPage = DataSourceRequestUtil.executeQuery(request, ApprovalLog.class, approvalLogService); + approvalLogService.fillUserNames(approvalLogPage.getRecords()); return ResponseResult.successData(approvalLogPage); } diff --git a/backend/src/main/java/com/yfd/platform/data/controller/ApprovalMainController.java b/backend/src/main/java/com/yfd/platform/data/controller/ApprovalMainController.java index d8e8daf..d145d90 100644 --- a/backend/src/main/java/com/yfd/platform/data/controller/ApprovalMainController.java +++ b/backend/src/main/java/com/yfd/platform/data/controller/ApprovalMainController.java @@ -42,6 +42,7 @@ public class ApprovalMainController { @Operation(summary = "分页查询审批列表(通用)") public ResponseResult queryPageList(@RequestBody DataSourceRequest request) { Page approvalMainPage = DataSourceRequestUtil.executeQuery(request, ApprovalMain.class, approvalMainService); + approvalMainService.fillUserNames(approvalMainPage.getRecords()); return ResponseResult.successData(approvalMainPage); } 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 7197d40..85a449d 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 @@ -240,8 +240,12 @@ public class FishDraftDataController { request.setBizType("FISH"); FishImportResult result = fishImportService.parseAndMapZip(file, uploadUserId); - - importTaskService.updateStatus(taskId, "VALIDATED", null); + result.setTaskId(taskId); + String status = "VALIDATED"; + if ("1".equals(result.getCode())) { + status="FAILED"; + } + importTaskService.updateStatus(taskId, status, null); importTaskService.updateProgress(taskId, result.getTotalCount(), result.getSuccessCount(), result.getFailedCount()); try { @@ -260,9 +264,8 @@ public class FishDraftDataController { @PostMapping("/cancelImport") @Operation(summary = "取消导入任务") - public ResponseResult cancelImport(@RequestParam String taskId, - @RequestParam String operatorId) { - boolean result = importTaskService.cancelTask(taskId, operatorId); + public ResponseResult cancelImport(@RequestBody FishImportRequest fishImportRequest) { + boolean result = importTaskService.cancelTask(fishImportRequest.getTaskId(),SecurityUtils.getUserId()); return result ? ResponseResult.success("取消成功") : ResponseResult.error("取消失败"); } diff --git a/backend/src/main/java/com/yfd/platform/data/controller/ImportTaskController.java b/backend/src/main/java/com/yfd/platform/data/controller/ImportTaskController.java index 171f3ec..176f640 100644 --- a/backend/src/main/java/com/yfd/platform/data/controller/ImportTaskController.java +++ b/backend/src/main/java/com/yfd/platform/data/controller/ImportTaskController.java @@ -5,6 +5,7 @@ import com.yfd.platform.common.DataSourceLoadOptionsBase; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.data.domain.ImportTask; +import com.yfd.platform.data.domain.ImportTaskRequest; import com.yfd.platform.data.service.IImportTaskService; import com.yfd.platform.utils.KendoUtil; import com.yfd.platform.utils.QgcQueryWrapperUtil; @@ -124,8 +125,8 @@ public class ImportTaskController { @PostMapping("/markSuccess") @Operation(summary = "标记任务成功") - public ResponseResult markSuccess(@RequestParam String id) { - boolean result = importTaskService.markSuccess(id); + public ResponseResult markSuccess(@RequestBody ImportTaskRequest request) { + boolean result = importTaskService.markSuccess(request.getId()); return result ? ResponseResult.success("标记成功") : ResponseResult.error("标记失败"); } diff --git a/backend/src/main/java/com/yfd/platform/data/domain/ApprovalChangeLog.java b/backend/src/main/java/com/yfd/platform/data/domain/ApprovalChangeLog.java index ddc9c05..171d46f 100644 --- a/backend/src/main/java/com/yfd/platform/data/domain/ApprovalChangeLog.java +++ b/backend/src/main/java/com/yfd/platform/data/domain/ApprovalChangeLog.java @@ -30,6 +30,12 @@ public class ApprovalChangeLog implements Serializable { */ private String approvalId; + /** + * 审批批次名称 + */ + @TableField(exist = false) + private String approvalName; + /** * 草稿数据ID */ @@ -55,6 +61,12 @@ public class ApprovalChangeLog implements Serializable { */ private String operatorId; + /** + * 操作人名称 + */ + @TableField(exist = false) + private String operatorName; + /** * 操作时间 */ diff --git a/backend/src/main/java/com/yfd/platform/data/domain/ApprovalLog.java b/backend/src/main/java/com/yfd/platform/data/domain/ApprovalLog.java index b8d4e3e..84f4662 100644 --- a/backend/src/main/java/com/yfd/platform/data/domain/ApprovalLog.java +++ b/backend/src/main/java/com/yfd/platform/data/domain/ApprovalLog.java @@ -30,6 +30,12 @@ public class ApprovalLog implements Serializable { */ private String approvalId; + /** + * 审批批次名字 + */ + @TableField(exist = false) + private String approvalName; + /** * 操作类型(SUBMIT提交 / APPROVE通过 / REJECT驳回) */ @@ -40,6 +46,12 @@ public class ApprovalLog implements Serializable { */ private String operatorId; + /** + * 操作人名字 + */ + @TableField(exist = false) + private String operatorName; + /** * 操作时间 */ diff --git a/backend/src/main/java/com/yfd/platform/data/domain/ApprovalMain.java b/backend/src/main/java/com/yfd/platform/data/domain/ApprovalMain.java index 9989f93..c45084c 100644 --- a/backend/src/main/java/com/yfd/platform/data/domain/ApprovalMain.java +++ b/backend/src/main/java/com/yfd/platform/data/domain/ApprovalMain.java @@ -45,6 +45,12 @@ public class ApprovalMain implements Serializable { */ private String applyUserId; + /** + * 提交人名称 + */ + @TableField(exist = false) + private String applyUserName; + /** * 提交时间 */ @@ -60,6 +66,12 @@ public class ApprovalMain implements Serializable { */ private String approverId; + /** + * 审批人名称 + */ + @TableField(exist = false) + private String approverName; + /** * 审批完成时间 */ 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 fb74d72..dc6d5a4 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 @@ -95,6 +95,19 @@ public class FishDraftData implements Serializable { */ private String picpth; + /** + * 过鱼视频文件路径 + */ + @TableField(exist = false) + private String vdpthName; + + /** + * 图片文件路径 + */ + @TableField(exist = false) + private String picpthName; + + /** * 是否鱼苗(0否 1是) */ @@ -188,7 +201,7 @@ public class FishDraftData implements Serializable { * 电站名称 */ @TableField(exist = false) - private String engName; + private String ennm; /** * 基地名称 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 3d063da..894aea4 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 @@ -16,5 +16,7 @@ public class FishImportRequest implements Serializable { private String uploadUserId; + private String taskId; + 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 b0ffa2a..6f8c8c4 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 @@ -26,6 +26,7 @@ public class FishImportResult { private String summary; private String code; private String message; + private String taskId; public FishImportResult() { this.successRows = new ArrayList<>(); @@ -42,16 +43,27 @@ public class FishImportResult { private FishDraftData data; private List unrecognizedFields; private List warnings; - + private List> vdpthList; + private List> picpthList; + private List vdpthsWarnings; + private List picpthsWarnings; public FishImportRow() { this.unrecognizedFields = new ArrayList<>(); this.warnings = new ArrayList<>(); + this.vdpthsWarnings = new ArrayList<>(); + this.picpthsWarnings = new ArrayList<>(); + this.vdpthList = new ArrayList<>(); + this.picpthList = new ArrayList<>(); } public FishImportRow(int rowIndex) { this.rowIndex = rowIndex; this.unrecognizedFields = new ArrayList<>(); this.warnings = new ArrayList<>(); + this.vdpthsWarnings = new ArrayList<>(); + this.picpthsWarnings = new ArrayList<>(); + this.vdpthList = new ArrayList<>(); + this.picpthList = new ArrayList<>(); } } } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/domain/ImportTaskRequest.java b/backend/src/main/java/com/yfd/platform/data/domain/ImportTaskRequest.java new file mode 100644 index 0000000..0a2050e --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/data/domain/ImportTaskRequest.java @@ -0,0 +1,8 @@ +package com.yfd.platform.data.domain; + +import lombok.Data; + +@Data +public class ImportTaskRequest { + private String id; +} diff --git a/backend/src/main/java/com/yfd/platform/data/domain/SysUserDataScope.java b/backend/src/main/java/com/yfd/platform/data/domain/SysUserDataScope.java index 7715b94..b3513dd 100644 --- a/backend/src/main/java/com/yfd/platform/data/domain/SysUserDataScope.java +++ b/backend/src/main/java/com/yfd/platform/data/domain/SysUserDataScope.java @@ -33,12 +33,19 @@ public class SysUserDataScope implements Serializable { private String userId; /** - * 资源类型(BASIN / BASE /COMPANY / STATION) + * 用户名称 + */ + @TableField(exist = false) + private String userName; + + + /** + * 资源类型(RVCD/HBRVCD/ BASE / STATION/COMPANY) */ private String orgType; /** - * 资源编码(流域编码/基地编码/公司编码/电站编码) + * 资源编码(流域编码/基地流域编码/基地编码/电站编码/公司编码) */ private String orgId; @@ -100,6 +107,12 @@ public class SysUserDataScope implements Serializable { */ private String createdBy; + /** + * 创建人名称 + */ + @TableField(exist = false) + private String createdByName; + /** * 更新时间 */ @@ -111,6 +124,12 @@ public class SysUserDataScope implements Serializable { */ private String updatedBy; + /** + * 更新人名称 + */ + @TableField(exist = false) + private String updatedByName; + /** * 备注 */ 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 index 6e21b5c..65c0f48 100644 --- 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 @@ -216,4 +216,19 @@ public class FishDraftDataVO implements Serializable { * 排序字段 */ private Integer orderIndex; + + /** + * 创建人名称 + */ + private String createdByName; + + /** + * 更新人名称 + */ + private String updatedByName; + + /** + * 删除人名称 + */ + private String deletedByName; } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/domain/vo/SysUserDataScopeVO.java b/backend/src/main/java/com/yfd/platform/data/domain/vo/SysUserDataScopeVO.java index b630477..7d792e8 100644 --- a/backend/src/main/java/com/yfd/platform/data/domain/vo/SysUserDataScopeVO.java +++ b/backend/src/main/java/com/yfd/platform/data/domain/vo/SysUserDataScopeVO.java @@ -24,13 +24,13 @@ public class SysUserDataScopeVO implements Serializable { @Schema(description = "用户ID") private String userId; - @Schema(description = "资源类型(BASIN/BASE/COMPANY/STATION)") + @Schema(description = "资源类型(RVCD/HBRVCD/ BASE / STATION/COMPANY)") private String orgType; @Schema(description = "资源编码") private String orgId; - @Schema(description = "资源名称(流域名称/基地名称/公司名称/电站名称)") + @Schema(description = "资源编码(流域编码/基地流域编码/基地编码/电站编码/公司编码)") private String orgName; @Schema(description = "上级资源编码") 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 3469a47..df87aa6 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 @@ -27,7 +27,7 @@ public interface FishDraftDataMapper extends BaseMapper { @Param("status") String status, @Param("ftp") String ftp, @Param("startTime") String startTime, - @Param("endTime") String endTime); + @Param("endTime") String endTime,@Param("userId") String userId); /** * 关联查询过鱼数据(不分页) 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 e36f654..8325796 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 @@ -64,6 +64,6 @@ public interface ImportTaskMapper extends BaseMapper { " WHERE UPLOAD_USER_ID = #{uploadUserId} \n" + " AND BIZ_TYPE = 'FISH' \n" + " ORDER BY CREATED_AT DESC\n" + - ") WHERE ROWNUM = 1;") + ") WHERE ROWNUM = 1") ImportTask selectLastByUserId(@Param("uploadUserId") String uploadUserId); } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/service/AttachmentUploadService.java b/backend/src/main/java/com/yfd/platform/data/service/AttachmentUploadService.java index 5cb5e08..146d18a 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/AttachmentUploadService.java +++ b/backend/src/main/java/com/yfd/platform/data/service/AttachmentUploadService.java @@ -1,8 +1,13 @@ package com.yfd.platform.data.service; +import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; import java.io.File; import java.io.IOException; import java.net.URI; @@ -10,13 +15,23 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.nio.file.Files; +import java.security.SecureRandom; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.*; +import java.util.stream.Collectors; @Slf4j @Service public class AttachmentUploadService { - + // 定义一个固定的线程池用于文件上传(建议根据服务器性能调整核心线程数) + private static final ExecutorService UPLOAD_EXECUTOR = new ThreadPoolExecutor( + 5, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100), + new ThreadPoolExecutor.CallerRunsPolicy() + ); private static final String UPLOAD_URL = "https://211.99.26.225:12125/upload"; private static final String VIDEO_URL = "https://211.99.26.225:12125/upload"; @@ -42,37 +57,114 @@ public class AttachmentUploadService { "Content-Type: application/octet-stream\r\n\r\n"; String footer = "\r\n--" + boundary + "--\r\n"; - byte[] body; - if (fileName.toLowerCase().endsWith(".mp4") || fileName.toLowerCase().endsWith(".avi") || - fileName.toLowerCase().endsWith(".mov") || fileName.toLowerCase().endsWith(".wmv")) { - body = new byte[header.getBytes().length + fileContent.length + footer.getBytes().length]; - System.arraycopy(header.getBytes(), 0, body, 0, header.getBytes().length); - System.arraycopy(fileContent, 0, body, header.getBytes().length, fileContent.length); - System.arraycopy(footer.getBytes(), 0, body, header.getBytes().length + fileContent.length, footer.getBytes().length); - } else { - body = new byte[header.getBytes().length + fileContent.length + footer.getBytes().length]; - System.arraycopy(header.getBytes(), 0, body, 0, header.getBytes().length); - System.arraycopy(fileContent, 0, body, header.getBytes().length, fileContent.length); - System.arraycopy(footer.getBytes(), 0, body, header.getBytes().length + fileContent.length, footer.getBytes().length); - } + byte[] body = new byte[header.getBytes().length + fileContent.length + footer.getBytes().length]; + System.arraycopy(header.getBytes(), 0, body, 0, header.getBytes().length); + System.arraycopy(fileContent, 0, body, header.getBytes().length, fileContent.length); + System.arraycopy(footer.getBytes(), 0, body, header.getBytes().length + fileContent.length, footer.getBytes().length); - HttpRequest request = HttpRequest.newBuilder() - .uri(URI.create(UPLOAD_URL)) - .header("Content-Type", "multipart/form-data; boundary=" + boundary) - .POST(HttpRequest.BodyPublishers.ofByteArray(body)) - .build(); + try { + // 1. 创建信任所有证书的 TrustManager + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + public void checkClientTrusted(X509Certificate[] chain, String authType) {} + public void checkServerTrusted(X509Certificate[] chain, String authType) {} + public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } + } + }; - HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + // 2. 初始化 SSLContext + SSLContext sc = SSLContext.getInstance("TLS"); + sc.init(null, trustAllCerts, new SecureRandom()); - if (response.statusCode() == 200) { - String responseBody = response.body(); - return parseAttachmentId(responseBody); - } else { - log.error("上传文件失败: {}, 状态码: {}", fileName, response.statusCode()); + // 3. 构建支持 HTTPS 且忽略证书验证的 HttpClient + HttpClient secureClient = HttpClient.newBuilder() + .sslContext(sc) + .build(); + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(UPLOAD_URL)) + .header("Content-Type", "multipart/form-data; boundary=" + boundary) + .POST(HttpRequest.BodyPublishers.ofByteArray(body)) + .build(); + + // 4. 使用新的 secureClient 发送请求 + HttpResponse response = secureClient.send(request, HttpResponse.BodyHandlers.ofString()); + + if (response.statusCode() == 200) { + String responseBody = response.body(); + return parseAttachmentId(responseBody); + } else { + log.error("上传文件失败: {}, 状态码: {}", fileName, response.statusCode()); + return null; + } + } catch (Exception e) { + log.error("文件上传过程中发生异常: {}", e.getMessage(), e); return null; } } + + /** + * 多线程批量上传文件 + * @param files 文件列表 + * @return 返回所有上传成功的附件ID列表 + */ + public List uploadFilesConcurrently(List files) { + if (files == null || files.isEmpty()) { + return Collections.emptyList(); + } + + List> futures = files.stream() + .map(file -> CompletableFuture.supplyAsync(() -> { + try { + // 复用单文件上传逻辑 + return uploadFile(file); + } catch (Exception e) { + log.error("线程上传文件失败: {}", file.getName(), e); + return null; + } + }, UPLOAD_EXECUTOR)) + .toList(); + + // 等待所有任务完成并收集结果 + return futures.stream() + .map(CompletableFuture::join) + .filter(id -> id != null) + .collect(Collectors.toList()); + } + + /** + * 批量上传 MultipartFile (调用多线程版本) + */ + public List uploadMultipartFiles(List files) { + if (files == null || files.isEmpty()) { + return Collections.emptyList(); + } + + List tempFiles = new ArrayList<>(); + try { + for (MultipartFile file : files) { + if (!file.isEmpty()) { + File tempFile = File.createTempFile("upload_", file.getOriginalFilename()); + file.transferTo(tempFile); + tempFiles.add(tempFile); + } + } + + if (!tempFiles.isEmpty()) { + return uploadFilesConcurrently(tempFiles); + } + } catch (Exception e) { + log.error("批量处理 MultipartFile 失败", e); + } finally { + for (File tempFile : tempFiles) { + if (tempFile.exists()) tempFile.delete(); + } + } + return Collections.emptyList(); + } + + public String uploadVideo(File file) throws IOException, InterruptedException { return uploadFile(file); } @@ -137,19 +229,14 @@ public class AttachmentUploadService { } try { - if (jsonResponse.contains("\"message\":")) { - int start = jsonResponse.indexOf("\"message\":\"") + 11; - int end = jsonResponse.indexOf("\"", start); - if (start > 10 && end > start) { - return jsonResponse.substring(start, end); - } - } - if (jsonResponse.contains("\"message\":\"")) { - int start = jsonResponse.indexOf("\"message\":\"") + 11; - int end = jsonResponse.indexOf("\"", start); - if (start > 10 && end > start) { - return jsonResponse.substring(start, end); - } + JSONObject json = JSONObject.parseObject(jsonResponse); + // 尝试从常见的返回字段中获取 ID,根据实际接口返回调整 key + if (json.containsKey("message")) { + return json.getString("message"); + } else if (json.containsKey("data")) { + return json.getString("data"); + } else if (json.containsKey("id")) { + return json.getString("id"); } } catch (Exception e) { log.error("解析附件ID失败: {}", jsonResponse, e); diff --git a/backend/src/main/java/com/yfd/platform/data/service/IApprovalChangeLogService.java b/backend/src/main/java/com/yfd/platform/data/service/IApprovalChangeLogService.java index 66e609f..756e9fb 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/IApprovalChangeLogService.java +++ b/backend/src/main/java/com/yfd/platform/data/service/IApprovalChangeLogService.java @@ -17,6 +17,8 @@ public interface IApprovalChangeLogService extends IService { */ List getByApprovalId(String approvalId); + void fillUserNames(List list); + /** * 根据草稿数据ID查询变更记录 */ diff --git a/backend/src/main/java/com/yfd/platform/data/service/IApprovalLogService.java b/backend/src/main/java/com/yfd/platform/data/service/IApprovalLogService.java index 8d01030..575273e 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/IApprovalLogService.java +++ b/backend/src/main/java/com/yfd/platform/data/service/IApprovalLogService.java @@ -17,6 +17,8 @@ public interface IApprovalLogService extends IService { */ List getByApprovalId(String approvalId); + void fillUserNames(List list); + /** * 根据操作类型查询 */ diff --git a/backend/src/main/java/com/yfd/platform/data/service/IApprovalMainService.java b/backend/src/main/java/com/yfd/platform/data/service/IApprovalMainService.java index d20136b..b2ee766 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/IApprovalMainService.java +++ b/backend/src/main/java/com/yfd/platform/data/service/IApprovalMainService.java @@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.yfd.platform.data.domain.ApprovalMain; +import java.util.List; + /** *

* 审批批次主表 服务类 @@ -16,6 +18,8 @@ public interface IApprovalMainService extends IService { */ Page queryPageList(Page page, String bizType, String status); + void fillUserNames(List list); + /** * 根据审批批次号查询 */ diff --git a/backend/src/main/java/com/yfd/platform/data/service/impl/ApprovalChangeLogServiceImpl.java b/backend/src/main/java/com/yfd/platform/data/service/impl/ApprovalChangeLogServiceImpl.java index f1f730a..c6dbc3c 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/impl/ApprovalChangeLogServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/data/service/impl/ApprovalChangeLogServiceImpl.java @@ -1,14 +1,16 @@ package com.yfd.platform.data.service.impl; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yfd.platform.data.domain.ApprovalChangeLog; import com.yfd.platform.data.mapper.ApprovalChangeLogMapper; import com.yfd.platform.data.service.IApprovalChangeLogService; +import com.yfd.platform.system.domain.SysUser; +import com.yfd.platform.system.mapper.SysUserMapper; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; -import java.util.Date; -import java.util.List; +import java.util.*; /** *

@@ -21,11 +23,48 @@ public class ApprovalChangeLogServiceImpl extends ServiceImpl getByApprovalId(String approvalId) { return approvalChangeLogMapper.selectByApprovalId(approvalId); } + @Override + public void fillUserNames(List list) { + if (list == null || list.isEmpty()) { + return; + } + Set userIds = new HashSet<>(); + for (ApprovalChangeLog vo : list) { + if (StrUtil.isNotBlank(vo.getApprovalId())) { + userIds.add(vo.getApprovalId()); + } + if (StrUtil.isNotBlank(vo.getOperatorId())) { + userIds.add(vo.getOperatorId()); + } + } + + if (userIds.isEmpty()) { + return; + } + + Map userNameMap = new HashMap<>(); + List users = sysUserMapper.selectBatchIds(userIds); + for (SysUser user : users) { + userNameMap.put(user.getId(), user.getNickname()); + } + + for (ApprovalChangeLog vo : list) { + if (StrUtil.isNotBlank(vo.getApprovalId())) { + vo.setApprovalName(userNameMap.get(vo.getApprovalId())); + } + if (StrUtil.isNotBlank(vo.getOperatorId())) { + vo.setOperatorName(userNameMap.get(vo.getOperatorId())); + } + + } + } @Override public List getByDataId(String dataId) { return approvalChangeLogMapper.selectByDataId(dataId); diff --git a/backend/src/main/java/com/yfd/platform/data/service/impl/ApprovalLogServiceImpl.java b/backend/src/main/java/com/yfd/platform/data/service/impl/ApprovalLogServiceImpl.java index d48ec47..cb49173 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/impl/ApprovalLogServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/data/service/impl/ApprovalLogServiceImpl.java @@ -1,14 +1,16 @@ package com.yfd.platform.data.service.impl; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yfd.platform.data.domain.ApprovalLog; import com.yfd.platform.data.mapper.ApprovalLogMapper; import com.yfd.platform.data.service.IApprovalLogService; +import com.yfd.platform.system.domain.SysUser; +import com.yfd.platform.system.mapper.SysUserMapper; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; -import java.util.Date; -import java.util.List; +import java.util.*; /** *

@@ -20,12 +22,50 @@ public class ApprovalLogServiceImpl extends ServiceImpl getByApprovalId(String approvalId) { return approvalLogMapper.selectByApprovalId(approvalId); } + @Override + public void fillUserNames(List list) { + if (list == null || list.isEmpty()) { + return; + } + + Set userIds = new HashSet<>(); + for (ApprovalLog vo : list) { + if (StrUtil.isNotBlank(vo.getApprovalId())) { + userIds.add(vo.getApprovalId()); + } + if (StrUtil.isNotBlank(vo.getOperatorId())) { + userIds.add(vo.getOperatorId()); + } + } + + if (userIds.isEmpty()) { + return; + } + + Map userNameMap = new HashMap<>(); + List users = sysUserMapper.selectBatchIds(userIds); + for (SysUser user : users) { + userNameMap.put(user.getId(), user.getNickname()); + } + + for (ApprovalLog vo : list) { + if (StrUtil.isNotBlank(vo.getApprovalId())) { + vo.setApprovalName(userNameMap.get(vo.getApprovalId())); + } + if (StrUtil.isNotBlank(vo.getOperatorId())) { + vo.setOperatorName(userNameMap.get(vo.getOperatorId())); + } + + } + } + @Override public List getByAction(String action) { return approvalLogMapper.selectByAction(action); diff --git a/backend/src/main/java/com/yfd/platform/data/service/impl/ApprovalMainServiceImpl.java b/backend/src/main/java/com/yfd/platform/data/service/impl/ApprovalMainServiceImpl.java index 907ede4..72f3d57 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/impl/ApprovalMainServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/data/service/impl/ApprovalMainServiceImpl.java @@ -1,19 +1,20 @@ package com.yfd.platform.data.service.impl; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.yfd.platform.data.domain.ApprovalLog; import com.yfd.platform.data.domain.ApprovalMain; -import com.yfd.platform.data.mapper.ApprovalLogMapper; import com.yfd.platform.data.mapper.ApprovalMainMapper; import com.yfd.platform.data.service.IApprovalLogService; import com.yfd.platform.data.service.IApprovalMainService; +import com.yfd.platform.system.domain.SysUser; +import com.yfd.platform.system.mapper.SysUserMapper; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; -import java.util.Date; +import java.util.*; /** *

@@ -29,15 +30,58 @@ public class ApprovalMainServiceImpl extends ServiceImpl queryPageList(Page page, String bizType, String status) { - return this.page(page, this.lambdaQuery() + Page approvalMainPage = this.page(page, this.lambdaQuery() .eq(StringUtils.hasText(bizType), ApprovalMain::getBizType, bizType) .eq(StringUtils.hasText(status), ApprovalMain::getStatus, status) .orderByDesc(ApprovalMain::getCreatedAt) .getWrapper()); + fillUserNames(approvalMainPage.getRecords()); + return approvalMainPage; } + @Override + public void fillUserNames(List list) { + if (list == null || list.isEmpty()) { + return; + } + + Set userIds = new HashSet<>(); + for (ApprovalMain vo : list) { + if (StrUtil.isNotBlank(vo.getApproverId())) { + userIds.add(vo.getApproverId()); + } + if (StrUtil.isNotBlank(vo.getApplyUserId())) { + userIds.add(vo.getApplyUserId()); + } + } + + if (userIds.isEmpty()) { + return; + } + + Map userNameMap = new HashMap<>(); + List users = sysUserMapper.selectBatchIds(userIds); + for (SysUser user : users) { + userNameMap.put(user.getId(), user.getNickname()); + } + + for (ApprovalMain vo : list) { + if (StrUtil.isNotBlank(vo.getApproverId())) { + vo.setApproverName(userNameMap.get(vo.getApproverId())); + } + if (StrUtil.isNotBlank(vo.getApplyUserId())) { + vo.setApplyUserName(userNameMap.get(vo.getApplyUserId())); + } + + } + } + + @Override public ApprovalMain getByApprovalNo(String approvalNo) { return approvalMainMapper.selectByApprovalNo(approvalNo); 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 e292482..86961e7 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 @@ -15,6 +15,8 @@ import com.yfd.platform.data.service.IApprovalChangeLogService; import com.yfd.platform.data.service.IApprovalLogService; import com.yfd.platform.data.service.IApprovalMainService; import com.yfd.platform.data.service.IFishDraftDataService; +import com.yfd.platform.system.domain.SysUser; +import com.yfd.platform.system.mapper.SysUserMapper; import com.yfd.platform.utils.KendoUtil; import com.yfd.platform.utils.QgcQueryWrapperUtil; import com.yfd.platform.utils.SecurityUtils; @@ -46,6 +48,9 @@ public class FishDraftDataServiceImpl extends ServiceImpl resultPage = fishDraftDataMapper.selectJoinPage( - page, stcd, rstcd, baseId, direction, status, ftp, startTime, endTime); + Page resultPage = fishDraftDataMapper.selectJoinPage(page, stcd, rstcd, baseId, direction, status, ftp, startTime, endTime,userId); + fillUserNames(resultPage.getRecords()); return resultPage; } @@ -84,7 +92,56 @@ public class FishDraftDataServiceImpl extends ServiceImpl list = fishDraftDataMapper.selectJoinList(stcd, rstcd, baseId, direction, status, ftp, startTime, endTime); + fillUserNames(list); + return list; + } + + private void fillUserNames(List list) { + if (list == null || list.isEmpty()) { + return; + } + + Set userIds = new HashSet<>(); + for (FishDraftDataVO vo : list) { + if (StrUtil.isNotBlank(vo.getCreatedBy())) { + userIds.add(vo.getCreatedBy()); + } + if (StrUtil.isNotBlank(vo.getCreatedBy())) { + userIds.add(vo.getCreatedBy()); + } + if (StrUtil.isNotBlank(vo.getUpdatedBy())) { + userIds.add(vo.getUpdatedBy()); + } + if (StrUtil.isNotBlank(vo.getDeletedBy())) { + userIds.add(vo.getDeletedBy()); + } + } + + if (userIds.isEmpty()) { + return; + } + + Map userNameMap = new HashMap<>(); + List users = sysUserMapper.selectBatchIds(userIds); + for (SysUser user : users) { + userNameMap.put(user.getId(), user.getNickname()); + } + + for (FishDraftDataVO vo : list) { + if (StrUtil.isNotBlank(vo.getCreatedBy())) { + vo.setCreatedByName(userNameMap.get(vo.getCreatedBy())); + } + if (StrUtil.isNotBlank(vo.getUpdatedBy())) { + vo.setUpdatedByName(userNameMap.get(vo.getUpdatedBy())); + } + if (StrUtil.isNotBlank(vo.getDeletedBy())) { + vo.setDeletedByName(userNameMap.get(vo.getDeletedBy())); + } + if (StrUtil.isNotBlank(vo.getDeletedBy())) { + vo.setDeletedByName(userNameMap.get(vo.getDeletedBy())); + } + } } @Override 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 3848f80..bd5d998 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 @@ -22,6 +22,7 @@ import org.springframework.web.multipart.MultipartFile; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; @@ -105,6 +106,8 @@ public class FishImportServiceImpl implements IFishImportService { EXCEL_COLUMN_INDEX_MAPPING.put(8, "fsz"); EXCEL_COLUMN_INDEX_MAPPING.put(9, "fwet"); EXCEL_COLUMN_INDEX_MAPPING.put(10, "wt"); + EXCEL_COLUMN_INDEX_MAPPING.put(11, "picpth"); + EXCEL_COLUMN_INDEX_MAPPING.put(12, "vdpth"); } @Override @@ -185,15 +188,15 @@ public class FishImportServiceImpl implements IFishImportService { switch (fieldName) { case "stationName": if (!StringUtils.hasText(cellValue)) { - importRow.getWarnings().add("engName"); - data.setEngName(cellValue.trim()); + importRow.getWarnings().add("ennm"); + data.setEnnm(cellValue.trim()); } else { String stcd = resolveStationCode(cellValue.trim()); if (stcd == null) { - importRow.getWarnings().add("engName"); - data.setEngName(cellValue.trim()); + importRow.getWarnings().add("ennm"); + data.setEnnm(cellValue.trim()); } else { - data.setEngName(cellValue.trim()); + data.setEnnm(cellValue.trim()); } } break; @@ -269,6 +272,19 @@ public class FishImportServiceImpl implements IFishImportService { data.setFcnt(fcnt); } break; + case "wt": + if (!StringUtils.hasText(cellValue)) { + importRow.getWarnings().add(fieldName); + data.setWt(parseBigDecimal(cellValue)); + } else { + BigDecimal wt = parseBigDecimal(cellValue); + if (wt == null) { + importRow.getWarnings().add(fieldName); + data.setWt(parseBigDecimal(cellValue)); + } + data.setWt(wt); + } + break; case "fwet": data.setFwet(cellValue.trim()); break; @@ -303,14 +319,16 @@ public class FishImportServiceImpl implements IFishImportService { break; case "vdpth": data.setVdpth(cellValue.trim()); + data.setVdpthName(cellValue.trim()); break; case "picpth": data.setPicpth(cellValue.trim()); + data.setPicpthName(cellValue.trim()); break; case "isfs": if (StringUtils.hasText(cellValue)) { String isfs = resolveIsfs(cellValue.trim(), importRow); - data.setIsfs("是".equals(isfs) ? 1 : 0); + data.setIsfs("1".equals(isfs) ? 1 : 0); } break; case "sourceType": @@ -525,13 +543,13 @@ public class FishImportServiceImpl implements IFishImportService { String lowerName = direction.toLowerCase().trim(); if (lowerName.contains("上行") && lowerName.contains("折返")) { - return "03"; + return "2"; } else if (lowerName.contains("下行") && lowerName.contains("折返")) { - return "04"; + return "3"; } else if (lowerName.contains("上行")) { - return "01"; + return "0"; } else if (lowerName.contains("下行")) { - return "02"; + return "1"; } importRow.getWarnings().add("direction"); return direction; @@ -677,6 +695,23 @@ public class FishImportServiceImpl implements IFishImportService { } } + /** + * 解析 BigDecimal 类型数据 + * @param value 字符串数值 + * @return BigDecimal 对象,解析失败或为空时返回 null + */ + private BigDecimal parseBigDecimal(String value) { + if (!StringUtils.hasText(value)) { + return null; + } + try { + return new BigDecimal(value.trim()); + } catch (NumberFormatException e) { + return null; + } + } + + private String parseSourceType(String value) { if (!StringUtils.hasText(value)) { return "IMPORT"; @@ -732,8 +767,24 @@ public class FishImportServiceImpl implements IFishImportService { } private void processAttachments(FishImportResult result, ZipFileUtil.ZipContent zipContent) { - if (result.getSuccessRows() == null || result.getSuccessRows().isEmpty()) { - return; + for (FishImportResult.FishImportRow importRow : result.getFailedRows()) { + FishDraftData data = importRow.getData(); + if (data == null) { + continue; + } + + String vdpth = data.getVdpth(); + String picpth = data.getPicpth(); + + if (StringUtils.hasText(vdpth)) { + String uploadedVdpth = processVideoAttachments(importRow,vdpth, zipContent.videos); + data.setVdpth(uploadedVdpth); + } + + if (StringUtils.hasText(picpth)) { + String uploadedPicpth = processImageAttachments(importRow,picpth, zipContent.images); + data.setPicpth(uploadedPicpth); + } } for (FishImportResult.FishImportRow importRow : result.getSuccessRows()) { @@ -746,18 +797,18 @@ public class FishImportServiceImpl implements IFishImportService { String picpth = data.getPicpth(); if (StringUtils.hasText(vdpth)) { - String uploadedVdpth = processVideoAttachments(vdpth, zipContent.videos); + String uploadedVdpth = processVideoAttachments(importRow,vdpth, zipContent.videos); data.setVdpth(uploadedVdpth); } if (StringUtils.hasText(picpth)) { - String uploadedPicpth = processImageAttachments(picpth, zipContent.images); + String uploadedPicpth = processImageAttachments(importRow,picpth, zipContent.images); data.setPicpth(uploadedPicpth); } } } - private String processVideoAttachments(String videoNames, Map videoMap) { + private String processVideoAttachments(FishImportResult.FishImportRow importRow, String videoNames, Map videoMap) { if (videoNames == null || videoNames.isEmpty() || videoMap == null || videoMap.isEmpty()) { return videoNames; } @@ -770,58 +821,70 @@ public class FishImportServiceImpl implements IFishImportService { if (fileName.isEmpty()) { continue; } - String actualPath = findFilePath(fileName, videoMap); + Map fileMap = new HashMap<>(); + fileMap.put("name", fileName); if (actualPath != null) { try { String attachmentId = attachmentUploadService.uploadFileAndGetId(actualPath); if (attachmentId != null) { attachmentIds.add(attachmentId); + fileMap.put("value", attachmentId); } else { - attachmentIds.add(fileName); + importRow.getVdpthsWarnings().add(fileName); +// attachmentIds.add(fileName); } } catch (Exception e) { - attachmentIds.add(fileName); + e.printStackTrace(); + importRow.getVdpthsWarnings().add(fileName); +// attachmentIds.add(fileName); } } else { - attachmentIds.add(fileName); + importRow.getVdpthsWarnings().add(fileName); +// attachmentIds.add(fileName); } + importRow.getVdpthList().add(fileMap); } return String.join(",", attachmentIds); } - private String processImageAttachments(String imageNames, Map imageMap) { + private String processImageAttachments(FishImportResult.FishImportRow importRow,String imageNames, Map imageMap) { if (imageNames == null || imageNames.isEmpty() || imageMap == null || imageMap.isEmpty()) { return imageNames; } String[] fileNames = imageNames.split(";"); List attachmentIds = new ArrayList<>(); - for (String fileName : fileNames) { fileName = fileName.trim(); if (fileName.isEmpty()) { continue; } - + Map fileMap = new HashMap<>(); + fileMap.put("name", fileName); String actualPath = findFilePath(fileName, imageMap); if (actualPath != null) { try { String attachmentId = attachmentUploadService.uploadFileAndGetId(actualPath); if (attachmentId != null) { attachmentIds.add(attachmentId); + fileMap.put("value", attachmentId); } else { - attachmentIds.add(fileName); + importRow.getPicpthsWarnings().add(fileName); +// attachmentIds.add(fileName); } } catch (Exception e) { - attachmentIds.add(fileName); + e.printStackTrace(); + importRow.getPicpthsWarnings().add(fileName); +// attachmentIds.add(fileName); } } else { - attachmentIds.add(fileName); + importRow.getPicpthsWarnings().add(fileName); +// attachmentIds.add(fileName); } + importRow.getPicpthList().add(fileMap); } - return String.join(",", attachmentIds); } 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 3d1a91a..4dfbb00 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 @@ -187,7 +187,7 @@ public class ImportTaskServiceImpl extends ServiceImpl().eq(ImportTask::getUploadUserId, uploadUserId).eq(ImportTask::getBizType, "FISH").orderByDesc(ImportTask::getCreatedAt)); + ImportTask importTask = importTaskMapper.selectLastByUserId(uploadUserId); return importTask; } } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/data/service/impl/SysUserDataScopeServiceImpl.java b/backend/src/main/java/com/yfd/platform/data/service/impl/SysUserDataScopeServiceImpl.java index 7492688..a1e8624 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/impl/SysUserDataScopeServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/data/service/impl/SysUserDataScopeServiceImpl.java @@ -11,13 +11,17 @@ import com.yfd.platform.data.domain.vo.SysUserDataScopeVO; import com.yfd.platform.data.mapper.SysUserDataScopeMapper; import com.yfd.platform.data.service.ISysUserDataScopeService; import com.yfd.platform.env.domain.SdEngInfoBH; +import com.yfd.platform.env.domain.SdHbrvDic; import com.yfd.platform.env.domain.SdHycdDic; import com.yfd.platform.env.domain.SdHydrobase; import com.yfd.platform.env.domain.SdRvcdDic; import com.yfd.platform.env.mapper.SdEngInfoBHMapper; +import com.yfd.platform.env.mapper.SdHbrvDicMapper; import com.yfd.platform.env.mapper.SdHycdDicMapper; import com.yfd.platform.env.mapper.SdHydrobaseMapper; import com.yfd.platform.env.mapper.SdRvcdDicMapper; +import com.yfd.platform.system.domain.SysUser; +import com.yfd.platform.system.mapper.SysUserMapper; import jakarta.annotation.Resource; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; @@ -44,15 +48,67 @@ public class SysUserDataScopeServiceImpl extends ServiceImpl queryPageList(Page page, String userId, String orgType, String orgId, Integer status) { - return this.page(page, this.lambdaQuery() + Page userDataScopePage = this.page(page, this.lambdaQuery() .eq(userId != null, SysUserDataScope::getUserId, userId) .eq(orgType != null && !orgType.isEmpty(), SysUserDataScope::getOrgType, orgType) .eq(orgId != null && !orgId.isEmpty(), SysUserDataScope::getOrgId, orgId) .eq(status != null, SysUserDataScope::getStatus, status) .orderByDesc(SysUserDataScope::getCreatedAt) .getWrapper()); + fillUserNames(userDataScopePage.getRecords()); + return userDataScopePage; + } + + private void fillUserNames(List list) { + if (list == null || list.isEmpty()) { + return; + } + + Set userIds = new HashSet<>(); + for (SysUserDataScope vo : list) { + if (StrUtil.isNotBlank(vo.getCreatedBy())) { + userIds.add(vo.getCreatedBy()); + } + if (StrUtil.isNotBlank(vo.getCreatedBy())) { + userIds.add(vo.getCreatedBy()); + } + if (StrUtil.isNotBlank(vo.getUpdatedBy())) { + userIds.add(vo.getUpdatedBy()); + } + if (StrUtil.isNotBlank(vo.getUserId())) { + userIds.add(vo.getUserId()); + } + } + + if (userIds.isEmpty()) { + return; + } + + Map userNameMap = new HashMap<>(); + List users = sysUserMapper.selectBatchIds(userIds); + for (SysUser user : users) { + userNameMap.put(user.getId(), user.getNickname()); + } + + for (SysUserDataScope vo : list) { + if (StrUtil.isNotBlank(vo.getCreatedBy())) { + vo.setCreatedByName(userNameMap.get(vo.getCreatedBy())); + } + if (StrUtil.isNotBlank(vo.getUpdatedBy())) { + vo.setUpdatedByName(userNameMap.get(vo.getUpdatedBy())); + } + if (StrUtil.isNotBlank(vo.getUserId())) { + vo.setUserId(userNameMap.get(vo.getUserId())); + } + } } @Override @@ -118,8 +174,8 @@ public class SysUserDataScopeServiceImpl extends ServiceImpl orgNameMap = new HashMap<>(); // 3.1 查询流域名称 (BASIN) - if (groupedByType.containsKey("BASIN")) { - Set rvcds = groupedByType.get("BASIN").stream() + if (groupedByType.containsKey("RVCD")) { + Set rvcds = groupedByType.get("RVCD").stream() .map(SysUserDataScope::getOrgId) .filter(StrUtil::isNotBlank) .collect(Collectors.toSet()); @@ -130,7 +186,20 @@ public class SysUserDataScopeServiceImpl extends ServiceImpl hbrvcds = groupedByType.get("HBRVCD").stream() + .map(SysUserDataScope::getOrgId) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toSet()); + + if (CollUtil.isNotEmpty(hbrvcds)) { + List hbrvs = hbrvDicMapper.selectBatchIds(hbrvcds); + hbrvs.forEach(hbrv -> orgNameMap.put(hbrv.getHbrvcd(), hbrv.getHbrvnm())); + } + } + + // 3.3 查询基地名称 (BASE) if (groupedByType.containsKey("BASE")) { Set baseIds = groupedByType.get("BASE").stream() .map(SysUserDataScope::getOrgId) @@ -143,7 +212,7 @@ public class SysUserDataScopeServiceImpl extends ServiceImpl hycds = groupedByType.get("COMPANY").stream() .map(SysUserDataScope::getOrgId) @@ -156,7 +225,7 @@ public class SysUserDataScopeServiceImpl extends ServiceImpl stcds = groupedByType.get("STATION").stream() .map(SysUserDataScope::getOrgId) 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 aac18b6..e810b84 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 @@ -76,6 +76,13 @@ public class SdEngInfoBHController { return ResponseResult.successData(engInfoBHService.selectForDropdown(baseId, ennm)); } + @GetMapping("/regDropdown") + @Operation(summary = "电站下拉列表(根据基地编码筛选 + 支持名称模糊搜索)注册") + public ResponseResult regDropdown(@RequestParam(required = false) String baseId, + @RequestParam(required = false) String ennm) { + return ResponseResult.successData(engInfoBHService.selectRegDropdown(baseId, ennm)); + } + @Log(module = "电站管理", value = "新增电站") @PostMapping("/add") @Operation(summary = "新增电站") diff --git a/backend/src/main/java/com/yfd/platform/env/controller/SdHbrvDicController.java b/backend/src/main/java/com/yfd/platform/env/controller/SdHbrvDicController.java new file mode 100644 index 0000000..1b87633 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/controller/SdHbrvDicController.java @@ -0,0 +1,115 @@ +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.SdHbrvDic; +import com.yfd.platform.env.service.ISdHbrvDicService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.*; + +import jakarta.annotation.Resource; +import java.util.List; + +/** + *

+ * 水电基地流域表 前端控制器 + *

+ */ +@RestController +@RequestMapping("/env/hbrv") +@Tag(name = "基地流域管理") +public class SdHbrvDicController { + + @Resource + private ISdHbrvDicService hbrvDicService; + + @GetMapping("/queryPageList") + @Operation(summary = "分页查询流域列表") + public ResponseResult queryPageList( + @RequestParam(required = false) String hbrvnm, + @RequestParam(required = false) String baseid, + @RequestParam(defaultValue = "1") Long pageNum, + @RequestParam(defaultValue = "10") Long pageSize) { + Page page = new Page<>(pageNum, pageSize); + Page result = hbrvDicService.queryPageList(page, hbrvnm, baseid); + return ResponseResult.successData(result); + } + + @GetMapping("/list") + @Operation(summary = "查询所有流域") + public ResponseResult list() { + return ResponseResult.successData(hbrvDicService.list()); + } + + @GetMapping("/getByBaseid") + @Operation(summary = "根据基地编码查询流域") + public ResponseResult getByBaseid(@RequestParam(required = false) String baseid) { + List list = hbrvDicService.getByBaseid(baseid); + return ResponseResult.successData(list); + } + + @GetMapping("/getByHbrvcd") + @Operation(summary = "根据父流域编码查询流域") + public ResponseResult getByHbrvcd(@RequestParam(required = false) String hbrvcd, + @RequestParam(required = false) String baseid) { + List list = hbrvDicService.getByHbrvcd(hbrvcd, baseid); + return ResponseResult.successData(list); + } + + @GetMapping("/getEnabledList") + @Operation(summary = "查询所有启用的流域") + public ResponseResult getEnabledList() { + return ResponseResult.successData(hbrvDicService.getEnabledList()); + } + + @GetMapping("/getById") + @Operation(summary = "根据编码查询流域") + public ResponseResult getById(@RequestParam String hbrvcd, + @RequestParam String baseid) { + SdHbrvDic hbrvDic = hbrvDicService.getById(hbrvcd); + return ResponseResult.successData(hbrvDic); + } + + @Log(module = "基地流域管理", value = "新增流域") + @PostMapping("/add") + @Operation(summary = "新增流域") + public ResponseResult add(@RequestBody SdHbrvDic hbrvDic) { + boolean result = hbrvDicService.addHbrvDic(hbrvDic); + return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败"); + } + + @Log(module = "基地流域管理", value = "修改流域") + @PostMapping("/update") + @Operation(summary = "修改流域") + public ResponseResult update(@RequestBody SdHbrvDic hbrvDic) { + boolean result = hbrvDicService.updateHbrvDic(hbrvDic); + return result ? ResponseResult.success("修改成功") : ResponseResult.error("修改失败"); + } + + @Log(module = "基地流域管理", value = "删除流域") + @PostMapping("/delete") + @Operation(summary = "删除流域") + public ResponseResult delete(@RequestParam String hbrvcd, + @RequestParam String baseid) { + boolean result = hbrvDicService.deleteHbrvDic(hbrvcd, baseid); + return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败"); + } + + @GetMapping("/selectForDropdown") + @Operation(summary = "下拉框列表查询") + public ResponseResult selectForDropdown( + @RequestParam(required = false) String hbrvnm, + @RequestParam(required = false) String baseid) { + return ResponseResult.successData(hbrvDicService.selectForDropdown(hbrvnm, baseid)); + } + + @GetMapping("/regDropdown") + @Operation(summary = "下拉框列表查询") + public ResponseResult regDropdown( + @RequestParam(required = false) String hbrvnm, + @RequestParam(required = false) String baseid) { + return ResponseResult.successData(hbrvDicService.regDropdown(hbrvnm, baseid)); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/controller/SdHycdDicController.java b/backend/src/main/java/com/yfd/platform/env/controller/SdHycdDicController.java index 568ffde..db5351f 100644 --- a/backend/src/main/java/com/yfd/platform/env/controller/SdHycdDicController.java +++ b/backend/src/main/java/com/yfd/platform/env/controller/SdHycdDicController.java @@ -62,6 +62,23 @@ public class SdHycdDicController { return ResponseResult.successData(hycdDicService.getById(hycd)); } + @GetMapping("/selectForDropdown") + @Operation(summary = "下拉框列表查询") + public ResponseResult selectForDropdown( + @RequestParam(required = false) String hynm, + @RequestParam(required = false) Integer grd) { + return ResponseResult.successData(hycdDicService.selectForDropdown(hynm, grd)); + } + + @GetMapping("/regDropdown") + @Operation(summary = "下拉框列表查询(注册)") + public ResponseResult regDropdown( + @RequestParam(required = false) String hynm, + @RequestParam(required = false) Integer grd) { + return ResponseResult.successData(hycdDicService.regDropdown(hynm, grd)); + } + + @Log(module = "公司管理", value = "新增公司") @PostMapping("/add") @Operation(summary = "新增公司") diff --git a/backend/src/main/java/com/yfd/platform/env/controller/TreeStructureController.java b/backend/src/main/java/com/yfd/platform/env/controller/TreeStructureController.java index 6c64cbe..1b39ca2 100644 --- a/backend/src/main/java/com/yfd/platform/env/controller/TreeStructureController.java +++ b/backend/src/main/java/com/yfd/platform/env/controller/TreeStructureController.java @@ -46,6 +46,15 @@ public class TreeStructureController { return ResponseResult.successData(result); } + @GetMapping("/hbrvEng") + @Operation(summary = "获取基地流域-电站树形结构") + public ResponseResult getHbrvEngTree( + @RequestParam(required = false) String hbrvcd, + @RequestParam(required = false) String engName) { + List> result = treeStructureService.getHbrvEngTree(hbrvcd, engName); + return ResponseResult.successData(result); + } + @GetMapping("/rvcdBaseEng") @Operation(summary = "获取流域-基地-电站树形结构") diff --git a/backend/src/main/java/com/yfd/platform/env/domain/SdEngInfoBH.java b/backend/src/main/java/com/yfd/platform/env/domain/SdEngInfoBH.java index bb71e6b..4d258c4 100644 --- a/backend/src/main/java/com/yfd/platform/env/domain/SdEngInfoBH.java +++ b/backend/src/main/java/com/yfd/platform/env/domain/SdEngInfoBH.java @@ -242,7 +242,7 @@ public class SdEngInfoBH implements Serializable { /** * 工程等别 字典编码:sd_enginfo_b_h.prgr 1=Ⅰ 2=Ⅱ 3=Ⅲ 4=Ⅳ 5=Ⅴ */ - private Integer prgr; + private String prgr; /** * 电站-主要功能 1=发电 2=防洪 3=灌溉 4=供水 5=航运 6=旅游 7=环境 8=养殖 9=其他 diff --git a/backend/src/main/java/com/yfd/platform/env/domain/SdHbrvDic.java b/backend/src/main/java/com/yfd/platform/env/domain/SdHbrvDic.java new file mode 100644 index 0000000..66a99ed --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/domain/SdHbrvDic.java @@ -0,0 +1,56 @@ +package com.yfd.platform.env.domain; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; + +/** + *

+ * 水电基地流域表 + *

+ */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("SD_HBRV_DIC") +public class SdHbrvDic implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 基地流域编码 + */ + @TableId(type = IdType.INPUT) + private String hbrvcd; + + /** + * 基地流域名称 + */ + private String hbrvnm; + + /** + * 水电基地编码 + */ + private String baseid; + + /** + * 树级别,从1开始 + */ + private Integer grd; + + /** + * 树全路径,中间以逗号分隔,末级要加逗号不加会影响like递归 + */ + private String path; + + /** + * 排序,建议业务规则"升序排序" + */ + private Integer orderIndex; + + /** + * 是否启用:0=禁用 1=启用 + */ + private Integer enabled; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/domain/SdHycdDic.java b/backend/src/main/java/com/yfd/platform/env/domain/SdHycdDic.java index b236f97..edf1562 100644 --- a/backend/src/main/java/com/yfd/platform/env/domain/SdHycdDic.java +++ b/backend/src/main/java/com/yfd/platform/env/domain/SdHycdDic.java @@ -83,4 +83,10 @@ public class SdHycdDic implements Serializable { * 简称 */ private String shortname; + + /** + * 类型 1:集团 ;2:公司 + */ + private String lx; + } diff --git a/backend/src/main/java/com/yfd/platform/env/mapper/SdEngInfoBHMapper.java b/backend/src/main/java/com/yfd/platform/env/mapper/SdEngInfoBHMapper.java index 31667a7..0c6b51c 100644 --- a/backend/src/main/java/com/yfd/platform/env/mapper/SdEngInfoBHMapper.java +++ b/backend/src/main/java/com/yfd/platform/env/mapper/SdEngInfoBHMapper.java @@ -27,4 +27,14 @@ public interface SdEngInfoBHMapper extends BaseMapper { * 根据流域编码查询电站列表(通过关联关系) */ List selectByRvcd(@Param("rvcd") String rvcd); + + /** + * 根据基地流域编码查询电站列表 + */ + List selectByHbrvcd(@Param("hbrvcd") String hbrvcd); + + /** + * 根据基地流域编码列表批量查询电站 + */ + List selectByHbrvcdList(@Param("hbrvcdList") List hbrvcdList); } diff --git a/backend/src/main/java/com/yfd/platform/env/mapper/SdHbrvDicMapper.java b/backend/src/main/java/com/yfd/platform/env/mapper/SdHbrvDicMapper.java new file mode 100644 index 0000000..715e22a --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/mapper/SdHbrvDicMapper.java @@ -0,0 +1,30 @@ +package com.yfd.platform.env.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yfd.platform.env.domain.SdHbrvDic; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 水电基地流域表 Mapper 接口 + *

+ */ +public interface SdHbrvDicMapper extends BaseMapper { + + /** + * 根据基地编码查询流域列表 + */ + List selectByBaseid(@Param("baseid") String baseid); + + /** + * 根据父流域编码查询流域列表 + */ + List selectByPhycd(@Param("hbrvcd") String hbrvcd, @Param("baseid") String baseid); + + /** + * 查询所有启用的流域 + */ + List selectEnabledList(); +} \ 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 4f6eed1..29de2f2 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 @@ -55,4 +55,6 @@ public interface ISdEngInfoBHService extends IService { * 删除电站 */ boolean deleteEngInfo(String stcd); + + List selectRegDropdown(String baseId, String ennm); } \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/service/ISdHbrvDicService.java b/backend/src/main/java/com/yfd/platform/env/service/ISdHbrvDicService.java new file mode 100644 index 0000000..3f3cf23 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/service/ISdHbrvDicService.java @@ -0,0 +1,61 @@ +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.SdHbrvDic; + +import java.util.List; +import java.util.Set; + +/** + *

+ * 水电基地流域表 服务类 + *

+ */ +public interface ISdHbrvDicService extends IService { + + /** + * 分页查询流域列表 + */ + Page queryPageList(Page page, String hbrvnm, String baseid); + + /** + * 根据基地编码查询流域列表 + */ + List getByBaseid(String baseid); + + /** + * 根据父流域编码查询流域列表 + */ + List getByHbrvcd(String hbrvcd, String baseid); + + /** + * 查询所有启用的流域 + */ + List getEnabledList(); + + /** + * 新增流域 + */ + boolean addHbrvDic(SdHbrvDic hbrvDic); + + /** + * 修改流域 + */ + boolean updateHbrvDic(SdHbrvDic hbrvDic); + + /** + * 删除流域 + */ + boolean deleteHbrvDic(String hbrvcd, String baseid); + + /** + * 下拉框列表查询(支持名称模糊查询) + */ + List selectForDropdown(String hbrvnm, String baseid); + + Set getUserAuthorizedStationCodes(); + + List regDropdown(String hbrvnm, String baseid); + +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/service/ISdHycdDicService.java b/backend/src/main/java/com/yfd/platform/env/service/ISdHycdDicService.java index 02a57be..ea2c24a 100644 --- a/backend/src/main/java/com/yfd/platform/env/service/ISdHycdDicService.java +++ b/backend/src/main/java/com/yfd/platform/env/service/ISdHycdDicService.java @@ -42,4 +42,11 @@ public interface ISdHycdDicService extends IService { * 删除公司 */ boolean deleteHycdDic(String hycd); + + /** + * 下拉框列表查询(支持名称和级别过滤) + */ + List selectForDropdown(String hynm, Integer grd); + + List regDropdown(String hynm, Integer grd); } diff --git a/backend/src/main/java/com/yfd/platform/env/service/ITreeStructureService.java b/backend/src/main/java/com/yfd/platform/env/service/ITreeStructureService.java index d6ca549..03342c9 100644 --- a/backend/src/main/java/com/yfd/platform/env/service/ITreeStructureService.java +++ b/backend/src/main/java/com/yfd/platform/env/service/ITreeStructureService.java @@ -52,4 +52,11 @@ public interface ITreeStructureService { * @param engName 电站名称(可选,用于模糊筛选电站) */ List> getBaseEngTree(String baseId, String engName); + + /** + * 获取基地流域-电站树形结构(二级树) + * @param hbrvcd 基地流域编码(可选,为空则返回全部) + * @param engName 电站名称(可选,用于模糊筛选电站) + */ + List> getHbrvEngTree(String hbrvcd, String engName); } 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 713b625..9219ece 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 @@ -75,9 +75,10 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl authorizedStations = getUserAuthorizedStationCodes(); if (authorizedStations != null && !authorizedStations.isEmpty()) { wrapper.in(SdEngInfoBH::getStcd, authorizedStations); - } else { - return new ArrayList<>(); } +// else { +// return new ArrayList<>(); +// } return this.list(wrapper); } @@ -104,7 +105,7 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl engInfos = this.lambdaQuery() .select(SdEngInfoBH::getStcd) - .in(SdEngInfoBH::getRvcd, basinCodes) + .in(SdEngInfoBH::getHbrvcd, basinCodes) .list(); return engInfos.stream() .map(SdEngInfoBH::getStcd) @@ -140,4 +141,15 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl selectRegDropdown(String baseId, String ennm) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(StringUtils.hasText(baseId), SdEngInfoBH::getBaseId, baseId) + .like(StringUtils.hasText(ennm), SdEngInfoBH::getEnnm, ennm) + .select(SdEngInfoBH::getStcd, SdEngInfoBH::getEnnm, SdEngInfoBH::getBaseId) + .orderByAsc(SdEngInfoBH::getOrderIndex); + + return this.list(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 index b70dc13..4cea76a 100644 --- 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 @@ -67,10 +67,6 @@ public class SdFpssBHServiceImpl extends ServiceImpl i public List selectForDropdown(String rstcd, String stnm, String baseId) { Set authorizedStations = getUserAuthorizedStationCodes(); - if (authorizedStations == null || authorizedStations.isEmpty()) { - return new ArrayList<>(); - } - List result; if (StringUtils.hasText(baseId)) { @@ -82,6 +78,9 @@ public class SdFpssBHServiceImpl extends ServiceImpl i .orderByDesc(SdFpssBH::getOrderIndex); result = list(wrapper); } + if (authorizedStations.isEmpty()) { + return result; + } return result.stream() .filter(fpss -> authorizedStations.contains(fpss.getRstcd())) @@ -110,7 +109,7 @@ public class SdFpssBHServiceImpl extends ServiceImpl i if ("STATION".equals(orgType)) { stationCodes.add(orgId); - } else if ("BASIN".equals(orgType)) { + } else if ("HBRVCD".equals(orgType)) { basinCodes.add(orgId); } } @@ -123,7 +122,7 @@ public class SdFpssBHServiceImpl extends ServiceImpl i List engInfos = sdEngInfoBHMapper.selectList( new LambdaQueryWrapper() .select(SdEngInfoBH::getStcd) - .in(SdEngInfoBH::getRvcd, basinCodes) + .in(SdEngInfoBH::getHbrvcd, basinCodes) ); return engInfos.stream() .map(SdEngInfoBH::getStcd) diff --git a/backend/src/main/java/com/yfd/platform/env/service/impl/SdHbrvDicServiceImpl.java b/backend/src/main/java/com/yfd/platform/env/service/impl/SdHbrvDicServiceImpl.java new file mode 100644 index 0000000..dac49a8 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/service/impl/SdHbrvDicServiceImpl.java @@ -0,0 +1,174 @@ +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.data.domain.SysUserDataScope; +import com.yfd.platform.data.mapper.SysUserDataScopeMapper; +import com.yfd.platform.env.domain.SdEngInfoBH; +import com.yfd.platform.env.domain.SdHbrvDic; +import com.yfd.platform.env.domain.SdHydrobase; +import com.yfd.platform.env.mapper.SdEngInfoBHMapper; +import com.yfd.platform.env.mapper.SdHbrvDicMapper; +import com.yfd.platform.env.service.ISdHbrvDicService; +import com.yfd.platform.utils.SecurityUtils; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + *

+ * 水电基地流域表 服务实现类 + *

+ */ +@Service +public class SdHbrvDicServiceImpl extends ServiceImpl implements ISdHbrvDicService { + @Resource + private SysUserDataScopeMapper sysUserDataScopeMapper; + + @Resource + private SdEngInfoBHMapper engInfoBHMapper; + @Override + public Page queryPageList(Page page, String hbrvnm, String baseid) { + return this.page(page, this.lambdaQuery() + .like(hbrvnm != null && !hbrvnm.isEmpty(), SdHbrvDic::getHbrvnm, hbrvnm) + .eq(baseid != null && !baseid.isEmpty(), SdHbrvDic::getBaseid, baseid) + .orderByAsc(SdHbrvDic::getOrderIndex) + .getWrapper()); + } + + @Override + public List getByBaseid(String baseid) { + return this.lambdaQuery() + .eq(SdHbrvDic::getBaseid, baseid) + .orderByAsc(SdHbrvDic::getOrderIndex) + .list(); + } + + @Override + public List getByHbrvcd(String hbrvcd, String baseid) { + return this.lambdaQuery() + .eq(SdHbrvDic::getHbrvcd, hbrvcd) + .eq(SdHbrvDic::getBaseid, baseid) + .orderByAsc(SdHbrvDic::getOrderIndex) + .list(); + } + + @Override + public List getEnabledList() { + return this.lambdaQuery() + .eq(SdHbrvDic::getEnabled, 1) + .orderByAsc(SdHbrvDic::getOrderIndex) + .list(); + } + + @Override + public boolean addHbrvDic(SdHbrvDic hbrvDic) { + if (hbrvDic.getOrderIndex() == null) { + hbrvDic.setOrderIndex(9999); + } + if (hbrvDic.getEnabled() == null) { + hbrvDic.setEnabled(1); + } + return this.save(hbrvDic); + } + + @Override + public boolean updateHbrvDic(SdHbrvDic hbrvDic) { + return this.updateById(hbrvDic); + } + + @Override + public boolean deleteHbrvDic(String hbrvcd, String baseid) { + return this.removeById(hbrvcd); + } + + @Override + public List selectForDropdown(String hbrvnm, String baseid) { + Set authorizedStations = getUserAuthorizedStationCodes(); + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + if (authorizedStations != null && !authorizedStations.isEmpty()) { + List engInfos = engInfoBHMapper.selectList( + new LambdaQueryWrapper() + .select(SdEngInfoBH::getHbrvcd) + .in(SdEngInfoBH::getStcd, authorizedStations) + ); + List hbrvcds = engInfos.stream() + .map(SdEngInfoBH::getHbrvcd) + .filter(id -> id != null && !id.isEmpty()) + .distinct() + .collect(Collectors.toList()); + + if (!hbrvcds.isEmpty()) { + wrapper.in(SdHbrvDic::getHbrvcd, hbrvcds); + } else { + return new ArrayList<>(); + } + } + wrapper.like(hbrvnm != null && !hbrvnm.isEmpty(), SdHbrvDic::getHbrvnm, hbrvnm) + .eq(baseid != null && !baseid.isEmpty(), SdHbrvDic::getBaseid, baseid) + .eq(SdHbrvDic::getEnabled, 1) + .orderByAsc(SdHbrvDic::getOrderIndex); + return this.list(wrapper); + } + + @Override + public Set getUserAuthorizedStationCodes() { + String userId = SecurityUtils.getUserId(); + List sysUserDataScopes = sysUserDataScopeMapper.selectList( + new LambdaQueryWrapper() + .eq(SysUserDataScope::getUserId, userId) + .select(SysUserDataScope::getOrgId, SysUserDataScope::getOrgType) + ); + + if (sysUserDataScopes == null || sysUserDataScopes.isEmpty()) { + return new HashSet<>(); + } + + Set stationCodes = new HashSet<>(); + List basinCodes = new ArrayList<>(); + + for (SysUserDataScope scope : sysUserDataScopes) { + String orgType = scope.getOrgType(); + String orgId = scope.getOrgId(); + + if ("STATION".equals(orgType)) { + stationCodes.add(orgId); + } else if ("HBRVCD".equals(orgType)) { + basinCodes.add(orgId); + } + } + + if (!stationCodes.isEmpty()) { + return stationCodes; + } + + if (!basinCodes.isEmpty()) { + List engInfos = engInfoBHMapper.selectList( + new LambdaQueryWrapper() + .select(SdEngInfoBH::getStcd) + .in(SdEngInfoBH::getHbrvcd, basinCodes) + ); + return engInfos.stream() + .map(SdEngInfoBH::getStcd) + .collect(Collectors.toSet()); + } + + return stationCodes; + } + + @Override + public List regDropdown(String hbrvnm, String baseid) { + return this.lambdaQuery() + .like(hbrvnm != null && !hbrvnm.isEmpty(), SdHbrvDic::getHbrvnm, hbrvnm) + .eq(baseid != null && !baseid.isEmpty(), SdHbrvDic::getBaseid, baseid) + .eq(SdHbrvDic::getEnabled, 1) + .orderByAsc(SdHbrvDic::getOrderIndex) + .list(); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/env/service/impl/SdHycdDicServiceImpl.java b/backend/src/main/java/com/yfd/platform/env/service/impl/SdHycdDicServiceImpl.java index f2294fe..2c0e4f7 100644 --- a/backend/src/main/java/com/yfd/platform/env/service/impl/SdHycdDicServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/env/service/impl/SdHycdDicServiceImpl.java @@ -56,4 +56,22 @@ public class SdHycdDicServiceImpl extends ServiceImpl selectForDropdown(String hynm, Integer grd) { + return this.lambdaQuery() + .like(hynm != null && !hynm.isEmpty(), SdHycdDic::getHynm, hynm) + .eq(grd != null, SdHycdDic::getGrd, grd) + .orderByAsc(SdHycdDic::getOrderIndex) + .list(); + } + + @Override + public List regDropdown(String hynm, Integer grd) { + return this.lambdaQuery() + .like(hynm != null && !hynm.isEmpty(), SdHycdDic::getHynm, hynm) + .eq(grd != null, SdHycdDic::getGrd, grd) + .orderByAsc(SdHycdDic::getOrderIndex) + .list(); + } } 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 febc709..3523a05 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 @@ -87,9 +87,10 @@ public class SdHydrobaseServiceImpl extends ServiceImpl(); } - } else { - return new ArrayList<>(); } +// else { +// return new ArrayList<>(); +// } wrapper.orderByAsc(SdHydrobase::getOrderIndex); return this.list(wrapper); } @@ -116,7 +117,7 @@ public class SdHydrobaseServiceImpl extends ServiceImpl engInfos = sdEngInfoBHMapper.selectList( new LambdaQueryWrapper() .select(SdEngInfoBH::getStcd) - .in(SdEngInfoBH::getRvcd, basinCodes) + .in(SdEngInfoBH::getHbrvcd, basinCodes) ); return engInfos.stream() .map(SdEngInfoBH::getStcd) diff --git a/backend/src/main/java/com/yfd/platform/env/service/impl/TreeStructureServiceImpl.java b/backend/src/main/java/com/yfd/platform/env/service/impl/TreeStructureServiceImpl.java index 3cfe57d..233835d 100644 --- a/backend/src/main/java/com/yfd/platform/env/service/impl/TreeStructureServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/env/service/impl/TreeStructureServiceImpl.java @@ -2,6 +2,7 @@ package com.yfd.platform.env.service.impl; import com.yfd.platform.env.domain.SdEngInfoBH; import com.yfd.platform.env.domain.SdHydrobase; +import com.yfd.platform.env.domain.SdHbrvDic; import com.yfd.platform.env.domain.SdHycdDic; import com.yfd.platform.env.domain.SdPrhbrltnB; import com.yfd.platform.env.domain.SdPrhyrltnB; @@ -41,6 +42,9 @@ public class TreeStructureServiceImpl implements ITreeStructureService { @Autowired private SdPrhyrltnBMapper prhyrltnBMapper; + @Autowired + private SdHbrvDicMapper hbrvDicMapper; + @Override public List> getRvcdBaseEngTree(String rvcd, String engName) { List> result = new ArrayList<>(); @@ -75,7 +79,7 @@ public class TreeStructureServiceImpl implements ITreeStructureService { for (SdRvcdDic rvcdDic : rvcdList) { Map rvcdNode = new LinkedHashMap<>(); - rvcdNode.put("type", "BASIN"); + rvcdNode.put("type", "RVCD"); rvcdNode.put("code", rvcdDic.getRvcd()); rvcdNode.put("name", rvcdDic.getRvnm()); rvcdNode.put("path", rvcdDic.getPath()); @@ -187,7 +191,7 @@ public class TreeStructureServiceImpl implements ITreeStructureService { // 3. 构建树形结构 for (SdRvcdDic rvcdDic : rvcdList) { Map rvcdNode = new LinkedHashMap<>(); - rvcdNode.put("type", "BASIN"); + rvcdNode.put("type", "RVCD"); rvcdNode.put("code", rvcdDic.getRvcd()); rvcdNode.put("name", rvcdDic.getRvnm()); rvcdNode.put("path", rvcdDic.getPath()); @@ -384,7 +388,7 @@ public class TreeStructureServiceImpl implements ITreeStructureService { // 3. 构建二级树形结构(流域 -> 电站) for (SdRvcdDic rvcdDic : rvcdList) { Map rvcdNode = new LinkedHashMap<>(); - rvcdNode.put("type", "BASIN"); + rvcdNode.put("type", "RVCD"); rvcdNode.put("code", rvcdDic.getRvcd()); rvcdNode.put("name", rvcdDic.getRvnm()); rvcdNode.put("path", rvcdDic.getPath()); @@ -503,5 +507,86 @@ public class TreeStructureServiceImpl implements ITreeStructureService { return result; } + @Override + public List> getHbrvEngTree(String hbrvcd, String engName) { + List> result = new ArrayList<>(); + + List hbrvList; + if (StringUtils.hasText(hbrvcd)) { + hbrvList = hbrvDicMapper.selectByPhycd(hbrvcd, null); + SdHbrvDic singleHbrv = hbrvDicMapper.selectById(hbrvcd); + if (singleHbrv != null && !hbrvList.contains(singleHbrv)) { + hbrvList = new ArrayList<>(); + hbrvList.add(singleHbrv); + } + } else { + hbrvList = hbrvDicMapper.selectEnabledList(); + } + + if (hbrvList == null || hbrvList.isEmpty()) { + return result; + } + + List hbrvcdList = hbrvList.stream() + .map(SdHbrvDic::getHbrvcd) + .collect(Collectors.toList()); + + List allEngList = engInfoBHMapper.selectByHbrvcdList(hbrvcdList); + + if (StringUtils.hasText(engName) && allEngList != null) { + allEngList = allEngList.stream() + .filter(eng -> eng.getEnnm() != null && eng.getEnnm().contains(engName)) + .collect(Collectors.toList()); + } + + Map> hbrvEngMap = new HashMap<>(); + if (allEngList != null && !allEngList.isEmpty()) { + for (SdEngInfoBH eng : allEngList) { + String engHbrvcd = eng.getHbrvcd(); + hbrvEngMap.computeIfAbsent(engHbrvcd, k -> new ArrayList<>()).add(eng); + } + } + + for (SdHbrvDic hbrvDic : hbrvList) { + Map hbrvNode = new LinkedHashMap<>(); + hbrvNode.put("type", "HBRVCD"); + hbrvNode.put("code", hbrvDic.getHbrvcd()); + hbrvNode.put("name", hbrvDic.getHbrvnm()); + hbrvNode.put("grd", hbrvDic.getGrd()); + hbrvNode.put("path", hbrvDic.getPath()); + hbrvNode.put("baseid", hbrvDic.getBaseid()); + hbrvNode.put("parentId", "0"); + hbrvNode.put("orgLevel", 0); + + List engList = hbrvEngMap.get(hbrvDic.getHbrvcd()); + List> engChildren = new ArrayList<>(); + + if (engList != null && !engList.isEmpty()) { + for (SdEngInfoBH eng : engList) { + Map engNode = new LinkedHashMap<>(); + engNode.put("type", "STATION"); + engNode.put("code", eng.getStcd()); + engNode.put("name", eng.getEnnm()); + engNode.put("lgtd", eng.getLgtd()); + engNode.put("lttd", eng.getLttd()); + engNode.put("elev", eng.getElev()); + engNode.put("usfl", eng.getUsfl()); + engNode.put("bldstt", eng.getBldstt()); + engNode.put("engtp", eng.getEngtp()); + engNode.put("parentId", hbrvDic.getHbrvcd()); + engNode.put("orgLevel", 1); + engChildren.add(engNode); + } + } + + if (!engChildren.isEmpty()) { + hbrvNode.put("children", engChildren); + result.add(hbrvNode); + } + } + + return result; + } + } diff --git a/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java b/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java new file mode 100644 index 0000000..98b329a --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/controller/SmsVerifyCodeController.java @@ -0,0 +1,282 @@ +package com.yfd.platform.system.controller; + +import cn.hutool.json.JSONUtil; +import cn.hutool.jwt.JWTUtil; +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.config.WebConfig; +import com.yfd.platform.system.domain.*; +import com.yfd.platform.system.service.ISmsVerifyCodeService; +import com.yfd.platform.system.service.ISysLogService; +import com.yfd.platform.system.service.IUserService; +import com.yfd.platform.utils.RequestHolder; +import com.yfd.platform.utils.StringUtils; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.web.bind.annotation.*; + +import java.sql.Timestamp; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +/** + *

+ * 短信验证码控制器 + *

+ */ +@RestController +@RequestMapping("/sms") +@Tag(name = "短信验证码管理") +public class SmsVerifyCodeController { + + @Resource + private ISmsVerifyCodeService smsVerifyCodeService; + + @Resource + private IUserService userService; + + @Resource + private WebConfig webConfig; + + @Resource + private ISysLogService sysLogService; + + @Value("${rsa.private_key}") + private String privateKey; + + /** + * 发送验证码 + */ + @PostMapping("/sendCode") + @Operation(summary = "发送验证码") + public ResponseResult sendVerifyCode(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { + String phone = smsVerifyCodeRequest.getPhone(); + Integer type = smsVerifyCodeRequest.getType(); + if (phone == null || phone.isEmpty()) { + return ResponseResult.error("手机号不能为空"); + } + if (type == null || (!type.equals(SmsVerifyCode.TYPE_REGISTER) && !type.equals(SmsVerifyCode.TYPE_FIND_PASSWORD))) { + return ResponseResult.error("类型错误:1-注册 2-找回密码"); + } + + if (type.equals(SmsVerifyCode.TYPE_REGISTER)) { + SysUser existUser = userService.getUserByPhone(phone); + if (existUser != null) { + return ResponseResult.error("该手机号已注册"); + } + } + + if (type.equals(SmsVerifyCode.TYPE_FIND_PASSWORD)) { + SysUser existUser = userService.getUserByPhone(phone); + if (existUser == null) { + return ResponseResult.error("该手机号未注册"); + } + } + + String code = smsVerifyCodeService.sendVerifyCode(phone, type); + if (code == null) { + return ResponseResult.error("验证码发送失败,请稍后重试"); + } + + return ResponseResult.success(); + } + + /** + * 注册用户 + */ + @PostMapping("/register") + @Operation(summary = "注册用户") + public ResponseResult register(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { + SysUser user = smsVerifyCodeRequest.getUser(); + String code = smsVerifyCodeRequest.getCode(); + if (user.getPhone() == null || user.getPhone().isEmpty()) { + return ResponseResult.error("手机号不能为空"); + } + if (user.getUsername() == null || user.getUsername().isEmpty()) { + return ResponseResult.error("用户名不能为空"); + } + if (user.getPassword() == null || user.getPassword().isEmpty()) { + return ResponseResult.error("密码不能为空"); + } + if (code == null || code.isEmpty()) { + return ResponseResult.error("验证码不能为空"); + } + + boolean verified = smsVerifyCodeService.verifyCode(user.getPhone(), code, SmsVerifyCode.TYPE_REGISTER); + if (!verified) { + return ResponseResult.error("验证码错误或已过期"); + } + + SysUser existUser = userService.getUserByPhone(user.getPhone()); + if (existUser != null) { + return ResponseResult.error("该手机号已注册"); + } + + try { + com.yfd.platform.utils.RsaUtils.decryptByPrivateKey(privateKey, user.getPassword()); + } catch (Exception e) { + return ResponseResult.error("密码解密失败"); + } + + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + user.setPassword(passwordEncoder.encode(user.getPassword())); + user.setRegStatus(0); + user.setRegTime(new Date()); + user.setStatus(1); + user.setUsertype(1); + + boolean success = userService.save(user); + if (success) { + return ResponseResult.success(); + } else { + return ResponseResult.error("注册失败"); + } + } + + /** + * 找回密码 + */ + @PostMapping("/resetPassword") + @Operation(summary = "找回密码") + public ResponseResult resetPassword(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { + String password = smsVerifyCodeRequest.getPassword(); + String phone = smsVerifyCodeRequest.getPhone(); + String code = smsVerifyCodeRequest.getCode(); + if (phone == null || phone.isEmpty()) { + return ResponseResult.error("手机号不能为空"); + } + if (code == null || code.isEmpty()) { + return ResponseResult.error("验证码不能为空"); + } + if (password == null || password.isEmpty()) { + return ResponseResult.error("新密码不能为空"); + } + + boolean verified = smsVerifyCodeService.verifyCode(phone, code, SmsVerifyCode.TYPE_FIND_PASSWORD); + if (!verified) { + return ResponseResult.error("验证码错误或已过期"); + } + + SysUser existUser = userService.getUserByPhone(phone); + if (existUser == null) { + return ResponseResult.error("该手机号未注册"); + } + + BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); + String encryptedPassword = passwordEncoder.encode(password); + + boolean success = userService.updatePasswordByPhone(phone, encryptedPassword); + if (success) { + return ResponseResult.success(); + } else { + return ResponseResult.error("密码重置失败"); + } + } + + /** + * 验证验证码是否有效 + */ + @GetMapping("/verifyCode") + @Operation(summary = "验证验证码") + public ResponseResult verifyCode(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { + String phone = smsVerifyCodeRequest.getPhone(); + String code = smsVerifyCodeRequest.getCode(); + Integer type = smsVerifyCodeRequest.getType(); + boolean valid = smsVerifyCodeService.verifyCode(phone, code, type); + if (valid) { + return ResponseResult.success(); + } else { + return ResponseResult.error("验证码错误或已过期"); + } + } + + /** + * 短信验证码登录 + */ + @PostMapping("/login") + @Operation(summary = "短信验证码登录") + public ResponseResult smsLogin(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) { + String phone = smsVerifyCodeRequest.getPhone(); + String code = smsVerifyCodeRequest.getCode(); + if (phone == null || phone.isEmpty()) { + return ResponseResult.error("手机号不能为空"); + } + if (code == null || code.isEmpty()) { + return ResponseResult.error("验证码不能为空"); + } + + boolean verified = smsVerifyCodeService.verifyCode(phone, code, SmsVerifyCode.TYPE_REGISTER); + if (!verified) { + return ResponseResult.error("验证码错误或已过期"); + } + + SysUser user = userService.getUserByPhone(phone); + if (user == null) { + return ResponseResult.error("该手机号未注册"); + } + + if (user.getStatus() != null && user.getStatus() == 0) { + return ResponseResult.error("账号已停用"); + } + + if (user.getRegStatus() != null && user.getRegStatus() == 0) { + return ResponseResult.error("账号待审核,请联系管理员"); + } + + if (user.getRegStatus() != null && user.getRegStatus() == 2) { + return ResponseResult.error("账号审核未通过"); + } + + UsernamePasswordAuthenticationToken authenticationToken = + new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()); + Authentication authenticate = new UsernamePasswordAuthenticationToken(user, null, authenticationToken.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(authenticate); + + LoginUser loginUser = new LoginUser(); + loginUser.setUser(user); + loginUser.setUsername(user.getUsername()); + + HttpServletRequest request = RequestHolder.getHttpServletRequest(); + SysLog sysLog = new SysLog(); + sysLog.setUsercode(user.getUsername()); + sysLog.setUsername(user.getNickname()); + sysLog.setRequestip(StringUtils.getIp(request)); + sysLog.setBrowser(StringUtils.getBrowser(request)); + sysLog.setOpttype("登录(login)"); + sysLog.setModule("短信验证码登录"); + sysLog.setMethod(this.getClass().getName() + ".smsLogin()"); + sysLog.setDescription(user.getNickname() + "使用短信验证码登录系统!"); + sysLog.setLogtime(new Timestamp(System.currentTimeMillis())); + sysLogService.save(sysLog); + + String userId = user.getId(); + Map map = new HashMap<>(10) { + private static final long serialVersionUID = 1L; + + { + put("userid", userId); + put("username", loginUser.getUsername()); + long expireTime = System.currentTimeMillis() + (30L * 24L * 60L * 60L * 1000L); + put("expire_time", expireTime); + } + }; + + String token = JWTUtil.createToken(map, "12345678".getBytes()); + map.put("token", token); + + String jsonStr = JSONUtil.toJsonStr(loginUser); + webConfig.loginuserCache().put("login:" + userId, jsonStr); + webConfig.loginuserCache().put("expire_time:" + userId, map.get("expire_time").toString()); + + map.put("user", user); + + return ResponseResult.successData(map); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/system/controller/UserController.java b/backend/src/main/java/com/yfd/platform/system/controller/UserController.java index 914b8f7..6c9d287 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/UserController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/UserController.java @@ -200,4 +200,32 @@ public class UserController { boolean ok = userService.uploadAvatar(id, multipartFile); return ResponseResult.success(); } + + @Log(module = "系统用户", value = "审核用户注册") + @PostMapping("/auditUser") + @Operation(summary = "审核用户注册") + @ResponseBody + public ResponseResult auditUser(@RequestParam String userId, + @RequestParam Integer auditStatus) { + if (userId == null || userId.isEmpty()) { + return ResponseResult.error("用户ID不能为空"); + } + if (auditStatus == null || (auditStatus != 1 && auditStatus != 2)) { + return ResponseResult.error("审核状态错误:1-通过 2-驳回"); + } + boolean ok = userService.auditUser(userId, auditStatus); + if (ok) { + return ResponseResult.success(); + } else { + return ResponseResult.error("审核失败"); + } + } + + @GetMapping("/queryPendingAuditUsers") + @Operation(summary = "查询待审核用户列表") + @ResponseBody + public ResponseResult queryPendingAuditUsers(Page page) { + Page result = userService.queryPendingAuditUsers(page); + return ResponseResult.successData(result); + } } diff --git a/backend/src/main/java/com/yfd/platform/system/domain/LoginUser.java b/backend/src/main/java/com/yfd/platform/system/domain/LoginUser.java index 44cfb35..902c628 100644 --- a/backend/src/main/java/com/yfd/platform/system/domain/LoginUser.java +++ b/backend/src/main/java/com/yfd/platform/system/domain/LoginUser.java @@ -20,6 +20,8 @@ public class LoginUser implements UserDetails { private SysUser user; + private String username; + private List permissions; public LoginUser(SysUser user, List permissions) { diff --git a/backend/src/main/java/com/yfd/platform/system/domain/SmsVerifyCode.java b/backend/src/main/java/com/yfd/platform/system/domain/SmsVerifyCode.java new file mode 100644 index 0000000..2cc1351 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/domain/SmsVerifyCode.java @@ -0,0 +1,65 @@ +package com.yfd.platform.system.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 短信验证码表 + *

+ */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("SMS_VERIFY_CODE") +public class SmsVerifyCode implements Serializable { + + private static final long serialVersionUID = 1L; + + public static final Integer TYPE_REGISTER = 1; + public static final Integer TYPE_FIND_PASSWORD = 2; + + public static final Integer STATUS_UNUSED = 0; + public static final Integer STATUS_USED = 1; + + /** + * 主键,默认SYS_GUID() + */ + @TableId(type = IdType.INPUT) + private String id; + + /** + * 手机号 + */ + private String phone; + + /** + * 验证码 + */ + private String code; + + /** + * 1-注册 2-找回密码 + */ + private Integer type; + + /** + * 过期时间 + */ + private Date expireTime; + + /** + * 创建时间,默认当前时间 + */ + private Date createTime; + + /** + * 0-未使用 1-已使用 + */ + private Integer status; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/system/domain/SmsVerifyCodeRequest.java b/backend/src/main/java/com/yfd/platform/system/domain/SmsVerifyCodeRequest.java new file mode 100644 index 0000000..b7f59eb --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/domain/SmsVerifyCodeRequest.java @@ -0,0 +1,50 @@ +package com.yfd.platform.system.domain; + + +import lombok.Data; + +@Data +public class SmsVerifyCodeRequest { + + /** + * 验证码类型 + */ + private Integer type; + /** + * 手机号 + */ + private String phone; + /** + * 验证码 + */ + private String code; + + /** + * 密码 + */ + private String password; + + /** + * 用户 + */ + private SysUser user; + + /** + * 流域编号 + */ + private String rvcdCode; + /** + * 集团编号 + */ + private String groupCode; + /** + * 公司编号 + */ + private String companyCode; + /** + * 站点编号 + */ + private String stationCode; + + +} diff --git a/backend/src/main/java/com/yfd/platform/system/domain/SysUser.java b/backend/src/main/java/com/yfd/platform/system/domain/SysUser.java index 57c5b85..ed9b24f 100644 --- a/backend/src/main/java/com/yfd/platform/system/domain/SysUser.java +++ b/backend/src/main/java/com/yfd/platform/system/domain/SysUser.java @@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode; import java.io.Serializable; import java.sql.Timestamp; +import java.util.Date; import java.util.List; /** @@ -115,6 +116,31 @@ public class SysUser implements Serializable { */ private String custom3; + /** + * 真实姓名(注册必填) + */ + private String realName; + + /** + * 注册状态:0-待审核 1-已通过 2-已驳回 + */ + private Integer regStatus; + + /** + * 审核人ID + */ + private String auditUser; + + /** + * 审核时间 + */ + private Date auditTime; + + /** + * 注册申请时间 + */ + private Date regTime; + @TableField(exist = false) List roles; } diff --git a/backend/src/main/java/com/yfd/platform/system/mapper/SmsVerifyCodeMapper.java b/backend/src/main/java/com/yfd/platform/system/mapper/SmsVerifyCodeMapper.java new file mode 100644 index 0000000..714ab94 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/mapper/SmsVerifyCodeMapper.java @@ -0,0 +1,37 @@ +package com.yfd.platform.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.yfd.platform.system.domain.SmsVerifyCode; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Update; + +import java.util.List; + +/** + *

+ * 短信验证码表 Mapper 接口 + *

+ */ +public interface SmsVerifyCodeMapper extends BaseMapper { + + /** + * 根据手机号和类型查询最新的有效验证码 + */ + SmsVerifyCode selectLatestByPhoneAndType(@Param("phone") String phone, @Param("type") Integer type); + + /** + * 标记验证码为已使用 + */ + @Update("UPDATE SMS_VERIFY_CODE SET STATUS = 1 WHERE ID = #{id}") + int markAsUsed(@Param("id") String id); + + /** + * 删除指定手机号和类型的过期验证码 + */ + int deleteExpiredByPhoneAndType(@Param("phone") String phone, @Param("type") Integer type); + + /** + * 查询指定手机号和类型的未使用验证码 + */ + List selectUnusedByPhoneAndType(@Param("phone") String phone, @Param("type") Integer type); +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/system/service/ISmsVerifyCodeService.java b/backend/src/main/java/com/yfd/platform/system/service/ISmsVerifyCodeService.java new file mode 100644 index 0000000..a8ca1b8 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/service/ISmsVerifyCodeService.java @@ -0,0 +1,40 @@ +package com.yfd.platform.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.yfd.platform.system.domain.SmsVerifyCode; + +/** + *

+ * 短信验证码表 服务类 + *

+ */ +public interface ISmsVerifyCodeService extends IService { + + /** + * 发送验证码 + * @param phone 手机号 + * @param type 1-注册 2-找回密码 + * @return 验证码 + */ + String sendVerifyCode(String phone, Integer type); + + /** + * 验证验证码 + * @param phone 手机号 + * @param code 验证码 + * @param type 类型 1-注册 2-找回密码 + * @return 是否验证通过 + */ + boolean verifyCode(String phone, String code, Integer type); + + /** + * 标记验证码已使用 + * @param id 验证码ID + */ + void markAsUsed(String id); + + /** + * 生成6位数字验证码 + */ + String generateCode(); +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/system/service/IUserService.java b/backend/src/main/java/com/yfd/platform/system/service/IUserService.java index e1ff507..f86da52 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/IUserService.java +++ b/backend/src/main/java/com/yfd/platform/system/service/IUserService.java @@ -138,6 +138,38 @@ public interface IUserService extends IService { ************************************/ boolean deleteUserByIds(String ids); + /*********************************** + * 用途说明:根据手机号查询用户 + * 参数说明 + *phone 手机号 + * 返回值说明: 用户对象 + ************************************/ + SysUser getUserByPhone(String phone); + /*********************************** + * 用途说明:根据手机号修改密码 + * 参数说明 + *phone 手机号 + * encryptedPassword 加密后的密码 + * 返回值说明: 是否修改成功 + ************************************/ + boolean updatePasswordByPhone(String phone, String encryptedPassword); + + /*********************************** + * 用途说明:审核用户注册 + * 参数说明 + *userId 用户id + * auditStatus 审核状态:1-通过 2-驳回 + * 返回值说明: 是否审核成功 + ************************************/ + boolean auditUser(String userId, Integer auditStatus); + + /*********************************** + * 用途说明:查询待审核用户列表 + * 参数说明 + *page 分页参数 + * 返回值说明: 待审核用户分页列表 + ************************************/ + Page queryPendingAuditUsers(Page page); } diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/SmsVerifyCodeServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/SmsVerifyCodeServiceImpl.java new file mode 100644 index 0000000..8e0c91f --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/SmsVerifyCodeServiceImpl.java @@ -0,0 +1,99 @@ +package com.yfd.platform.system.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.yfd.platform.system.domain.SmsVerifyCode; +import com.yfd.platform.system.mapper.SmsVerifyCodeMapper; +import com.yfd.platform.system.service.ISmsVerifyCodeService; +import com.yfd.platform.utils.SmsSender; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; +import java.util.Random; + +/** + *

+ * 短信验证码表 服务实现类 + *

+ */ +@Service +public class SmsVerifyCodeServiceImpl extends ServiceImpl implements ISmsVerifyCodeService { + + private static final int CODE_VALID_MINUTES = 1; + private static final Random RANDOM = new Random(); + + @Resource + private SmsSender smsSender; + + @Override + @Transactional(rollbackFor = Exception.class) + public String sendVerifyCode(String phone, Integer type) { + String code = generateCode(); + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SmsVerifyCode::getPhone, phone) + .eq(SmsVerifyCode::getType, type) + .eq(SmsVerifyCode::getStatus, SmsVerifyCode.STATUS_UNUSED); + this.remove(queryWrapper); + + SmsVerifyCode verifyCode = new SmsVerifyCode(); + verifyCode.setId(java.util.UUID.randomUUID().toString().replace("-", "")); + verifyCode.setPhone(phone); + verifyCode.setCode(code); + verifyCode.setType(type); + verifyCode.setStatus(SmsVerifyCode.STATUS_UNUSED); + verifyCode.setCreateTime(new Date()); + + Date expireTime = new Date(System.currentTimeMillis() + CODE_VALID_MINUTES * 60 * 1000L); + verifyCode.setExpireTime(expireTime); + + this.save(verifyCode); + + String content = "您的验证码为:" + code + "," + CODE_VALID_MINUTES + "分钟内有效,请勿泄露给他人。"; + boolean sent = smsSender.send(phone, content); + + if (!sent) { + return null; + } + + return code; + } + + @Override + public boolean verifyCode(String phone, String code, Integer type) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SmsVerifyCode::getPhone, phone) + .eq(SmsVerifyCode::getCode, code) + .eq(SmsVerifyCode::getType, type) + .eq(SmsVerifyCode::getStatus, SmsVerifyCode.STATUS_UNUSED) + .gt(SmsVerifyCode::getExpireTime, new Date()); + + SmsVerifyCode verifyCode = this.getOne(queryWrapper); + if (verifyCode == null) { + return false; + } + + verifyCode.setStatus(SmsVerifyCode.STATUS_USED); + this.updateById(verifyCode); + + return true; + } + + @Override + public void markAsUsed(String id) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SmsVerifyCode::getId, id); + SmsVerifyCode verifyCode = this.getOne(queryWrapper); + if (verifyCode != null) { + verifyCode.setStatus(SmsVerifyCode.STATUS_USED); + this.updateById(verifyCode); + } + } + + @Override + public String generateCode() { + return String.format("%06d", RANDOM.nextInt(1000000)); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java index 7e483f1..537a57f 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java @@ -561,6 +561,49 @@ public class UserServiceImpl extends ServiceImpl impleme } } + @Override + public SysUser getUserByPhone(String phone) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUser::getPhone, phone); + return this.getOne(queryWrapper); + } + + @Override + public boolean updatePasswordByPhone(String phone, String encryptedPassword) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("phone", phone) + .set("password", encryptedPassword) + .set("pwdresettime", new Timestamp(System.currentTimeMillis())) + .set("lastmodifydate", new Timestamp(System.currentTimeMillis())) + .set("lastmodifier", getUsername()); + return this.update(updateWrapper); + } + + @Override + public boolean auditUser(String userId, Integer auditStatus) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", userId) + .set("reg_status", auditStatus) + .set("audit_user", getUsername()) + .set("audit_time", new Timestamp(System.currentTimeMillis())) + .set("lastmodifydate", new Timestamp(System.currentTimeMillis())) + .set("lastmodifier", getUsername()); + if (auditStatus == 1) { + updateWrapper.set("status", 1); + } else if (auditStatus == 2) { + updateWrapper.set("status", 0); + } + return this.update(updateWrapper); + } + + @Override + public Page queryPendingAuditUsers(Page page) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysUser::getRegStatus, 0); + queryWrapper.orderByDesc(SysUser::getRegTime); + return this.page(page, queryWrapper); + } + /*********************************** * 用途说明:比较登录名称是否有重复 * 参数说明 diff --git a/backend/src/main/java/com/yfd/platform/utils/DefaultSmsSender.java b/backend/src/main/java/com/yfd/platform/utils/DefaultSmsSender.java new file mode 100644 index 0000000..7be8355 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/utils/DefaultSmsSender.java @@ -0,0 +1,66 @@ +package com.yfd.platform.utils; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpUtil; +import com.alibaba.fastjson.JSONObject; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +/** + * 默认短信发送实现(模拟实现) + * 当 sms.enabled=false 或未配置时启用 + * 实际使用时替换为真实的短信网关 + */ +@Slf4j +@Component +@ConditionalOnProperty(name = "sms.enabled", havingValue = "true", matchIfMissing = true) +public class DefaultSmsSender implements SmsSender { + @Resource + private SmsProperties smsProperties; + @Override + public boolean send(String phone, String content) { + if (StrUtil.isBlank(phone) || StrUtil.isBlank(content)) { + log.warn("【短信发送】手机号或内容为空"); + return false; + } + + try { + // 构建请求参数 + Map params = new HashMap<>(); + params.put("phone", phone); + params.put("msg", content); + params.put("source", smsProperties.getSource()); + + log.info("【短信发送】开始发送,URL: {}, 手机号: {}", smsProperties.getUrl(), phone); + + // 发送 POST 请求 + String result = HttpUtil.post(smsProperties.getUrl(), JSONObject.toJSONString(params), smsProperties.getTimeout()); + + if (StrUtil.isNotBlank(result)) { + JSONObject json = JSONObject.parseObject(result); + int code = json.getIntValue("code"); + boolean data = json.getBooleanValue("data"); + String msg = json.getString("msg"); + + if (code == 200 && data) { + log.info("【短信发送】发送成功,手机号: {}", phone); + return true; + } else { + log.error("【短信发送】发送失败,code: {}, msg: {}, 手机号: {}", code, msg, phone); + return false; + } + } else { + log.error("【短信发送】HTTP 请求失败,接口无响应,手机号: {}", phone); + return false; + } + } catch (Exception e) { + log.error("【短信发送】发生异常: {}", e.getMessage(), e); + return false; + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/utils/SmsProperties.java b/backend/src/main/java/com/yfd/platform/utils/SmsProperties.java new file mode 100644 index 0000000..579fe2d --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/utils/SmsProperties.java @@ -0,0 +1,17 @@ +package com.yfd.platform.utils; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Data +@Component +@ConfigurationProperties(prefix = "sms") +public class SmsProperties { + + private String url; + + private Integer source; + + private Integer timeout = 10000; +} diff --git a/backend/src/main/java/com/yfd/platform/utils/SmsSender.java b/backend/src/main/java/com/yfd/platform/utils/SmsSender.java new file mode 100644 index 0000000..1b1b3bc --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/utils/SmsSender.java @@ -0,0 +1,15 @@ +package com.yfd.platform.utils; + +/** + * 短信发送接口 + */ +public interface SmsSender { + + /** + * 发送短信 + * @param phone 手机号 + * @param content 短信内容 + * @return 是否发送成功 + */ + boolean send(String phone, String content); +} \ 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 05839c9..34a784a 100644 --- a/backend/src/main/resources/application-devtw.yml +++ b/backend/src/main/resources/application-devtw.yml @@ -75,6 +75,9 @@ login: # 启动自动数据库初始化(仅 dev/server): app: + # ZIP导入临时目录配置 + zip-import: + temp-dir: ${ZIP_IMPORT_TEMP_DIR:D:\zip_import_temp} init: enabled: false schema: classpath:db-init/sql/min-schema.sql diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 547f405..cfbf0b8 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -1,6 +1,6 @@ spring: profiles: - active: prod + active: devtw jasypt: encryptor: @@ -10,6 +10,13 @@ jasypt: rsa: private_key: ${RSA_PRIVATE_KEY:MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEA0vfvyTdGJkdbHkB8mp0f3FE0GYP3AYPaJF7jUd1M0XxFSE2ceK3k2kw20YvQ09NJKk+OMjWQl9WitG9pB6tSCQIDAQABAkA2SimBrWC2/wvauBuYqjCFwLvYiRYqZKThUS3MZlebXJiLB+Ue/gUifAAKIg1avttUZsHBHrop4qfJCwAI0+YRAiEA+W3NK/RaXtnRqmoUUkb59zsZUBLpvZgQPfj1MhyHDz0CIQDYhsAhPJ3mgS64NbUZmGWuuNKp5coY2GIj/zYDMJp6vQIgUueLFXv/eZ1ekgz2Oi67MNCk5jeTF2BurZqNLR3MSmUCIFT3Q6uHMtsB9Eha4u7hS31tj1UWE+D+ADzp59MGnoftAiBeHT7gDMuqeJHPL4b+kC+gzV4FGTfhR9q3tTbklZkD2A==} +# 短信配置 +sms: + enabled: true + url: http://172.16.31.153:8688/sms/sendNotice + source: 2 + timeout: 10000 + # Actuator & Micrometer 默认配置 management: endpoints: diff --git a/backend/src/main/resources/mapper/data/FishDraftDataMapper.xml b/backend/src/main/resources/mapper/data/FishDraftDataMapper.xml index fc47cec..e07207d 100644 --- a/backend/src/main/resources/mapper/data/FishDraftDataMapper.xml +++ b/backend/src/main/resources/mapper/data/FishDraftDataMapper.xml @@ -6,6 +6,7 @@ + @@ -133,6 +134,9 @@ AND D.STCD = #{stcd} + + AND D.CREATED_BY = #{userId} + AND D.FTP = #{ftp} diff --git a/backend/src/main/resources/mapper/env/SdEngInfoBHMapper.xml b/backend/src/main/resources/mapper/env/SdEngInfoBHMapper.xml index a1b6923..bee8c09 100644 --- a/backend/src/main/resources/mapper/env/SdEngInfoBHMapper.xml +++ b/backend/src/main/resources/mapper/env/SdEngInfoBHMapper.xml @@ -249,4 +249,19 @@ ORDER BY ORDER_INDEX ASC + + + + diff --git a/backend/src/main/resources/mapper/env/SdHbrvDicMapper.xml b/backend/src/main/resources/mapper/env/SdHbrvDicMapper.xml new file mode 100644 index 0000000..850aebd --- /dev/null +++ b/backend/src/main/resources/mapper/env/SdHbrvDicMapper.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/src/main/resources/mapper/env/SdRvcdDicMapper.xml b/backend/src/main/resources/mapper/env/SdRvcdDicMapper.xml index 004754f..1eaf1b7 100644 --- a/backend/src/main/resources/mapper/env/SdRvcdDicMapper.xml +++ b/backend/src/main/resources/mapper/env/SdRvcdDicMapper.xml @@ -39,7 +39,8 @@