diff --git a/urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/controller/app/appmodule/AppAppModuleController.java b/urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/controller/app/appmodule/AppAppModuleController.java index fb0332b..4503f3c 100644 --- a/urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/controller/app/appmodule/AppAppModuleController.java +++ b/urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/controller/app/appmodule/AppAppModuleController.java @@ -15,8 +15,12 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import static com.zteits.urbanops.framework.common.pojo.CommonResult.success; @@ -47,13 +51,56 @@ public class AppAppModuleController { // 填充统计数据(根据extra中的statisticKey配置) // appModuleService.fillModuleStatistics(list, userId); - // 排序并转换 - list.sort(Comparator.comparing(AppModuleDO::getSort)); - List result = AppModuleConvert.INSTANCE.convertAppList(list); + // 转换为 VO 列表并构建树 + List modules = AppModuleConvert.INSTANCE.convertAppList(list); + List moduleTree = buildModuleTree(modules); // MapStruct 转换已通过 @AfterMapping 自动填充 statisticCount - return success(result); + return success(moduleTree); + } + + private List buildModuleTree(List modules) { + if (modules == null || modules.isEmpty()) { + return Collections.emptyList(); + } + + Map moduleMap = new LinkedHashMap<>(modules.size()); + for (AppModuleVO module : modules) { + module.setChildren(new ArrayList<>()); + moduleMap.put(module.getId(), module); + } + + List roots = new ArrayList<>(); + for (AppModuleVO module : modules) { + Long parentId = module.getParentId(); + if (parentId == null || AppModuleDO.ID_ROOT.equals(parentId)) { + roots.add(module); + continue; + } + + AppModuleVO parent = moduleMap.get(parentId); + if (parent == null) { + roots.add(module); + continue; + } + parent.getChildren().add(module); + } + + sortModules(roots); + return roots; + } + + private void sortModules(List modules) { + if (modules == null || modules.isEmpty()) { + return; + } + + modules.sort(Comparator.comparing(AppModuleVO::getSort, + Comparator.nullsLast(Integer::compareTo))); + for (AppModuleVO module : modules) { + sortModules(module.getChildren()); + } } } diff --git a/urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/controller/app/appmodule/vo/AppModuleVO.java b/urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/controller/app/appmodule/vo/AppModuleVO.java index 1db8357..46d3b86 100644 --- a/urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/controller/app/appmodule/vo/AppModuleVO.java +++ b/urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/controller/app/appmodule/vo/AppModuleVO.java @@ -3,6 +3,7 @@ package com.zteits.urbanops.module.system.controller.app.appmodule.vo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import java.util.List; import java.util.Map; @Schema(description = "用户 APP - App 功能模块 Response VO") @@ -51,4 +52,7 @@ public class AppModuleVO { @Schema(description = "扩展字段 JSON", example = "{}") private Map extra; + @Schema(description = "子模块集合") + private List children; + } diff --git a/urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/service/appmodule/AppModuleServiceImpl.java b/urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/service/appmodule/AppModuleServiceImpl.java index 86772ab..6405df3 100644 --- a/urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/service/appmodule/AppModuleServiceImpl.java +++ b/urbanops-module-system/src/main/java/com/zteits/urbanops/module/system/service/appmodule/AppModuleServiceImpl.java @@ -143,6 +143,7 @@ public class AppModuleServiceImpl implements AppModuleService { // 查询所有启用的模块 reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); List modules = getAppModuleList(reqVO); + modules = includeParentModules(modules); // 过滤掉关闭的节点 modules = filterDisableModules(modules); @@ -159,6 +160,46 @@ public class AppModuleServiceImpl implements AppModuleService { return modules; } + private List includeParentModules(List modules) { + if (CollUtil.isEmpty(modules)) { + return modules; + } + + Map moduleMap = new LinkedHashMap<>(); + for (AppModuleDO module : modules) { + moduleMap.put(module.getId(), module); + } + + Set pendingParentIds = new HashSet<>(); + for (AppModuleDO module : modules) { + Long parentId = module.getParentId(); + if (parentId == null || ObjUtil.equal(parentId, ID_ROOT) || moduleMap.containsKey(parentId)) { + continue; + } + pendingParentIds.add(parentId); + } + + while (CollUtil.isNotEmpty(pendingParentIds)) { + List parents = appModuleMapper.selectByIds(pendingParentIds); + pendingParentIds = new HashSet<>(); + for (AppModuleDO parent : parents) { + if (parent == null) { + continue; + } + if (!moduleMap.containsKey(parent.getId())) { + moduleMap.put(parent.getId(), parent); + } + Long ancestorId = parent.getParentId(); + if (ancestorId != null && !ObjUtil.equal(ancestorId, ID_ROOT) + && !moduleMap.containsKey(ancestorId)) { + pendingParentIds.add(ancestorId); + } + } + } + + return new ArrayList<>(moduleMap.values()); + } + @Override public List filterDisableModules(List moduleList) { if (CollUtil.isEmpty(moduleList)) {