This commit is contained in:
扈兆增 2026-04-22 17:53:36 +08:00
commit 6e9b4a4d5b
17 changed files with 1109 additions and 46 deletions

View File

@ -0,0 +1,162 @@
package com.yfd.platform.data.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.common.DataSourceLoadOptionsBase;
import com.yfd.platform.common.DataSourceRequest;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.data.domain.ImportTask;
import com.yfd.platform.data.service.IImportTaskService;
import com.yfd.platform.utils.KendoUtil;
import com.yfd.platform.utils.QgcQueryWrapperUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.List;
/**
* <p>
* 导入任务表 前端控制器
* </p>
*/
@RestController
@RequestMapping("/data/importTask")
@Tag(name = "导入任务管理")
public class ImportTaskController {
@Resource
private IImportTaskService importTaskService;
// @GetMapping("/page")
// @Operation(summary = "分页查询导入任务")
// public ResponseResult queryPageList(
// @RequestParam(defaultValue = "1") Integer current,
// @RequestParam(defaultValue = "10") Integer size,
// @RequestParam(required = false) String bizType,
// @RequestParam(required = false) String status,
// @RequestParam(required = false) Long uploadUserId) {
// Page<ImportTask> page = new Page<>(current, size);
// Page<ImportTask> result = importTaskService.queryPageList(page, bizType, status, uploadUserId);
// return ResponseResult.successData(result);
// }
@PostMapping("/page")
@Operation(summary = "分页查询导入任务")
public ResponseResult queryPageList(@RequestBody DataSourceRequest dataSourceRequest) {
Page page = KendoUtil.getPage(dataSourceRequest);
DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest();
String bizType = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "bizType");
String status = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "status");
String uploadUserId = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "uploadUserId");
Page<ImportTask> result = importTaskService.queryPageList(page, bizType, status, uploadUserId);
return ResponseResult.successData(result);
}
@GetMapping("/list")
@Operation(summary = "查询导入任务列表")
public ResponseResult list() {
List<ImportTask> list = importTaskService.list();
return ResponseResult.successData(list);
}
@GetMapping("/getById")
@Operation(summary = "根据ID查询")
public ResponseResult getById(@RequestParam Long id) {
ImportTask importTask = importTaskService.getById(id);
return ResponseResult.successData(importTask);
}
@GetMapping("/getByImportNo")
@Operation(summary = "根据任务编号查询")
public ResponseResult getByImportNo(@RequestParam String importNo) {
ImportTask importTask = importTaskService.getByImportNo(importNo);
return ResponseResult.successData(importTask);
}
@GetMapping("/getByBizType")
@Operation(summary = "根据业务类型查询")
public ResponseResult getByBizType(@RequestParam String bizType) {
List<ImportTask> list = importTaskService.getByBizType(bizType);
return ResponseResult.successData(list);
}
@GetMapping("/getByStatus")
@Operation(summary = "根据状态查询")
public ResponseResult getByStatus(@RequestParam String status) {
List<ImportTask> list = importTaskService.getByStatus(status);
return ResponseResult.successData(list);
}
@PostMapping("/createTask")
@Operation(summary = "创建导入任务")
public ResponseResult createTask(@RequestBody ImportTask importTask) {
boolean result = importTaskService.createTask(importTask);
return result ? ResponseResult.success("创建成功") : ResponseResult.error("创建失败");
}
@PostMapping("/updateStatus")
@Operation(summary = "更新任务状态")
public ResponseResult updateStatus(@RequestParam String id,
@RequestParam String status,
@RequestParam(required = false) String errorMsg) {
boolean result = importTaskService.updateStatus(id, status, errorMsg);
return result ? ResponseResult.success("更新成功") : ResponseResult.error("更新失败");
}
@PostMapping("/updateProgress")
@Operation(summary = "更新解析进度")
public ResponseResult updateProgress(@RequestParam String id,
@RequestParam(required = false) Integer totalCount,
@RequestParam(required = false) Integer successCount,
@RequestParam(required = false) Integer failCount) {
boolean result = importTaskService.updateProgress(id, totalCount, successCount, failCount);
return result ? ResponseResult.success("更新成功") : ResponseResult.error("更新失败");
}
@PostMapping("/markFailed")
@Operation(summary = "标记任务失败")
public ResponseResult markFailed(@RequestParam String id,
@RequestParam String errorMsg) {
boolean result = importTaskService.markFailed(id, errorMsg);
return result ? ResponseResult.success("标记失败") : ResponseResult.error("标记失败");
}
@PostMapping("/markSuccess")
@Operation(summary = "标记任务成功")
public ResponseResult markSuccess(@RequestParam String id) {
boolean result = importTaskService.markSuccess(id);
return result ? ResponseResult.success("标记成功") : ResponseResult.error("标记失败");
}
@PostMapping("/deleteExpired")
@Operation(summary = "删除过期任务")
public ResponseResult deleteExpired() {
boolean result = importTaskService.deleteExpiredTasks();
return result ? ResponseResult.success("清理完成") : ResponseResult.error("清理失败");
}
@PostMapping("/add")
@Operation(summary = "新增导入任务")
public ResponseResult add(@RequestBody ImportTask importTask) {
importTask.setCreatedAt(new Date());
importTask.setUpdatedAt(new Date());
boolean result = importTaskService.save(importTask);
return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败");
}
@PostMapping("/update")
@Operation(summary = "修改导入任务")
public ResponseResult update(@RequestBody ImportTask importTask) {
importTask.setUpdatedAt(new Date());
boolean result = importTaskService.updateById(importTask);
return result ? ResponseResult.success("修改成功") : ResponseResult.error("修改失败");
}
@PostMapping("/delete")
@Operation(summary = "删除导入任务")
public ResponseResult delete(@RequestParam Long id) {
boolean result = importTaskService.removeById(id);
return result ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败");
}
}

View File

@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.annotation.Log;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.data.domain.SysUserDataScope;
import com.yfd.platform.data.domain.bo.EditUserDataScopeBo;
import com.yfd.platform.data.domain.vo.SysUserDataScopeVO;
import com.yfd.platform.data.service.ISysUserDataScopeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -53,6 +55,13 @@ public class SysUserDataScopeController {
return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败");
}
@PostMapping("/batchAdd")
@Operation(summary = "新增数据填报权限")
public ResponseResult batchAdd(@RequestBody EditUserDataScopeBo editUserDataScopeBo) {
boolean result = dataScopeService.batchAddDataScope(editUserDataScopeBo);
return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败");
}
/**
* 修改数据填报权限
*/
@ -118,7 +127,7 @@ public class SysUserDataScopeController {
@GetMapping("/getValidPermissions")
@Operation(summary = "查询用户有效权限")
public ResponseResult getValidPermissions(@RequestParam String userId) {
List<SysUserDataScope> list = dataScopeService.getValidPermissions(userId);
List<SysUserDataScopeVO> list = dataScopeService.getValidPermissionsWithOrgName(userId);
return ResponseResult.successData(list);
}
}

View File

@ -1,8 +1,6 @@
package com.yfd.platform.data.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -65,5 +63,6 @@ public class ApprovalChangeLog implements Serializable {
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createdAt;
}

View File

@ -1,8 +1,6 @@
package com.yfd.platform.data.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -55,5 +53,7 @@ public class ApprovalLog implements Serializable {
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createdAt;
}

View File

@ -1,8 +1,6 @@
package com.yfd.platform.data.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -75,10 +73,12 @@ public class ApprovalMain implements Serializable {
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createdAt;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updatedAt;
}

View File

@ -1,13 +1,11 @@
package com.yfd.platform.data.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
@ -124,6 +122,32 @@ public class FishDraftData implements Serializable {
*/
private Date submitTime;
/**
* 水温
*/
@TableField(exist = false)
private BigDecimal wt;
/**
* 电站名称
*/
@TableField(exist = false)
private String engName;
/**
* 基地名称
*/
@TableField(exist = false)
private String baseName;
/**
* 设施名称
*/
@TableField(exist = false)
private String fPname;
/**
* 审批完成时间
*/
@ -147,6 +171,7 @@ public class FishDraftData implements Serializable {
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createdAt;
/**
@ -157,6 +182,7 @@ public class FishDraftData implements Serializable {
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updatedAt;
/**

View File

@ -0,0 +1,109 @@
package com.yfd.platform.data.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 导入任务表ZIP导入全过程管理
* </p>
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("IMPORT_TASK")
public class ImportTask implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(type = IdType.ASSIGN_UUID)
private String id;
/**
* 导入任务编号唯一
*/
private String importNo;
/**
* 业务类型FISH过鱼数据
*/
private String bizType;
/**
* 上传压缩包文件名
*/
private String fileName;
/**
* 文件大小字节
*/
private Long fileSize;
/**
* 原始压缩包存储路径
*/
private String filePath;
/**
* 解压后的临时目录路径
*/
private String tempDir;
/**
* 总数据条数
*/
private Integer totalCount;
/**
* 校验通过条数
*/
private Integer successCount;
/**
* 校验失败条数
*/
private Integer failCount;
/**
* 任务状态UPLOADED已上传 / PARSING解析中 / VALIDATED已校验 / FAILED失败 / CONFIRMED已入库
*/
private String status;
/**
* 错误信息异常时记录
*/
private String errorMsg;
/**
* 上传人ID
*/
private Long uploadUserId;
/**
* 上传时间
*/
private Date uploadTime;
/**
* 过期时间用于清理临时文件
*/
private Date expireTime;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createdAt;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updatedAt;
}

View File

@ -0,0 +1,13 @@
package com.yfd.platform.data.domain.bo;
import com.yfd.platform.data.domain.SysUserDataScope;
import lombok.Data;
import java.util.List;
@Data
public class EditUserDataScopeBo {
private String userId;
List<SysUserDataScope> dataScopeList;
}

View File

@ -0,0 +1,84 @@
package com.yfd.platform.data.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 用户数据权限VO包含关联的资源名称
* </p>
*/
@Data
@Schema(description = "用户数据权限VO")
public class SysUserDataScopeVO implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "主键ID")
private String id;
@Schema(description = "用户ID")
private String userId;
@Schema(description = "资源类型BASIN/BASE/COMPANY/STATION")
private String orgType;
@Schema(description = "资源编码")
private String orgId;
@Schema(description = "资源名称(流域名称/基地名称/公司名称/电站名称)")
private String orgName;
@Schema(description = "上级资源编码")
private String parentId;
@Schema(description = "所属站层级")
private Long orgLevel;
@Schema(description = "所属站全路径")
private String path;
@Schema(description = "权限类型READ/WRITE/ADMIN")
private String permissionType;
@Schema(description = "角色标识")
private String roleCode;
@Schema(description = "数据范围ALL/SELF/CUSTOM")
private String dataScope;
@Schema(description = "状态1有效 0无效")
private Integer status;
@Schema(description = "生效时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date startTime;
@Schema(description = "失效时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date endTime;
@Schema(description = "创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createdAt;
@Schema(description = "创建人")
private String createdBy;
@Schema(description = "更新时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updatedAt;
@Schema(description = "更新人")
private String updatedBy;
@Schema(description = "备注")
private String remark;
@Schema(description = "是否全选0非全选 1全选")
private Integer isAllChildren;
}

View File

@ -0,0 +1,46 @@
package com.yfd.platform.data.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yfd.platform.data.domain.ImportTask;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* <p>
* 导入任务表 Mapper 接口
* </p>
*/
public interface ImportTaskMapper extends BaseMapper<ImportTask> {
/**
* 根据任务编号查询
*/
@Select("SELECT * FROM IMPORT_TASK WHERE IMPORT_NO = #{importNo}")
ImportTask selectByImportNo(@Param("importNo") String importNo);
/**
* 根据业务类型查询
*/
@Select("SELECT * FROM IMPORT_TASK WHERE BIZ_TYPE = #{bizType} ORDER BY CREATED_AT DESC")
List<ImportTask> selectByBizType(@Param("bizType") String bizType);
/**
* 根据状态查询
*/
@Select("SELECT * FROM IMPORT_TASK WHERE STATUS = #{status} ORDER BY CREATED_AT DESC")
List<ImportTask> selectByStatus(@Param("status") String status);
/**
* 根据上传人查询
*/
@Select("SELECT * FROM IMPORT_TASK WHERE UPLOAD_USER_ID = #{uploadUserId} ORDER BY CREATED_AT DESC")
List<ImportTask> selectByUploadUserId(@Param("uploadUserId") Long uploadUserId);
/**
* 查询过期的任务
*/
@Select("SELECT * FROM IMPORT_TASK WHERE EXPIRE_TIME < SYSDATE AND EXPIRE_TIME IS NOT NULL")
List<ImportTask> selectExpiredTasks();
}

View File

@ -0,0 +1,65 @@
package com.yfd.platform.data.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yfd.platform.data.domain.ImportTask;
import java.util.List;
/**
* <p>
* 导入任务表 服务类
* </p>
*/
public interface IImportTaskService extends IService<ImportTask> {
/**
* 分页查询导入任务
*/
Page<ImportTask> queryPageList(Page<ImportTask> page, String bizType, String status, String uploadUserId);
/**
* 根据任务编号查询
*/
ImportTask getByImportNo(String importNo);
/**
* 根据业务类型查询
*/
List<ImportTask> getByBizType(String bizType);
/**
* 根据状态查询
*/
List<ImportTask> getByStatus(String status);
/**
* 创建导入任务
*/
boolean createTask(ImportTask importTask);
/**
* 更新任务状态
*/
boolean updateStatus(String id, String status, String errorMsg);
/**
* 更新解析进度
*/
boolean updateProgress(String id, Integer totalCount, Integer successCount, Integer failCount);
/**
* 标记任务失败
*/
boolean markFailed(String id, String errorMsg);
/**
* 标记任务成功
*/
boolean markSuccess(String id);
/**
* 删除过期任务
*/
boolean deleteExpiredTasks();
}

View File

@ -3,6 +3,8 @@ package com.yfd.platform.data.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yfd.platform.data.domain.SysUserDataScope;
import com.yfd.platform.data.domain.bo.EditUserDataScopeBo;
import com.yfd.platform.data.domain.vo.SysUserDataScopeVO;
import java.util.List;
@ -52,4 +54,19 @@ public interface ISysUserDataScopeService extends IService<SysUserDataScope> {
* 查询用户有效权限状态=1且在有效期内的
*/
List<SysUserDataScope> getValidPermissions(String userId);
boolean batchAddDataScope(EditUserDataScopeBo editUserDataScopeBo);
/**
* 查询用户有效权限包含关联的资源名称- 扩展版本
* 根据 orgType 自动关联查询
* - BASIN: 关联 SD_RVCD_DIC 获取流域名称
* - BASE: 关联 SD_HYDROBASE 获取基地名称
* - COMPANY: 关联 SD_HYCD_DIC 获取公司名称
* - STATION: 关联 SD_ENGINFO_B_H 获取电站名称
*
* @param userId 用户ID
* @return 包含资源名称的权限列表
*/
List<SysUserDataScopeVO> getValidPermissionsWithOrgName(String userId);
}

View File

@ -0,0 +1,140 @@
package com.yfd.platform.data.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.data.domain.ImportTask;
import com.yfd.platform.data.mapper.ImportTaskMapper;
import com.yfd.platform.data.service.IImportTaskService;
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.List;
/**
* <p>
* 导入任务表 服务实现类
* </p>
*/
@Service
public class ImportTaskServiceImpl extends ServiceImpl<ImportTaskMapper, ImportTask> implements IImportTaskService {
@Resource
private ImportTaskMapper importTaskMapper;
@Override
public Page<ImportTask> queryPageList(Page<ImportTask> page, String bizType, String status, String uploadUserId) {
return this.page(page, this.lambdaQuery()
.eq(StringUtils.hasText(bizType), ImportTask::getBizType, bizType)
.eq(StringUtils.hasText(status), ImportTask::getStatus, status)
.eq(uploadUserId != null, ImportTask::getUploadUserId, uploadUserId)
.orderByDesc(ImportTask::getCreatedAt)
.getWrapper());
}
@Override
public ImportTask getByImportNo(String importNo) {
return importTaskMapper.selectByImportNo(importNo);
}
@Override
public List<ImportTask> getByBizType(String bizType) {
return importTaskMapper.selectByBizType(bizType);
}
@Override
public List<ImportTask> getByStatus(String status) {
return importTaskMapper.selectByStatus(status);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean createTask(ImportTask importTask) {
importTask.setStatus("UPLOADED");
importTask.setCreatedAt(new Date());
importTask.setUpdatedAt(new Date());
if (importTask.getTotalCount() == null) {
importTask.setTotalCount(0);
}
if (importTask.getSuccessCount() == null) {
importTask.setSuccessCount(0);
}
if (importTask.getFailCount() == null) {
importTask.setFailCount(0);
}
return this.save(importTask);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean updateStatus(String id, String status, String errorMsg) {
ImportTask importTask = this.getById(id);
if (importTask == null) {
return false;
}
importTask.setStatus(status);
if (StringUtils.hasText(errorMsg)) {
importTask.setErrorMsg(errorMsg);
}
importTask.setUpdatedAt(new Date());
return this.updateById(importTask);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean updateProgress(String id, Integer totalCount, Integer successCount, Integer failCount) {
ImportTask importTask = this.getById(id);
if (importTask == null) {
return false;
}
if (totalCount != null) {
importTask.setTotalCount(totalCount);
}
if (successCount != null) {
importTask.setSuccessCount(successCount);
}
if (failCount != null) {
importTask.setFailCount(failCount);
}
importTask.setUpdatedAt(new Date());
return this.updateById(importTask);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean markFailed(String id, String errorMsg) {
ImportTask importTask = this.getById(id);
if (importTask == null) {
return false;
}
importTask.setStatus("FAILED");
importTask.setErrorMsg(errorMsg);
importTask.setUpdatedAt(new Date());
return this.updateById(importTask);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean markSuccess(String id) {
ImportTask importTask = this.getById(id);
if (importTask == null) {
return false;
}
importTask.setStatus("CONFIRMED");
importTask.setUpdatedAt(new Date());
return this.updateById(importTask);
}
@Override
@Transactional(rollbackFor = Exception.class)
public boolean deleteExpiredTasks() {
List<ImportTask> expiredTasks = importTaskMapper.selectExpiredTasks();
if (expiredTasks == null || expiredTasks.isEmpty()) {
return true;
}
List<String> ids = expiredTasks.stream().map(ImportTask::getId).toList();
return this.removeByIds(ids);
}
}

View File

@ -1,13 +1,29 @@
package com.yfd.platform.data.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
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.domain.bo.EditUserDataScopeBo;
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.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.SdHycdDicMapper;
import com.yfd.platform.env.mapper.SdHydrobaseMapper;
import com.yfd.platform.env.mapper.SdRvcdDicMapper;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
* <p>
@ -16,6 +32,17 @@ import java.util.List;
*/
@Service
public class SysUserDataScopeServiceImpl extends ServiceImpl<SysUserDataScopeMapper, SysUserDataScope> implements ISysUserDataScopeService {
@Resource
private SdRvcdDicMapper rvcdDicMapper;
@Resource
private SdHydrobaseMapper hydrobaseMapper;
@Resource
private SdHycdDicMapper hycdDicMapper;
@Resource
private SdEngInfoBHMapper engInfoBHMapper;
@Override
public Page<SysUserDataScope> queryPageList(Page<SysUserDataScope> page, String userId, String orgType, String orgId, Integer status) {
@ -73,4 +100,174 @@ public class SysUserDataScopeServiceImpl extends ServiceImpl<SysUserDataScopeMap
.orderByDesc(SysUserDataScope::getCreatedAt)
.list();
}
@Override
public List<SysUserDataScopeVO> getValidPermissionsWithOrgName(String userId) {
// 1. 查询用户的有效权限
List<SysUserDataScope> permissions = this.getValidPermissions(userId);
if (CollUtil.isEmpty(permissions)) {
return Collections.emptyList();
}
// 2. orgType 分组
Map<String, List<SysUserDataScope>> groupedByType = permissions.stream()
.collect(Collectors.groupingBy(SysUserDataScope::getOrgType));
// 3. 批量查询各类资源的名称
Map<String, String> orgNameMap = new HashMap<>();
// 3.1 查询流域名称 (BASIN)
if (groupedByType.containsKey("BASIN")) {
Set<String> rvcds = groupedByType.get("BASIN").stream()
.map(SysUserDataScope::getOrgId)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toSet());
if (CollUtil.isNotEmpty(rvcds)) {
List<SdRvcdDic> basins = rvcdDicMapper.selectBatchIds(rvcds);
basins.forEach(basin -> orgNameMap.put(basin.getRvcd(), basin.getRvnm()));
}
}
// 3.2 查询基地名称 (BASE)
if (groupedByType.containsKey("BASE")) {
Set<String> baseIds = groupedByType.get("BASE").stream()
.map(SysUserDataScope::getOrgId)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toSet());
if (CollUtil.isNotEmpty(baseIds)) {
List<SdHydrobase> bases = hydrobaseMapper.selectBatchIds(baseIds);
bases.forEach(base -> orgNameMap.put(base.getBaseid(), base.getBasename()));
}
}
// 3.3 查询公司名称 (COMPANY)
if (groupedByType.containsKey("COMPANY")) {
Set<String> hycds = groupedByType.get("COMPANY").stream()
.map(SysUserDataScope::getOrgId)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toSet());
if (CollUtil.isNotEmpty(hycds)) {
List<SdHycdDic> companies = hycdDicMapper.selectBatchIds(hycds);
companies.forEach(company -> orgNameMap.put(company.getHycd(), company.getHynm()));
}
}
// 3.4 查询电站名称 (STATION)
if (groupedByType.containsKey("STATION")) {
Set<String> stcds = groupedByType.get("STATION").stream()
.map(SysUserDataScope::getOrgId)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toSet());
if (CollUtil.isNotEmpty(stcds)) {
List<SdEngInfoBH> stations = engInfoBHMapper.selectBatchIds(stcds);
stations.forEach(station -> orgNameMap.put(station.getStcd(), station.getEnnm()));
}
}
// 4. 组装 VO 对象
List<SysUserDataScopeVO> voList = new ArrayList<>();
for (SysUserDataScope permission : permissions) {
SysUserDataScopeVO vo = new SysUserDataScopeVO();
BeanUtils.copyProperties(permission, vo);
// 设置资源名称
String orgName = orgNameMap.get(permission.getOrgId());
vo.setOrgName(StrUtil.blankToDefault(orgName, "未知"));
voList.add(vo);
}
return voList;
}
@Override
public boolean batchAddDataScope(EditUserDataScopeBo editUserDataScopeBo) {
List<SysUserDataScope> dataScopeList = editUserDataScopeBo.getDataScopeList();
if (CollUtil.isEmpty(dataScopeList)) {
String userId = editUserDataScopeBo.getUserId();
// 删除旧数据
this.remove(new LambdaQueryWrapper<SysUserDataScope>().eq(SysUserDataScope::getUserId, userId));
return true;
}
// 1. 去重基于 userId + orgType + orgId 去除传入列表中的重复数据
List<SysUserDataScope> uniqueList = dataScopeList.stream()
.collect(Collectors.toMap(
scope -> buildUniqueKey(scope.getUserId(), scope.getOrgType(), scope.getOrgId()),
scope -> scope,
(existing, replacement) -> replacement // 如果有重复保留后者
))
.values()
.stream()
.collect(Collectors.toList());
// 2. 提取所有需要处理的唯一键
Set<String> targetKeys = uniqueList.stream()
.map(scope -> buildUniqueKey(scope.getUserId(), scope.getOrgType(), scope.getOrgId()))
.collect(Collectors.toSet());
// 3. 查询数据库中已存在的记录
List<SysUserDataScope> existingRecords = this.lambdaQuery()
.in(SysUserDataScope::getUserId,
uniqueList.stream().map(SysUserDataScope::getUserId).collect(Collectors.toSet()))
.list();
// 4. 找出需要删除的记录数据库中存在但新列表中不存在的
Set<String> existingKeys = existingRecords.stream()
.map(record -> buildUniqueKey(record.getUserId(), record.getOrgType(), record.getOrgId()))
.collect(Collectors.toSet());
List<String> idsToDelete = existingRecords.stream()
.filter(record -> !targetKeys.contains(
buildUniqueKey(record.getUserId(), record.getOrgType(), record.getOrgId())
))
.map(SysUserDataScope::getId)
.collect(Collectors.toList());
// 5. 找出需要更新的记录数据库和新列表中都存在的
List<SysUserDataScope> toUpdate = uniqueList.stream()
.filter(scope -> existingKeys.contains(
buildUniqueKey(scope.getUserId(), scope.getOrgType(), scope.getOrgId())
))
.peek(scope -> {
// 设置已存在记录的ID
existingRecords.stream()
.filter(existing -> buildUniqueKey(existing.getUserId(), existing.getOrgType(), existing.getOrgId())
.equals(buildUniqueKey(scope.getUserId(), scope.getOrgType(), scope.getOrgId())))
.findFirst()
.ifPresent(existing -> scope.setId(existing.getId()));
})
.collect(Collectors.toList());
// 6. 找出需要新增的记录数据库中不存在的
List<SysUserDataScope> toInsert = uniqueList.stream()
.filter(scope -> !existingKeys.contains(
buildUniqueKey(scope.getUserId(), scope.getOrgType(), scope.getOrgId())
))
.collect(Collectors.toList());
// 7. 执行删除操作
if (CollUtil.isNotEmpty(idsToDelete)) {
this.removeByIds(idsToDelete);
}
// 8. 执行批量新增和更新
boolean insertResult = CollUtil.isEmpty(toInsert) || this.saveBatch(toInsert);
boolean updateResult = CollUtil.isEmpty(toUpdate) || this.updateBatchById(toUpdate);
return insertResult && updateResult;
}
/**
* 构建唯一键userId + orgType + orgId
*/
private String buildUniqueKey(String userId, String orgType, String orgId) {
return String.format("%s_%s_%s",
StrUtil.blankToDefault(userId, ""),
StrUtil.blankToDefault(orgType, ""),
StrUtil.blankToDefault(orgId, ""));
}
}

View File

@ -10,6 +10,8 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import jakarta.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -26,20 +28,45 @@ public class TreeStructureController {
@Resource
private ITreeStructureService treeStructureService;
@GetMapping("/rvcdEng")
@Operation(summary = "获取流域-电站树形结构")
public ResponseResult getRvcdEngTree(
@RequestParam(required = false) String rvcd,
@RequestParam(required = false) String engName) {
List<Map<String, Object>> result = treeStructureService.getRvcdEngTree(rvcd, engName);
return ResponseResult.successData(result);
}
@GetMapping("/rvcdBaseEng")
@Operation(summary = "获取流域-基地-电站树形结构")
public ResponseResult getRvcdBaseEngTree(@RequestParam(required = false) String rvcd) {
List<Map<String, Object>> result = treeStructureService.getRvcdBaseEngTree(rvcd);
public ResponseResult getRvcdBaseEngTree(@RequestParam(required = false) String rvcd, @RequestParam(required = false) String engName) {
List<Map<String, Object>> result = treeStructureService.getRvcdBaseEngTree(rvcd, engName);
return ResponseResult.successData(result);
}
@GetMapping("/rvcdCompanyEng")
@Operation(summary = "获取流域-公司-电站树形结构")
public ResponseResult getRvcdCompanyEngTree(@RequestParam(required = false) String rvcd) {
List<Map<String, Object>> result = treeStructureService.getRvcdCompanyEngTree(rvcd);
public ResponseResult getRvcdCompanyEngTree(
@RequestParam(required = false) String rvcd,
@RequestParam(required = false) String engName) {
List<Map<String, Object>> result = treeStructureService.getRvcdCompanyEngTree(rvcd, engName);
return ResponseResult.successData(result);
}
@GetMapping("/getRvcdBaseOrCompanyEngTree")
@Operation(summary = "获取流域-基地-电站树形结构")
public ResponseResult getRvcdBaseOrCompanyEngTree(@RequestParam(required = false) String rvcd, @RequestParam(required = false) String engName, @RequestParam(required = false) String type) {
if ("1".equals(type)) {
List<Map<String, Object>> result = treeStructureService.getRvcdBaseEngTree(rvcd, engName);
return ResponseResult.successData(result);
} else if ("2".equals(type)) {
List<Map<String, Object>> rvcdCompanyEngTree = treeStructureService.getRvcdCompanyEngTree(rvcd, engName);
return ResponseResult.successData(rvcdCompanyEngTree);
}
return ResponseResult.successData(new ArrayList<>());
}
@GetMapping("/rvcd")
@Operation(summary = "获取流域树")
public ResponseResult getRvcdTree(@RequestParam(required = false) String prvcd) {

View File

@ -16,13 +16,13 @@ public interface ITreeStructureService {
* 获取流域-基地-电站树形结构
* @param rvcd 流域编码可选为空则返回全部
*/
List<Map<String, Object>> getRvcdBaseEngTree(String rvcd);
List<Map<String, Object>> getRvcdBaseEngTree(String rvcd, String engName);
/**
* 获取流域-公司-电站树形结构
* @param rvcd 流域编码可选为空则返回全部
*/
List<Map<String, Object>> getRvcdCompanyEngTree(String rvcd);
List<Map<String, Object>> getRvcdCompanyEngTree(String rvcd, String engName);
/**
* 获取流域树带子节点标记
@ -38,4 +38,11 @@ public interface ITreeStructureService {
* 获取公司树带子节点标记
*/
List<Map<String, Object>> getHycdTree(String phycd);
/**
* 获取流域-电站树形结构二级树
* @param rvcd 流域编码可选为空则返回全部
* @param engName 电站名称可选用于模糊筛选电站
*/
List<Map<String, Object>> getRvcdEngTree(String rvcd, String engName);
}

View File

@ -42,7 +42,7 @@ public class TreeStructureServiceImpl implements ITreeStructureService {
private SdPrhyrltnBMapper prhyrltnBMapper;
@Override
public List<Map<String, Object>> getRvcdBaseEngTree(String rvcd) {
public List<Map<String, Object>> getRvcdBaseEngTree(String rvcd, String engName) {
List<Map<String, Object>> result = new ArrayList<>();
List<SdRvcdDic> rvcdList;
@ -60,16 +60,26 @@ public class TreeStructureServiceImpl implements ITreeStructureService {
Map<String, List<SdEngInfoBH>> rvcdEngMap = new HashMap<>();
for (SdRvcdDic rvcdDic : rvcdList) {
List<SdEngInfoBH> engList = engInfoBHMapper.selectByRvcd(rvcdDic.getRvcd());
// 如果提供了电站名称参数进行模糊匹配筛选
if (StringUtils.hasText(engName) && engList != null) {
engList = engList.stream()
.filter(eng -> eng.getEnnm() != null && eng.getEnnm().contains(engName))
.collect(Collectors.toList());
}
if (engList != null && !engList.isEmpty()) {
rvcdEngMap.put(rvcdDic.getRvcd(), engList);
}
}
for (SdRvcdDic rvcdDic : rvcdList) {
Map<String, Object> rvcdNode = new LinkedHashMap<>();
rvcdNode.put("type", "BASIN");
rvcdNode.put("code", rvcdDic.getRvcd());
rvcdNode.put("name", rvcdDic.getRvnm());
rvcdNode.put("path", rvcdDic.getPath());
rvcdNode.put("orgLevel", 0);
rvcdNode.put("grd", rvcdDic.getGrd());
rvcdNode.put("lgtd", rvcdDic.getLgtd());
rvcdNode.put("lttd", rvcdDic.getLttd());
@ -102,6 +112,8 @@ public class TreeStructureServiceImpl implements ITreeStructureService {
baseNode.put("shortname", base.getShortname());
baseNode.put("grd", base.getGrd());
baseNode.put("parentId", rvcdDic.getRvcd());
baseNode.put("orgLevel", 1);
List<Map<String, Object>> engChildren = new ArrayList<>();
for (SdEngInfoBH eng : baseEngList) {
Map<String, Object> engNode = new LinkedHashMap<>();
@ -115,71 +127,140 @@ public class TreeStructureServiceImpl implements ITreeStructureService {
engNode.put("bldstt", eng.getBldstt());
engNode.put("engtp", eng.getEngtp());
engNode.put("parentId", base.getBaseid());
engNode.put("orgLevel", 2);
engChildren.add(engNode);
}
baseNode.put("children", engChildren);
baseChildren.add(baseNode);
// 只有当该基地下有电站时才添加该基地节点
if (!engChildren.isEmpty()) {
baseNode.put("children", engChildren);
baseChildren.add(baseNode);
}
}
}
rvcdNode.put("children", baseChildren);
result.add(rvcdNode);
// 只有当该流域下有基地进而有电站时才添加该流域节点
if (!baseChildren.isEmpty()) {
rvcdNode.put("children", baseChildren);
result.add(rvcdNode);
}
}
return result;
}
@Override
public List<Map<String, Object>> getRvcdCompanyEngTree(String rvcd) {
public List<Map<String, Object>> getRvcdCompanyEngTree(String rvcd, String engName) {
List<Map<String, Object>> result = new ArrayList<>();
// 1. 查询流域列表
List<SdRvcdDic> rvcdList;
if (StringUtils.hasText(rvcd)) {
rvcdList = rvcdDicMapper.selectByPrvcd(rvcd);
SdRvcdDic singleRvcd = rvcdDicMapper.selectById(rvcd);
if (singleRvcd != null && !rvcdList.contains(singleRvcd)) {
rvcdList = new ArrayList<>();
rvcdList.add(singleRvcd);
}
} else {
rvcdList = rvcdDicMapper.selectRootList();
}
// 2. 预加载所有流域下的电站按流域分组
Map<String, List<SdEngInfoBH>> rvcdEngMap = new HashMap<>();
for (SdRvcdDic rvcdDic : rvcdList) {
List<SdEngInfoBH> engList = engInfoBHMapper.selectByRvcd(rvcdDic.getRvcd());
// 如果提供了电站名称参数进行模糊匹配筛选
if (StringUtils.hasText(engName) && engList != null) {
engList = engList.stream()
.filter(eng -> eng.getEnnm() != null && eng.getEnnm().contains(engName))
.collect(Collectors.toList());
}
if (engList != null && !engList.isEmpty()) {
rvcdEngMap.put(rvcdDic.getRvcd(), engList);
}
}
// 3. 构建树形结构
for (SdRvcdDic rvcdDic : rvcdList) {
Map<String, Object> rvcdNode = new LinkedHashMap<>();
rvcdNode.put("type", "RVCD");
rvcdNode.put("type", "BASIN");
rvcdNode.put("code", rvcdDic.getRvcd());
rvcdNode.put("name", rvcdDic.getRvnm());
rvcdNode.put("path", rvcdDic.getPath());
rvcdNode.put("orgLevel", 0);
rvcdNode.put("grd", rvcdDic.getGrd());
rvcdNode.put("lgtd", rvcdDic.getLgtd());
rvcdNode.put("lttd", rvcdDic.getLttd());
rvcdNode.put("parentId", "0");
List<SdHycdDic> companyList = hycdDicMapper.selectRootList();
List<Map<String, Object>> companyChildren = new ArrayList<>();
for (SdHycdDic company : companyList) {
Map<String, Object> companyNode = new LinkedHashMap<>();
companyNode.put("type", "COMPANY");
companyNode.put("code", company.getHycd());
companyNode.put("name", company.getHynm());
companyNode.put("shortname", company.getShortname());
// 获取该流域下的所有电站
List<SdEngInfoBH> engList = rvcdEngMap.get(rvcdDic.getRvcd());
if (engList != null && !engList.isEmpty()) {
// 按公司编码分组直接使用电站表中的 HYCD 字段
Map<String, List<SdEngInfoBH>> companyEngMap = engList.stream()
.filter(eng -> StringUtils.hasText(eng.getHycd()))
.collect(Collectors.groupingBy(SdEngInfoBH::getHycd));
List<String> stcdList = prhyrltnBMapper.selectStcdListByHycd(company.getHycd());
List<Map<String, Object>> engChildren = new ArrayList<>();
// 遍历每个公司构建公司节点
for (Map.Entry<String, List<SdEngInfoBH>> entry : companyEngMap.entrySet()) {
String hycd = entry.getKey();
List<SdEngInfoBH> companyEngList = entry.getValue();
for (String stcd : stcdList) {
SdEngInfoBH eng = engInfoBHMapper.selectById(stcd);
if (eng != null) {
// 查询公司信息
SdHycdDic company = hycdDicMapper.selectById(hycd);
if (company == null) {
company = new SdHycdDic();
company.setHycd(hycd);
company.setHynm("未知公司");
company.setShortname("未知");
}
Map<String, Object> companyNode = new LinkedHashMap<>();
companyNode.put("type", "COMPANY");
companyNode.put("code", company.getHycd());
companyNode.put("name", company.getHynm());
companyNode.put("shortname", company.getShortname());
companyNode.put("grd", company.getGrd());
companyNode.put("parentId", rvcdDic.getRvcd());
companyNode.put("orgLevel", 1);
// 构建电站子节点
List<Map<String, Object>> engChildren = new ArrayList<>();
for (SdEngInfoBH eng : companyEngList) {
Map<String, Object> engNode = new LinkedHashMap<>();
engNode.put("type", "ENG");
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", company.getHycd());
engNode.put("orgLevel", 2);
engChildren.add(engNode);
}
}
companyNode.put("children", engChildren);
companyChildren.add(companyNode);
// 只有当该公司下有电站时才添加该公司节点
if (!engChildren.isEmpty()) {
companyNode.put("children", engChildren);
companyChildren.add(companyNode);
}
}
}
rvcdNode.put("children", companyChildren);
result.add(rvcdNode);
// 只有当该流域下有公司进而有电站时才添加该流域节点
if (!companyChildren.isEmpty()) {
rvcdNode.put("children", companyChildren);
result.add(rvcdNode);
}
}
return result;
@ -265,4 +346,85 @@ public class TreeStructureServiceImpl implements ITreeStructureService {
return result;
}
@Override
public List<Map<String, Object>> getRvcdEngTree(String rvcd, String engName) {
List<Map<String, Object>> result = new ArrayList<>();
// 1. 查询流域列表
List<SdRvcdDic> rvcdList;
if (StringUtils.hasText(rvcd)) {
rvcdList = rvcdDicMapper.selectByPrvcd(rvcd);
SdRvcdDic singleRvcd = rvcdDicMapper.selectById(rvcd);
if (singleRvcd != null && !rvcdList.contains(singleRvcd)) {
rvcdList = new ArrayList<>();
rvcdList.add(singleRvcd);
}
} else {
rvcdList = rvcdDicMapper.selectRootList();
}
// 2. 预加载所有流域下的电站按流域分组
Map<String, List<SdEngInfoBH>> rvcdEngMap = new HashMap<>();
for (SdRvcdDic rvcdDic : rvcdList) {
List<SdEngInfoBH> engList = engInfoBHMapper.selectByRvcd(rvcdDic.getRvcd());
// 如果提供了电站名称参数进行模糊匹配筛选
if (StringUtils.hasText(engName) && engList != null) {
engList = engList.stream()
.filter(eng -> eng.getEnnm() != null && eng.getEnnm().contains(engName))
.collect(Collectors.toList());
}
if (engList != null && !engList.isEmpty()) {
rvcdEngMap.put(rvcdDic.getRvcd(), engList);
}
}
// 3. 构建二级树形结构流域 -> 电站
for (SdRvcdDic rvcdDic : rvcdList) {
Map<String, Object> rvcdNode = new LinkedHashMap<>();
rvcdNode.put("type", "BASIN");
rvcdNode.put("code", rvcdDic.getRvcd());
rvcdNode.put("name", rvcdDic.getRvnm());
rvcdNode.put("path", rvcdDic.getPath());
rvcdNode.put("orgLevel", 0);
rvcdNode.put("grd", rvcdDic.getGrd());
rvcdNode.put("lgtd", rvcdDic.getLgtd());
rvcdNode.put("lttd", rvcdDic.getLttd());
rvcdNode.put("parentId", "0");
// 获取该流域下的所有电站
List<SdEngInfoBH> engList = rvcdEngMap.get(rvcdDic.getRvcd());
List<Map<String, Object>> engChildren = new ArrayList<>();
if (engList != null && !engList.isEmpty()) {
for (SdEngInfoBH eng : engList) {
Map<String, Object> 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", rvcdDic.getRvcd());
engNode.put("orgLevel", 1);
engChildren.add(engNode);
}
}
// 只有当该流域下有电站时才添加该流域节点
if (!engChildren.isEmpty()) {
rvcdNode.put("children", engChildren);
result.add(rvcdNode);
}
}
return result;
}
}