diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/menu/MenuAndButtonTreeResponse.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/menu/MenuAndButtonTreeResponse.java new file mode 100644 index 000000000..e9e55ad80 --- /dev/null +++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/menu/MenuAndButtonTreeResponse.java @@ -0,0 +1,106 @@ +/* + * Copyright [2020-2030] [https://www.stylefeng.cn] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Guns采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点: + * + * 1.请不要删除和修改根目录下的LICENSE文件。 + * 2.请不要删除和修改Guns源码头部的版权声明。 + * 3.请保留源码和相关描述文件的项目出处,作者声明等。 + * 4.分发源码时候,请注明软件出处 https://gitee.com/stylefeng/guns + * 5.在修改包名,模块名称,项目代码等时,请注明软件出处 https://gitee.com/stylefeng/guns + * 6.若您的项目无法满足以上几点,可申请商业授权 + */ +package cn.stylefeng.roses.kernel.system.api.pojo.menu; + +import cn.stylefeng.roses.kernel.rule.tree.factory.base.AbstractTreeNode; +import cn.stylefeng.roses.kernel.scanner.api.annotation.field.ChineseDescription; +import lombok.Data; + +import java.util.List; + +/** + * 新版的角色绑定菜单和按钮,用在角色分配菜单和按钮节点 + * + * @author fengshuonan + * @date 2021/8/10 22:36 + */ +@Data +public class MenuAndButtonTreeResponse implements AbstractTreeNode { + + /** + * 节点ID,可以是菜单id和按钮id + */ + @ChineseDescription("节点ID") + private Long id; + + /** + * 节点父ID + */ + @ChineseDescription("节点父ID") + private Long pid; + + /** + * 节点名称 + */ + @ChineseDescription("节点名称") + private String name; + + /** + * code + */ + @ChineseDescription("code") + private String code; + + /** + * 是否选择(已拥有的是true) + */ + @ChineseDescription("是否选择(已拥有的是true)") + private Boolean checked; + + /** + * 当前节点的按钮集合 + */ + @ChineseDescription("当前节点的按钮集合") + private List buttons; + + /** + * 子节点集合 + */ + @ChineseDescription("子节点集合") + private List children; + + @Override + public String getNodeId() { + if (this.id != null) { + return this.id.toString(); + } else { + return ""; + } + } + + @Override + public String getNodeParentId() { + if (this.pid != null) { + return this.pid.toString(); + } else { + return ""; + } + } + + @Override + public void setChildrenNodes(List childrenNodes) { + this.children = childrenNodes; + } +} diff --git a/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/controller/SysMenuController.java b/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/controller/SysMenuController.java index d959dff4a..37e33df0b 100644 --- a/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/controller/SysMenuController.java +++ b/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/controller/SysMenuController.java @@ -30,6 +30,7 @@ import cn.stylefeng.roses.kernel.rule.tree.ztree.ZTreeNode; import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource; import cn.stylefeng.roses.kernel.scanner.api.annotation.GetResource; import cn.stylefeng.roses.kernel.scanner.api.annotation.PostResource; +import cn.stylefeng.roses.kernel.system.api.pojo.menu.MenuAndButtonTreeResponse; import cn.stylefeng.roses.kernel.system.api.pojo.menu.SysMenuRequest; import cn.stylefeng.roses.kernel.system.api.pojo.menu.antd.AntdMenuSelectTreeNode; import cn.stylefeng.roses.kernel.system.api.pojo.menu.antd.AntdSysMenuDTO; @@ -183,4 +184,16 @@ public class SysMenuController { return new SuccessResponseData(treeResponseList); } + /** + * 新版角色分配菜单和按钮界面使用的接口 + * + * @author fengshuonan + * @date 2021/8/10 22:21 + */ + @GetResource(name = "新版角色分配菜单和按钮界面使用的接口(v2)", path = "/sysMenu/menuAndButtonTreeChildrenV2", responseClass = LayuiMenuAndButtonTreeResponse.class) + public ResponseData menuAndButtonTreeChildrenV2(SysRoleRequest sysRoleRequest) { + List treeResponseList = sysMenuService.getRoleMenuAndButtons(sysRoleRequest); + return new SuccessResponseData(treeResponseList); + } + } diff --git a/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/factory/AntdMenusFactory.java b/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/factory/AntdMenusFactory.java index 43247152f..d41a8a30d 100644 --- a/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/factory/AntdMenusFactory.java +++ b/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/factory/AntdMenusFactory.java @@ -28,9 +28,13 @@ import cn.hutool.core.util.ObjectUtil; import cn.stylefeng.roses.kernel.rule.constants.TreeConstants; import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum; import cn.stylefeng.roses.kernel.rule.tree.factory.DefaultTreeBuildFactory; +import cn.stylefeng.roses.kernel.system.api.pojo.menu.MenuAndButtonTreeResponse; import cn.stylefeng.roses.kernel.system.api.pojo.menu.antd.AntdMenuSelectTreeNode; import cn.stylefeng.roses.kernel.system.api.pojo.menu.antd.AntdSysMenuDTO; +import cn.stylefeng.roses.kernel.system.api.pojo.role.dto.SysRoleMenuButtonDTO; +import cn.stylefeng.roses.kernel.system.api.pojo.role.dto.SysRoleMenuDTO; import cn.stylefeng.roses.kernel.system.modular.menu.entity.SysMenu; +import cn.stylefeng.roses.kernel.system.modular.menu.entity.SysMenuButton; import java.math.BigDecimal; import java.util.ArrayList; @@ -110,6 +114,79 @@ public class AntdMenusFactory { } } + /** + * 菜单集合转化成角色分配菜单的集合 + * + * @author fengshuonan + * @date 2021/8/10 22:56 + */ + public static List parseMenuAndButtonTreeResponse(List sysMenuList, List roleBindMenus) { + ArrayList result = new ArrayList<>(); + + if (ObjectUtil.isEmpty(sysMenuList)) { + return result; + } + + for (SysMenu sysMenu : sysMenuList) { + MenuAndButtonTreeResponse menuAndButtonTreeResponse = new MenuAndButtonTreeResponse(); + menuAndButtonTreeResponse.setId(sysMenu.getMenuId()); + menuAndButtonTreeResponse.setName(sysMenu.getMenuName()); + menuAndButtonTreeResponse.setCode(sysMenu.getMenuCode()); + menuAndButtonTreeResponse.setPid(sysMenu.getMenuParentId()); + menuAndButtonTreeResponse.setChecked(false); + + if (ObjectUtil.isNotEmpty(roleBindMenus)) { + for (SysRoleMenuDTO roleBindMenu : roleBindMenus) { + if (roleBindMenu.getMenuId().equals(sysMenu.getMenuId())) { + menuAndButtonTreeResponse.setChecked(true); + } + } + } + + result.add(menuAndButtonTreeResponse); + } + + return result; + } + + /** + * 菜单集合转化成角色分配菜单的集合 + * + * @author fengshuonan + * @date 2021/8/10 22:56 + */ + public static void fillButtons(List sysMenuList, List buttonList, List roleMenuButtonList) { + for (MenuAndButtonTreeResponse menuAndButtonTreeResponse : sysMenuList) { + if (ObjectUtil.isEmpty(buttonList)) { + continue; + } + + ArrayList menuButtonList = new ArrayList<>(); + + for (SysMenuButton sysMenuButton : buttonList) { + if (menuAndButtonTreeResponse.getId().equals(sysMenuButton.getMenuId())) { + MenuAndButtonTreeResponse buttonInfo = new MenuAndButtonTreeResponse(); + buttonInfo.setId(sysMenuButton.getButtonId()); + buttonInfo.setName(sysMenuButton.getButtonName()); + buttonInfo.setCode(sysMenuButton.getButtonCode()); + buttonInfo.setChecked(false); + + if (ObjectUtil.isNotEmpty(roleMenuButtonList)) { + for (SysRoleMenuButtonDTO sysRoleMenuButtonDTO : roleMenuButtonList) { + if (sysRoleMenuButtonDTO.getButtonId().equals(sysMenuButton.getButtonId())) { + buttonInfo.setChecked(true); + } + } + } + + menuButtonList.add(buttonInfo); + } + } + + menuAndButtonTreeResponse.setButtons(menuButtonList); + } + } + /** * 模型转化 * diff --git a/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/service/SysMenuService.java b/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/service/SysMenuService.java index 86b6bd0e9..890db2a58 100644 --- a/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/service/SysMenuService.java +++ b/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/service/SysMenuService.java @@ -25,6 +25,7 @@ package cn.stylefeng.roses.kernel.system.modular.menu.service; import cn.stylefeng.roses.kernel.rule.tree.ztree.ZTreeNode; +import cn.stylefeng.roses.kernel.system.api.pojo.menu.MenuAndButtonTreeResponse; import cn.stylefeng.roses.kernel.system.api.pojo.menu.SysMenuRequest; import cn.stylefeng.roses.kernel.system.api.pojo.menu.antd.AntdMenuSelectTreeNode; import cn.stylefeng.roses.kernel.system.api.pojo.menu.antd.AntdSysMenuDTO; @@ -145,6 +146,14 @@ public interface SysMenuService extends IService { */ List getMenuAndButtonTree(SysRoleRequest sysRoleRequest, Boolean lateralFlag); + /** + * 获取角色绑定菜单和按钮权限的树 + * + * @author fengshuonan + * @date 2021/8/10 22:23 + */ + List getRoleMenuAndButtons(SysRoleRequest sysRoleRequest); + /** * 获取当前用户的某个应用下的菜单 * diff --git a/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/service/impl/SysMenuServiceImpl.java b/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/service/impl/SysMenuServiceImpl.java index be1c79749..95606424e 100644 --- a/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/service/impl/SysMenuServiceImpl.java +++ b/kernel-s-system/system-business-menu/src/main/java/cn/stylefeng/roses/kernel/system/modular/menu/service/impl/SysMenuServiceImpl.java @@ -45,6 +45,7 @@ import cn.stylefeng.roses.kernel.system.api.RoleServiceApi; import cn.stylefeng.roses.kernel.system.api.exception.SystemModularException; import cn.stylefeng.roses.kernel.system.api.exception.enums.menu.SysMenuExceptionEnum; import cn.stylefeng.roses.kernel.system.api.exception.enums.user.SysUserExceptionEnum; +import cn.stylefeng.roses.kernel.system.api.pojo.menu.MenuAndButtonTreeResponse; import cn.stylefeng.roses.kernel.system.api.pojo.menu.SysMenuRequest; import cn.stylefeng.roses.kernel.system.api.pojo.menu.antd.AntdMenuSelectTreeNode; import cn.stylefeng.roses.kernel.system.api.pojo.menu.antd.AntdSysMenuDTO; @@ -311,22 +312,24 @@ public class SysMenuServiceImpl extends ServiceImpl impl public List getMenuAndButtonTree(SysRoleRequest sysRoleRequest, Boolean lateralFlag) { List menuTreeNodeList = CollectionUtil.newArrayList(); - LambdaQueryWrapper munuWrapper = new LambdaQueryWrapper<>(); - munuWrapper.eq(SysMenu::getStatusFlag, StatusEnum.ENABLE.getCode()); - munuWrapper.eq(SysMenu::getDelFlag, YesOrNotEnum.N.getCode()); - // 非超级管理员则获取自己拥有的菜单,分配给人员,防止越级授权 + // 查询未删除的启用的菜单列表 + LambdaQueryWrapper menuWrapper = new LambdaQueryWrapper<>(); + menuWrapper.eq(SysMenu::getStatusFlag, StatusEnum.ENABLE.getCode()); + menuWrapper.eq(SysMenu::getDelFlag, YesOrNotEnum.N.getCode()); + + // 非超级管理员则获取自己拥有的菜单 if (!LoginContext.me().getSuperAdminFlag()) { List menuIdList = getCurrentUserMenuIds(); if (!menuIdList.isEmpty()) { - munuWrapper.in(SysMenu::getMenuId, menuIdList); + menuWrapper.in(SysMenu::getMenuId, menuIdList); } } + List sysMenuList = this.list(menuWrapper); - List sysMenuList = this.list(munuWrapper); - + // 获取菜单的id集合 List menuList = sysMenuList.parallelStream().map(SysMenu::getMenuId).collect(Collectors.toList()); - // 查询所有的按钮 + // 查询这些菜单对应的所有按钮 LambdaQueryWrapper buttonWrapper = new LambdaQueryWrapper<>(); buttonWrapper.eq(SysMenuButton::getDelFlag, YesOrNotEnum.N.getCode()); buttonWrapper.in(SysMenuButton::getMenuId, menuList); @@ -346,6 +349,7 @@ public class SysMenuServiceImpl extends ServiceImpl impl // 查询所有已有的权限 // 所有已有的菜单权限 List roleMenuList = roleServiceApi.getRoleMenuList(Collections.singletonList(sysRoleRequest.getRoleId())); + // 转换成map方便后续处理 Map roleMenuMap = new HashMap<>(); for (SysRoleMenuDTO sysRoleMenuResponse : roleMenuList) { @@ -370,11 +374,7 @@ public class SysMenuServiceImpl extends ServiceImpl impl menuTree.setPid(sysMenu.getMenuParentId()); // 判断是否已经有了 SysRoleMenuDTO roleMenuResponse = roleMenuMap.get(sysMenu.getMenuId()); - if (ObjectUtil.isEmpty(roleMenuResponse)) { - menuTree.setChecked(false); - } else { - menuTree.setChecked(true); - } + menuTree.setChecked(!ObjectUtil.isEmpty(roleMenuResponse)); // 处理该菜单的按钮 List menuButtons = buttons.get(sysMenu.getMenuId()); @@ -412,6 +412,51 @@ public class SysMenuServiceImpl extends ServiceImpl impl } } + @Override + public List getRoleMenuAndButtons(SysRoleRequest sysRoleRequest) { + List menuTreeNodeList = CollectionUtil.newArrayList(); + + // 查询未删除的启用的菜单列表 + LambdaQueryWrapper menuWrapper = new LambdaQueryWrapper<>(); + menuWrapper.eq(SysMenu::getDelFlag, YesOrNotEnum.N.getCode()); + menuWrapper.eq(SysMenu::getStatusFlag, StatusEnum.ENABLE.getCode()); + + // 非超级管理员则获取自己拥有的菜单 + if (!LoginContext.me().getSuperAdminFlag()) { + List menuIdList = getCurrentUserMenuIds(); + if (!menuIdList.isEmpty()) { + menuWrapper.in(SysMenu::getMenuId, menuIdList); + } + } + + // 查询所有菜单列表 + List sysMenuList = this.list(menuWrapper); + + // 获取菜单的id集合 + List menuIdList = sysMenuList.stream().map(SysMenu::getMenuId).collect(Collectors.toList()); + + // 获取角色绑定的菜单的id + List roleMenuList = roleServiceApi.getRoleMenuList(Collections.singletonList(sysRoleRequest.getRoleId())); + + // 转化 --->>> 菜单列表自转化为响应的节点类型 + List menuAndButtonTreeResponses = AntdMenusFactory.parseMenuAndButtonTreeResponse(sysMenuList, roleMenuList); + + // 查询这些菜单对应的所有按钮 + LambdaQueryWrapper buttonWrapper = new LambdaQueryWrapper<>(); + buttonWrapper.eq(SysMenuButton::getDelFlag, YesOrNotEnum.N.getCode()); + buttonWrapper.in(SysMenuButton::getMenuId, menuIdList); + List buttonList = sysMenuButtonService.list(buttonWrapper); + + // 获取角色绑定的按钮的id + List roleMenuButtonList = roleServiceApi.getRoleMenuButtonList(Collections.singletonList(sysRoleRequest.getRoleId())); + + // 转化 --->>> 将这些按钮,分别绑定在各自的菜单上 + AntdMenusFactory.fillButtons(menuAndButtonTreeResponses, buttonList, roleMenuButtonList); + + // 菜单列表转化为一棵树 + return new DefaultTreeBuildFactory().doTreeBuild(menuAndButtonTreeResponses); + } + @Override public List getCurrentUserMenus(String appCode, Boolean layuiVisibleFlag) {