diff --git a/kernel-s-system/system-business-permission/pom.xml b/kernel-s-system/system-business-permission/pom.xml index d7d918cfa..22ee4a8f4 100644 --- a/kernel-s-system/system-business-permission/pom.xml +++ b/kernel-s-system/system-business-permission/pom.xml @@ -17,6 +17,13 @@ + + + com.javaguns.roses + kernel-d-tree + ${roses.version} + + com.javaguns.roses diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/SysMenuService.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/SysMenuService.java index 71a9269da..517138868 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/SysMenuService.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/SysMenuService.java @@ -134,4 +134,14 @@ public interface SysMenuService extends IService, SysMenuServiceApi { */ Map getMenuIdParentIdMap(); + /** + * 将指定的菜单补全父级菜单 + *

+ * 一般用在参数是叶子节点的情况下,向上补全,为了方便展示菜单树 + * + * @author fengshuonan + * @since 2024/10/30 20:57 + */ + List completeParentMenu(List menuList); + } \ No newline at end of file diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/impl/SysMenuServiceImpl.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/impl/SysMenuServiceImpl.java index 1518517ac..1caf7ad23 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/impl/SysMenuServiceImpl.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/menu/service/impl/SysMenuServiceImpl.java @@ -10,6 +10,7 @@ import cn.stylefeng.roses.kernel.event.sdk.publish.BusinessEventPublisher; import cn.stylefeng.roses.kernel.rule.constants.SymbolConstant; import cn.stylefeng.roses.kernel.rule.constants.TreeConstants; import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException; +import cn.stylefeng.roses.kernel.rule.pidset.ParentIdParseUtil; import cn.stylefeng.roses.kernel.rule.tree.buildpids.PidStructureBuildUtil; import cn.stylefeng.roses.kernel.sys.api.callback.RemoveMenuCallbackApi; import cn.stylefeng.roses.kernel.sys.api.constants.SysConstants; @@ -159,7 +160,7 @@ public class SysMenuServiceImpl extends ServiceImpl impl @Override public List getTotalMenus(Set limitMenuIds) { LambdaQueryWrapper menuLambdaQueryWrapper = new LambdaQueryWrapper<>(); - menuLambdaQueryWrapper.select(SysMenu::getMenuId, SysMenu::getMenuName, SysMenu::getMenuParentId, SysMenu::getAppId, + menuLambdaQueryWrapper.select(SysMenu::getMenuId, SysMenu::getMenuName, SysMenu::getMenuParentId, SysMenu::getAppId, SysMenu::getMenuPids, SysMenu::getMenuSort); // 如果限制菜单不为空,则根据限制菜单id进行筛选,否则查询所有菜单 @@ -284,6 +285,51 @@ public class SysMenuServiceImpl extends ServiceImpl impl return sysMenuList.stream().collect(Collectors.toMap(SysMenu::getMenuId, SysMenu::getMenuParentId)); } + @Override + public List completeParentMenu(List menuList) { + if (ObjectUtil.isEmpty(menuList)) { + return new ArrayList<>(); + } + + // 获取菜单的所有id,获取所有菜单的父级id集合 + Set menuIds = menuList.stream().map(SysMenu::getMenuId).collect(Collectors.toSet()); + Set needToAddMenuIdList = new HashSet<>(); + for (SysMenu sysMenu : menuList) { + String menuPids = sysMenu.getMenuPids(); + if (ObjectUtil.isEmpty(menuPids)) { + continue; + } + List parentIdList = ParentIdParseUtil.parseToPidList(menuPids); + if (ObjectUtil.isEmpty(parentIdList)) { + continue; + } + for (Long parentId : parentIdList) { + if (!parentId.equals(TreeConstants.DEFAULT_PARENT_ID)) { + if (!menuIds.contains(parentId)) { + needToAddMenuIdList.add(parentId); + } + } + } + } + + if (ObjectUtil.isEmpty(needToAddMenuIdList)) { + return menuList; + } + + // 查找新家菜单的集合 + List newAddMenuList = this.listByIds(needToAddMenuIdList); + + // 组合新增的和旧的菜单集合 + ArrayList sysMenus = new ArrayList<>(); + sysMenus.addAll(menuList); + sysMenus.addAll(newAddMenuList); + + // 对菜单进行再次排序,因为有的菜单是101,有的菜单是10101,需要将位数小的补0,再次排序 + MenuOrderFixUtil.fixOrder(sysMenus); + + return sysMenus; + } + @Override public List getAppMenuGroupDetail(SysMenuRequest sysMenuRequest) { diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/factory/PermissionAssignFactory.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/factory/PermissionAssignFactory.java index e7136b723..5fcc30f29 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/factory/PermissionAssignFactory.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/factory/PermissionAssignFactory.java @@ -12,7 +12,6 @@ import cn.stylefeng.roses.kernel.sys.modular.role.pojo.response.RoleBindPermissi import cn.stylefeng.roses.kernel.sys.modular.role.pojo.response.RoleBindPermissionResponse; import java.util.ArrayList; -import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -33,25 +32,32 @@ public class PermissionAssignFactory { * @author fengshuonan * @since 2023/6/13 16:32 */ - public static List createPermissionMenus(List sysMenus) { + public static List createPermissionMenus(List limitScopeTotalMenusWithTree) { - if (ObjectUtil.isEmpty(sysMenus)) { + if (ObjectUtil.isEmpty(limitScopeTotalMenusWithTree)) { return new ArrayList<>(); } // 搜集所有的父级菜单id - Set totalParentMenuId = sysMenus.stream().map(SysMenu::getMenuParentId).collect(Collectors.toSet()); + Set totalParentMenuId = limitScopeTotalMenusWithTree.stream().map(SysMenu::getMenuParentId).collect(Collectors.toSet()); // 通过父级菜单,筛选出来所有的叶子节点(如果菜单不存在父级菜单里,则代表是叶子节点) - Set leafMenus = sysMenus.stream().filter(item -> !totalParentMenuId.contains(item.getMenuId())) - .collect(Collectors.toCollection(LinkedHashSet::new)); + Set leafMenus = limitScopeTotalMenusWithTree.stream().map(SysMenu::getMenuId).filter(menuId -> !totalParentMenuId.contains(menuId)).collect(Collectors.toSet()); // 叶子节点转化为RoleBindPermissionItem结构 ArrayList roleBindPermissionItems = new ArrayList<>(); + for (SysMenu sysMenu : limitScopeTotalMenusWithTree) { + + // 转化结构 + RoleBindPermissionItem roleBindPermissionItem = new RoleBindPermissionItem(sysMenu.getMenuId(), sysMenu.getAppId(), sysMenu.getMenuName(), PermissionNodeTypeEnum.MENU.getCode(), false); + + // 判断是否是叶子节点 + if (leafMenus.contains(sysMenu.getMenuId())) { + roleBindPermissionItem.setLeafFlag(true); + } else { + roleBindPermissionItem.setLeafFlag(false); + } - for (SysMenu leafMenu : leafMenus) { - RoleBindPermissionItem roleBindPermissionItem = new RoleBindPermissionItem(leafMenu.getMenuId(), - leafMenu.getAppId(), leafMenu.getMenuName(), PermissionNodeTypeEnum.MENU.getCode(), false); roleBindPermissionItems.add(roleBindPermissionItem); } @@ -74,8 +80,8 @@ public class PermissionAssignFactory { // 封装响应结果 for (SysApp sysApp : sysApps) { - RoleBindPermissionItem roleBindPermissionItem = new RoleBindPermissionItem(sysApp.getAppId(), - TreeConstants.DEFAULT_PARENT_ID, sysApp.getAppName(), PermissionNodeTypeEnum.APP.getCode(), false); + RoleBindPermissionItem roleBindPermissionItem = new RoleBindPermissionItem(sysApp.getAppId(), TreeConstants.DEFAULT_PARENT_ID, sysApp.getAppName(), PermissionNodeTypeEnum.APP.getCode(), + false); appResults.add(roleBindPermissionItem); } @@ -98,8 +104,7 @@ public class PermissionAssignFactory { // 封装响应结果 for (SysMenuOptions sysMenuOptions : sysMenuOptionsList) { - RoleBindPermissionItem roleBindPermissionItem = new RoleBindPermissionItem(sysMenuOptions.getMenuOptionId(), - sysMenuOptions.getMenuId(), sysMenuOptions.getOptionName(), + RoleBindPermissionItem roleBindPermissionItem = new RoleBindPermissionItem(sysMenuOptions.getMenuOptionId(), sysMenuOptions.getMenuId(), sysMenuOptions.getOptionName(), PermissionNodeTypeEnum.OPTIONS.getCode(), false); optionsResult.add(roleBindPermissionItem); } @@ -116,20 +121,30 @@ public class PermissionAssignFactory { * @author fengshuonan * @since 2023/6/13 17:43 */ - public static RoleBindPermissionResponse composeSelectStructure(List apps, - List menus, - List options) { + public static RoleBindPermissionResponse composeSelectStructure(List apps, List menus, List options) { // 定义全选属性 RoleBindPermissionResponse roleBindPermissionResponse = new RoleBindPermissionResponse(); roleBindPermissionResponse.setChecked(false); + // 【2024年10月30日】把菜单上的功能挂载到菜单上 + for (RoleBindPermissionItem menuItem : menus) { + for (RoleBindPermissionItem optionItem : options) { + if (Convert.toLong(optionItem.getNodeParentId()).equals(Convert.toLong(menuItem.getNodeId()))) { + List functionList = menuItem.getFunctionList(); + if (ObjectUtil.isEmpty(functionList)) { + functionList = new ArrayList<>(); + } + functionList.add(optionItem); + menuItem.setFunctionList(functionList); + } + } + } + // 合并应用菜单和功能,并构建树形结构 apps.addAll(menus); - apps.addAll(options); - List roleBindPermissionItems = new DefaultTreeBuildFactory().doTreeBuild( - apps); + List roleBindPermissionItems = new DefaultTreeBuildFactory().doTreeBuild(apps); roleBindPermissionResponse.setAppPermissionList(roleBindPermissionItems); return roleBindPermissionResponse; @@ -143,8 +158,7 @@ public class PermissionAssignFactory { * @author fengshuonan * @since 2023/6/13 19:00 */ - public static RoleBindPermissionResponse fillCheckedFlag(RoleBindPermissionResponse roleBindPermissionResponse, - Set rolePermissions) { + public static RoleBindPermissionResponse fillCheckedFlag(RoleBindPermissionResponse roleBindPermissionResponse, Set rolePermissions) { List appList = roleBindPermissionResponse.getAppPermissionList(); diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/response/RoleBindPermissionItem.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/response/RoleBindPermissionItem.java index c78e17a85..b3ea9dde6 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/response/RoleBindPermissionItem.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/pojo/response/RoleBindPermissionItem.java @@ -60,9 +60,11 @@ public class RoleBindPermissionItem implements AbstractTreeNode + * 【2024年10月30日修改】去掉了3-功能,功能现在单独放在functionList这个字段 */ - @ChineseDescription("节点类型:1-应用,2-菜单,3-功能,-1-所有权限") + @ChineseDescription("节点类型:1-应用,2-菜单,-1-所有权限") private Integer permissionNodeType; /** @@ -77,6 +79,18 @@ public class RoleBindPermissionItem implements AbstractTreeNode children; + /** + * 是否是叶子节点 + */ + @ChineseDescription("是否是叶子节点") + private Boolean leafFlag; + + /** + * 功能集合 + */ + @ChineseDescription("功能集合") + private List functionList; + public RoleBindPermissionItem() { } diff --git a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/PermissionAssignServiceImpl.java b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/PermissionAssignServiceImpl.java index ac4dac8ba..05f2f6a96 100644 --- a/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/PermissionAssignServiceImpl.java +++ b/kernel-s-system/system-business-permission/src/main/java/cn/stylefeng/roses/kernel/sys/modular/role/service/impl/PermissionAssignServiceImpl.java @@ -119,18 +119,21 @@ public class PermissionAssignServiceImpl implements PermissionAssignService { public RoleBindPermissionResponse createSelectTreeStructure(Set limitMenuIdsAndOptionIds) { // 获取指定所有的菜单,如果不限制范围,则直接查询所有的菜单 - List totalMenus = null; + List limitScopeTotalMenus = null; if (ObjectUtil.isEmpty(limitMenuIdsAndOptionIds)) { - totalMenus = this.sysMenuService.getTotalMenus(); + limitScopeTotalMenus = this.sysMenuService.getTotalMenus(); } else { - totalMenus = this.sysMenuService.getTotalMenus(limitMenuIdsAndOptionIds); + limitScopeTotalMenus = this.sysMenuService.getTotalMenus(limitMenuIdsAndOptionIds); } + // 【2024年10月30日新增】将这些菜单,补全父级节点,因为角色权限分配这块,单纯渲染叶子节点不方便 + List limitScopeTotalMenusWithTree = this.sysMenuService.completeParentMenu(limitScopeTotalMenus); + // 组装所有的叶子节点菜单【初始化菜单】 - List totalResultMenus = PermissionAssignFactory.createPermissionMenus(totalMenus); + List totalResultMenus = PermissionAssignFactory.createPermissionMenus(limitScopeTotalMenusWithTree); // 查询菜单对应的所有应用 - Set appIdList = totalMenus.stream().map(SysMenu::getAppId).collect(Collectors.toSet()); + Set appIdList = limitScopeTotalMenusWithTree.stream().map(SysMenu::getAppId).collect(Collectors.toSet()); LambdaQueryWrapper sysAppLambdaQueryWrapper = new LambdaQueryWrapper<>(); sysAppLambdaQueryWrapper.in(SysApp::getAppId, appIdList); sysAppLambdaQueryWrapper.select(SysApp::getAppId, SysApp::getAppName);