diff --git a/backend/src/main/java/com/yfd/platform/data/controller/SysUserDataScopeController.java b/backend/src/main/java/com/yfd/platform/data/controller/SysUserDataScopeController.java index e895035..6858f42 100644 --- a/backend/src/main/java/com/yfd/platform/data/controller/SysUserDataScopeController.java +++ b/backend/src/main/java/com/yfd/platform/data/controller/SysUserDataScopeController.java @@ -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; @@ -55,8 +57,8 @@ public class SysUserDataScopeController { @PostMapping("/batchAdd") @Operation(summary = "新增数据填报权限") - public ResponseResult batchAdd(@RequestBody List dataScopeList) { - boolean result = dataScopeService.batchAddDataScope(dataScopeList); + public ResponseResult batchAdd(@RequestBody EditUserDataScopeBo editUserDataScopeBo) { + boolean result = dataScopeService.batchAddDataScope(editUserDataScopeBo); return result ? ResponseResult.success("新增成功") : ResponseResult.error("新增失败"); } @@ -125,7 +127,7 @@ public class SysUserDataScopeController { @GetMapping("/getValidPermissions") @Operation(summary = "查询用户有效权限") public ResponseResult getValidPermissions(@RequestParam String userId) { - List list = dataScopeService.getValidPermissions(userId); + List list = dataScopeService.getValidPermissionsWithOrgName(userId); return ResponseResult.successData(list); } } diff --git a/backend/src/main/java/com/yfd/platform/data/domain/bo/EditUserDataScopeBo.java b/backend/src/main/java/com/yfd/platform/data/domain/bo/EditUserDataScopeBo.java new file mode 100644 index 0000000..db27b4f --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/data/domain/bo/EditUserDataScopeBo.java @@ -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 dataScopeList; +} 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 new file mode 100644 index 0000000..b630477 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/data/domain/vo/SysUserDataScopeVO.java @@ -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; + +/** + *

+ * 用户数据权限VO(包含关联的资源名称) + *

+ */ +@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; +} diff --git a/backend/src/main/java/com/yfd/platform/data/service/ISysUserDataScopeService.java b/backend/src/main/java/com/yfd/platform/data/service/ISysUserDataScopeService.java index fb642d4..a4f75d3 100644 --- a/backend/src/main/java/com/yfd/platform/data/service/ISysUserDataScopeService.java +++ b/backend/src/main/java/com/yfd/platform/data/service/ISysUserDataScopeService.java @@ -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; @@ -53,5 +55,18 @@ public interface ISysUserDataScopeService extends IService { */ List getValidPermissions(String userId); - boolean batchAddDataScope(List dataScopeList); + 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 getValidPermissionsWithOrgName(String userId); } 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 fa771d2..7492688 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 @@ -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; /** *

@@ -16,6 +32,17 @@ import java.util.List; */ @Service public class SysUserDataScopeServiceImpl extends ServiceImpl implements ISysUserDataScopeService { + @Resource + private SdRvcdDicMapper rvcdDicMapper; + + @Resource + private SdHydrobaseMapper hydrobaseMapper; + + @Resource + private SdHycdDicMapper hycdDicMapper; + + @Resource + private SdEngInfoBHMapper engInfoBHMapper; @Override public Page queryPageList(Page page, String userId, String orgType, String orgId, Integer status) { @@ -75,7 +102,172 @@ public class SysUserDataScopeServiceImpl extends ServiceImpl dataScopeList) { - return this.saveOrUpdateBatch(dataScopeList); + public List getValidPermissionsWithOrgName(String userId) { + // 1. 查询用户的有效权限 + List permissions = this.getValidPermissions(userId); + + if (CollUtil.isEmpty(permissions)) { + return Collections.emptyList(); + } + + // 2. 按 orgType 分组 + Map> groupedByType = permissions.stream() + .collect(Collectors.groupingBy(SysUserDataScope::getOrgType)); + + // 3. 批量查询各类资源的名称 + Map orgNameMap = new HashMap<>(); + + // 3.1 查询流域名称 (BASIN) + if (groupedByType.containsKey("BASIN")) { + Set rvcds = groupedByType.get("BASIN").stream() + .map(SysUserDataScope::getOrgId) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toSet()); + + if (CollUtil.isNotEmpty(rvcds)) { + List basins = rvcdDicMapper.selectBatchIds(rvcds); + basins.forEach(basin -> orgNameMap.put(basin.getRvcd(), basin.getRvnm())); + } + } + + // 3.2 查询基地名称 (BASE) + if (groupedByType.containsKey("BASE")) { + Set baseIds = groupedByType.get("BASE").stream() + .map(SysUserDataScope::getOrgId) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toSet()); + + if (CollUtil.isNotEmpty(baseIds)) { + List bases = hydrobaseMapper.selectBatchIds(baseIds); + bases.forEach(base -> orgNameMap.put(base.getBaseid(), base.getBasename())); + } + } + + // 3.3 查询公司名称 (COMPANY) + if (groupedByType.containsKey("COMPANY")) { + Set hycds = groupedByType.get("COMPANY").stream() + .map(SysUserDataScope::getOrgId) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toSet()); + + if (CollUtil.isNotEmpty(hycds)) { + List companies = hycdDicMapper.selectBatchIds(hycds); + companies.forEach(company -> orgNameMap.put(company.getHycd(), company.getHynm())); + } + } + + // 3.4 查询电站名称 (STATION) + if (groupedByType.containsKey("STATION")) { + Set stcds = groupedByType.get("STATION").stream() + .map(SysUserDataScope::getOrgId) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toSet()); + + if (CollUtil.isNotEmpty(stcds)) { + List stations = engInfoBHMapper.selectBatchIds(stcds); + stations.forEach(station -> orgNameMap.put(station.getStcd(), station.getEnnm())); + } + } + + // 4. 组装 VO 对象 + List 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 dataScopeList = editUserDataScopeBo.getDataScopeList(); + if (CollUtil.isEmpty(dataScopeList)) { + String userId = editUserDataScopeBo.getUserId(); + // 删除旧数据 + this.remove(new LambdaQueryWrapper().eq(SysUserDataScope::getUserId, userId)); + return true; + } + // 1. 去重:基于 userId + orgType + orgId 去除传入列表中的重复数据 + List 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 targetKeys = uniqueList.stream() + .map(scope -> buildUniqueKey(scope.getUserId(), scope.getOrgType(), scope.getOrgId())) + .collect(Collectors.toSet()); + + // 3. 查询数据库中已存在的记录 + List existingRecords = this.lambdaQuery() + .in(SysUserDataScope::getUserId, + uniqueList.stream().map(SysUserDataScope::getUserId).collect(Collectors.toSet())) + .list(); + + // 4. 找出需要删除的记录(数据库中存在但新列表中不存在的) + Set existingKeys = existingRecords.stream() + .map(record -> buildUniqueKey(record.getUserId(), record.getOrgType(), record.getOrgId())) + .collect(Collectors.toSet()); + + List idsToDelete = existingRecords.stream() + .filter(record -> !targetKeys.contains( + buildUniqueKey(record.getUserId(), record.getOrgType(), record.getOrgId()) + )) + .map(SysUserDataScope::getId) + .collect(Collectors.toList()); + + // 5. 找出需要更新的记录(数据库和新列表中都存在的) + List 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 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, "")); } } 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 4286e1d..c3ab36e 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 @@ -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; @@ -28,18 +30,33 @@ public class TreeStructureController { @GetMapping("/rvcdBaseEng") @Operation(summary = "获取流域-基地-电站树形结构") - public ResponseResult getRvcdBaseEngTree(@RequestParam(required = false) String rvcd) { - List> result = treeStructureService.getRvcdBaseEngTree(rvcd); + public ResponseResult getRvcdBaseEngTree(@RequestParam(required = false) String rvcd, @RequestParam(required = false) String engName) { + List> result = treeStructureService.getRvcdBaseEngTree(rvcd, engName); return ResponseResult.successData(result); } @GetMapping("/rvcdCompanyEng") @Operation(summary = "获取流域-公司-电站树形结构") - public ResponseResult getRvcdCompanyEngTree(@RequestParam(required = false) String rvcd) { - List> result = treeStructureService.getRvcdCompanyEngTree(rvcd); + public ResponseResult getRvcdCompanyEngTree( + @RequestParam(required = false) String rvcd, + @RequestParam(required = false) String engName) { + List> 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> result = treeStructureService.getRvcdBaseEngTree(rvcd, engName); + return ResponseResult.successData(result); + } else if ("2".equals(type)) { + List> 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) { 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 8d669d1..918c854 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 @@ -16,13 +16,13 @@ public interface ITreeStructureService { * 获取流域-基地-电站树形结构 * @param rvcd 流域编码(可选,为空则返回全部) */ - List> getRvcdBaseEngTree(String rvcd); + List> getRvcdBaseEngTree(String rvcd, String engName); /** * 获取流域-公司-电站树形结构 * @param rvcd 流域编码(可选,为空则返回全部) */ - List> getRvcdCompanyEngTree(String rvcd); + List> getRvcdCompanyEngTree(String rvcd, String engName); /** * 获取流域树(带子节点标记) 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 4b62087..f8502ca 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 @@ -42,7 +42,7 @@ public class TreeStructureServiceImpl implements ITreeStructureService { private SdPrhyrltnBMapper prhyrltnBMapper; @Override - public List> getRvcdBaseEngTree(String rvcd) { + public List> getRvcdBaseEngTree(String rvcd, String engName) { List> result = new ArrayList<>(); List rvcdList; @@ -60,10 +60,19 @@ public class TreeStructureServiceImpl implements ITreeStructureService { Map> rvcdEngMap = new HashMap<>(); for (SdRvcdDic rvcdDic : rvcdList) { List 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 rvcdNode = new LinkedHashMap<>(); rvcdNode.put("type", "BASIN"); @@ -104,6 +113,7 @@ public class TreeStructureServiceImpl implements ITreeStructureService { baseNode.put("grd", base.getGrd()); baseNode.put("parentId", rvcdDic.getRvcd()); baseNode.put("orgLevel", 1); + List> engChildren = new ArrayList<>(); for (SdEngInfoBH eng : baseEngList) { Map engNode = new LinkedHashMap<>(); @@ -120,69 +130,137 @@ public class TreeStructureServiceImpl implements ITreeStructureService { 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> getRvcdCompanyEngTree(String rvcd) { + public List> getRvcdCompanyEngTree(String rvcd, String engName) { List> result = new ArrayList<>(); + // 1. 查询流域列表 List 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> rvcdEngMap = new HashMap<>(); + for (SdRvcdDic rvcdDic : rvcdList) { + List 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 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 companyList = hycdDicMapper.selectRootList(); List> companyChildren = new ArrayList<>(); - for (SdHycdDic company : companyList) { - Map companyNode = new LinkedHashMap<>(); - companyNode.put("type", "COMPANY"); - companyNode.put("code", company.getHycd()); - companyNode.put("name", company.getHynm()); - companyNode.put("shortname", company.getShortname()); + // 获取该流域下的所有电站 + List engList = rvcdEngMap.get(rvcdDic.getRvcd()); + if (engList != null && !engList.isEmpty()) { + // 按公司编码分组(直接使用电站表中的 HYCD 字段) + Map> companyEngMap = engList.stream() + .filter(eng -> StringUtils.hasText(eng.getHycd())) + .collect(Collectors.groupingBy(SdEngInfoBH::getHycd)); - List stcdList = prhyrltnBMapper.selectStcdListByHycd(company.getHycd()); - List> engChildren = new ArrayList<>(); + // 遍历每个公司,构建公司节点 + for (Map.Entry> entry : companyEngMap.entrySet()) { + String hycd = entry.getKey(); + List 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 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> engChildren = new ArrayList<>(); + for (SdEngInfoBH eng : companyEngList) { Map 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;