ソースを参照

菜单权限bug

liuyc 2 年 前
コミット
d03ae31c2f

+ 5 - 0
blade-service-api/blade-system-api/pom.xml

@@ -24,6 +24,11 @@
             <artifactId>blade-dict-api</artifactId>
             <version>2.9.1.RELEASE</version>
         </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-user-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 5 - 4
blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/GrantTreeVO.java

@@ -2,6 +2,7 @@ package org.springblade.system.vo;
 
 import lombok.Data;
 import org.springblade.core.tool.node.TreeNode;
+import org.springblade.system.user.vo.TreeNodeVO;
 
 import java.io.Serializable;
 import java.util.List;
@@ -16,16 +17,16 @@ public class GrantTreeVO implements Serializable {
 	private static final long serialVersionUID = 1L;
 
 	//后管
-	private List<TreeNode> menu;
+	private List<TreeNodeVO> menu;
 
 	//客户端
-	private List<TreeNode> usermenu;
+	private List<TreeNodeVO> usermenu;
 
 	//数据
-	private List<TreeNode> dataScope;
+	private List<TreeNodeVO> dataScope;
 
 	//api
-	private List<TreeNode> apiScope;
+	private List<TreeNodeVO> apiScope;
 
 	//表单
 	private List<DictVO02> tableOwners;

+ 16 - 0
blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/RoleAndMenusVO.java

@@ -0,0 +1,16 @@
+package org.springblade.system.vo;
+
+import lombok.Data;
+import java.io.Serializable;
+
+@Data
+public class RoleAndMenusVO implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    private Long menuId;
+
+    private Long roleId;
+
+}

+ 118 - 0
blade-service-api/blade-user-api/src/main/java/org/springblade/system/user/vo/TreeNodeVO.java

@@ -0,0 +1,118 @@
+package org.springblade.system.user.vo;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import lombok.Data;
+import org.springblade.core.tool.node.BaseNode;
+
+@Data
+public class TreeNodeVO extends BaseNode<TreeNodeVO> {
+    private static final long serialVersionUID = 1L;
+    private String title;
+    @JsonSerialize(
+        using = ToStringSerializer.class
+    )
+    private Long key;
+    @JsonSerialize(
+        using = ToStringSerializer.class
+    )
+    private Long value;
+
+    private Long sysId;
+
+    public TreeNodeVO() {
+    }
+
+    public String getTitle() {
+        return this.title;
+    }
+
+    public Long getKey() {
+        return this.key;
+    }
+
+    public Long getValue() {
+        return this.value;
+    }
+
+    public void setTitle(final String title) {
+        this.title = title;
+    }
+
+    public void setKey(final Long key) {
+        this.key = key;
+    }
+
+    public void setValue(final Long value) {
+        this.value = value;
+    }
+
+    public String toString() {
+        return "TreeNode(title=" + this.getTitle() + ", key=" + this.getKey() + ", value=" + this.getValue() + ")";
+    }
+
+    public boolean equals(final Object o) {
+        if (o == this) {
+            return true;
+        } else if (!(o instanceof TreeNodeVO)) {
+            return false;
+        } else {
+            TreeNodeVO other = (TreeNodeVO)o;
+            if (!other.canEqual(this)) {
+                return false;
+            } else {
+                label47: {
+                    Object this$key = this.getKey();
+                    Object other$key = other.getKey();
+                    if (this$key == null) {
+                        if (other$key == null) {
+                            break label47;
+                        }
+                    } else if (this$key.equals(other$key)) {
+                        break label47;
+                    }
+
+                    return false;
+                }
+
+                Object this$value = this.getValue();
+                Object other$value = other.getValue();
+                if (this$value == null) {
+                    if (other$value != null) {
+                        return false;
+                    }
+                } else if (!this$value.equals(other$value)) {
+                    return false;
+                }
+
+                Object this$title = this.getTitle();
+                Object other$title = other.getTitle();
+                if (this$title == null) {
+                    if (other$title != null) {
+                        return false;
+                    }
+                } else if (!this$title.equals(other$title)) {
+                    return false;
+                }
+
+                return true;
+            }
+        }
+    }
+
+    protected boolean canEqual(final Object other) {
+        return other instanceof TreeNodeVO;
+    }
+
+    public int hashCode() {
+        boolean PRIME = true;
+        int result = 1;
+        Object $key = this.getKey();
+        result = result * 59 + ($key == null ? 43 : $key.hashCode());
+        Object $value = this.getValue();
+        result = result * 59 + ($value == null ? 43 : $value.hashCode());
+        Object $title = this.getTitle();
+        result = result * 59 + ($title == null ? 43 : $title.hashCode());
+        return result;
+    }
+}

+ 2 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreeController.java

@@ -172,10 +172,10 @@ public class WbsTreeController extends BladeController {
     @ApiImplicitParam(name = "id", value = "表单id", required = true)
     public R removeTableById(@RequestParam("id") String id) {
         if (StringUtils.isNotEmpty(id)) {
-            List<WbsFormElementVO> wbsFormElements = wbsTreeService.selectFormElements(id);
+            /*List<WbsFormElementVO> wbsFormElements = wbsTreeService.selectFormElements(id);
             if (wbsFormElements.size() > 0) {
                 throw new ServiceException("该表单中存在元素,删除失败");
-            }
+            }*/
             /*Long wbsTreePrivates = wbsTreePrivateMapper.selectCount(Wrappers.<WbsTreePrivate>query().lambda()
                     .eq(WbsTreePrivate::getStatus, 1)
                     .eq(WbsTreePrivate::getId, id));

+ 2 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/WbsTreePrivateController.java

@@ -256,14 +256,14 @@ public class WbsTreePrivateController extends BladeController {
     public R removeTableByCondition(@RequestParam("id") String id,
                                     @RequestParam("wbsId") String wbsId,
                                     @RequestParam("projectId") String projectId) {
-        Long wbsTreeContracts = wbsTreeContractMapper.selectCount(Wrappers.<WbsTreeContract>query().lambda()
+        /*Long wbsTreeContracts = wbsTreeContractMapper.selectCount(Wrappers.<WbsTreeContract>query().lambda()
                 .eq(WbsTreeContract::getProjectId, projectId)
                 .eq(WbsTreeContract::getWbsId, wbsId)
                 .eq(WbsTreeContract::getId, id)
         );
         if (wbsTreeContracts > 0L) {
             throw new ServiceException("当前表单被合同段引用中,删除失败");
-        }
+        }*/
         boolean result = wbsTreePrivateService.removeTableByCondition(id, wbsId, projectId);
         if (result) {
             return R.success("删除成功");

+ 36 - 17
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -419,21 +419,6 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         return true;
     }
 
-    private WbsTreeContract buildFailData(Integer nodeType, String nodeName, String partitionCode) {
-        WbsTreeContract wbsTreeContract = new WbsTreeContract();
-        Long id = SnowFlakeUtil.getId();
-        wbsTreeContract.setPKeyId(id);
-        wbsTreeContract.setId(id);
-        wbsTreeContract.setNodeName(nodeName);
-        wbsTreeContract.setFullName(nodeName);
-        wbsTreeContract.setImportMatchingInfo(nodeName);
-        wbsTreeContract.setPartitionCode(partitionCode);
-        wbsTreeContract.setType(1);
-        wbsTreeContract.setNodeType(nodeType);
-        wbsTreeContract.setIsImportIdentificationNode(0);  //识别失败
-        return wbsTreeContract;
-    }
-
     private List<WbsTreeContract> findAllNodeList(String wbsTreeIds, String projectId, String contractId, String wbsId) {
         String[] ids = wbsTreeIds.split(",");
         List<WbsTreeContract> list = new ArrayList<>();
@@ -666,16 +651,35 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
             }
         }
 
+        Set<WbsTreeContractVO> listSet = new HashSet<>();
+        //把successData的节点的上级节点都添加进去
+        if (successData.size() > 0) {
+            //通过ancestors获取所有上级节点
+            for (WbsTreeContractVO successDatum : successData) {
+                String ancestorsIds = successDatum.getAncestors();
+                List<Long> parentIds = Func.toLongList(ancestorsIds);
+                for (Long parentId : parentIds) {
+                    for (WbsTreeContractVO wbsTreeContractVO : wbsTreeContractVOS) {
+                        if (parentId.equals(wbsTreeContractVO.getId())) {
+                            listSet.add(wbsTreeContractVO);
+                        }
+                    }
+                }
+            }
+        }
+
         WbsTreeContractVO4 res = new WbsTreeContractVO4();
         try {
             //重复导入时删除多余节点信息
             List<WbsTreeContract> wbsTreeContractDel = baseMapper.selectList(Wrappers.<WbsTreeContract>query().lambda().eq(WbsTreeContract::getContractId, wbsTreeContractRoot.getContractId()));
             List<Long> delIds = wbsTreeContractDel.stream().filter(f -> f.getNodeName().contains(("_copy_copy")) && f.getId().equals(f.getPKeyId())).collect(Collectors.toList())
                     .stream().map(WbsTreeContract::getPKeyId).collect(Collectors.toList());
-            baseMapper.deleteByIds(delIds);
+            if (delIds.size() > 0) {
+                baseMapper.deleteByIds(delIds);
+            }
 
             //构建成功树
-            List<WbsTreeContractVO> collect1 = successData.stream().collect(
+            List<WbsTreeContractVO> collect1 = listSet.stream().collect(
                     Collectors.collectingAndThen(
                             Collectors.toCollection(() -> new TreeSet<>(
                                     Comparator.comparing(o -> o.getId() + ";" + o.getFullName()))), ArrayList::new));
@@ -829,6 +833,21 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         return resultData;
     }
 
+    private WbsTreeContract buildFailData(Integer nodeType, String nodeName, String partitionCode) {
+        WbsTreeContract wbsTreeContract = new WbsTreeContract();
+        Long id = SnowFlakeUtil.getId();
+        wbsTreeContract.setPKeyId(id);
+        wbsTreeContract.setId(id);
+        wbsTreeContract.setNodeName(nodeName);
+        wbsTreeContract.setFullName(nodeName);
+        wbsTreeContract.setImportMatchingInfo(nodeName);
+        wbsTreeContract.setPartitionCode(partitionCode);
+        wbsTreeContract.setType(1);
+        wbsTreeContract.setNodeType(nodeType);
+        wbsTreeContract.setIsImportIdentificationNode(0);  //识别失败
+        return wbsTreeContract;
+    }
+
     private List<WbsTreeContractVO> buildWbsTreeByStream(List<WbsTreeContractVO> wbsTreeVO2s, Long id) {
         List<WbsTreeContractVO> list = wbsTreeVO2s.stream().filter(f -> f.getParentId().equals(id)).collect(Collectors.toList());
         Map<Long, List<WbsTreeContractVO>> map = wbsTreeVO2s.stream().collect(Collectors.groupingBy(WbsTreeContractVO::getParentId));

+ 0 - 43
blade-service/blade-manager/src/test/java/org/springblade/flow/test/launch/LauncherTestServiceImpl.java

@@ -1,43 +0,0 @@
-/*
- *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright
- *  notice, this list of conditions and the following disclaimer in the
- *  documentation and/or other materials provided with the distribution.
- *  Neither the name of the dreamlu.net developer nor the names of its
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *  Author: Chill 庄骞 (smallchill@163.com)
- */
-package org.springblade.flow.test.launch;
-
-import org.springblade.common.constant.LauncherConstant;
-import org.springblade.core.auto.service.AutoService;
-import org.springblade.core.launch.service.LauncherService;
-import org.springblade.core.launch.utils.PropsUtil;
-import org.springframework.boot.builder.SpringApplicationBuilder;
-
-import java.util.Properties;
-
-/**
- * 启动参数拓展
- *
- * @author smallchil
- */
-@AutoService(LauncherService.class)
-public class LauncherTestServiceImpl implements LauncherService {
-
-	@Override
-	public void launcher(SpringApplicationBuilder builder, String appName, String profile, boolean isLocalDev) {
-		Properties props = System.getProperties();
-		PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.server-addr", LauncherConstant.nacosAddr(profile));
-		PropsUtil.setProperty(props, "spring.cloud.nacos.config.server-addr", LauncherConstant.nacosAddr(profile));
-		PropsUtil.setProperty(props, "spring.datasource.dynamic.enabled", "false");
-	}
-
-}

+ 25 - 10
blade-service/blade-system/src/main/java/org/springblade/system/controller/MenuController.java

@@ -32,6 +32,7 @@ import org.springblade.core.tool.node.TreeNode;
 import org.springblade.core.tool.support.Kv;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.entity.WbsTableOwnerRole;
+import org.springblade.system.entity.AuthClient;
 import org.springblade.system.entity.Dict;
 import org.springblade.system.entity.Menu;
 import org.springblade.system.entity.TopMenu;
@@ -40,6 +41,7 @@ import org.springblade.system.service.IDictService;
 import org.springblade.system.service.IMenuService;
 import org.springblade.system.service.IRoleService;
 import org.springblade.system.service.ITopMenuService;
+import org.springblade.system.user.vo.TreeNodeVO;
 import org.springblade.system.vo.CheckedTreeVO;
 import org.springblade.system.vo.DictVO02;
 import org.springblade.system.vo.GrantTreeVO;
@@ -217,22 +219,36 @@ public class MenuController extends BladeController {
 
     /**
      * 获取权限分配树形结构
-     *
      */
     @GetMapping("/grant-tree")
     @ApiOperationSupport(order = 12)
     @ApiOperation(value = "权限分配树形结构", notes = "权限分配树形结构")
     public R<GrantTreeVO> grantTree(BladeUser user) {
         GrantTreeVO vo = new GrantTreeVO();
-        List<TreeNode> treeUserMenu = new ArrayList<>();
-        List<TreeNode> treeMenu = new ArrayList<>();
+        List<TreeNodeVO> treeUserMenu = new ArrayList<>();
+        List<TreeNodeVO> treeMenu = new ArrayList<>();
         //获取所有菜单
-        List<TreeNode> treeNodesAll = menuService.grantTree(user);
-        for (TreeNode treeNode : treeNodesAll) {
-            if (treeNode.getTitle().equals("质量管理") || treeNode.getTitle().equals("任务管理")) {
-                treeUserMenu.add(treeNode);
-            } else {
-                treeMenu.add(treeNode);
+        List<TreeNodeVO> treeNodesAll = menuService.grantTree(user);
+        //获取AuthClient
+        List<AuthClient> authClients = menuService.getSysId();
+
+        for (TreeNodeVO treeNode : treeNodesAll) {
+            if (treeNode.getSysId() != null) {
+                for (AuthClient authClient : authClients) {
+                    if (("client").equals(authClient.getClientId())) {
+                        //客户端
+                        if (treeNode.getSysId().equals(authClient.getId())) {
+                            treeUserMenu.add(treeNode);
+                        }
+                    }
+                    if (("saber").equals(authClient.getClientId())) {
+                        //后管
+                        if (treeNode.getSysId().equals(authClient.getId())) {
+                            treeMenu.add(treeNode);
+                        }
+                    }
+                    //TODO 其他菜单权限
+                }
             }
         }
 
@@ -253,7 +269,6 @@ public class MenuController extends BladeController {
 
     /**
      * 获取权限分配树形结构
-     *
      */
     @GetMapping("/role-tree-keys")
     @ApiOperationSupport(order = 13)

+ 16 - 8
blade-service/blade-system/src/main/java/org/springblade/system/mapper/MenuMapper.java

@@ -18,9 +18,12 @@ package org.springblade.system.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.springblade.core.tool.node.TreeNode;
+import org.springblade.system.entity.AuthClient;
+import org.springblade.system.user.vo.TreeNodeVO;
 import org.springblade.system.dto.MenuDTO;
 import org.springblade.system.entity.Menu;
 import org.springblade.system.vo.MenuVO;
+import org.springblade.system.vo.RoleAndMenusVO;
 
 import java.util.List;
 import java.util.Map;
@@ -63,7 +66,7 @@ public interface MenuMapper extends BaseMapper<Menu> {
 	 *
 	 * @return
 	 */
-	List<TreeNode> grantTree();
+	List<TreeNodeVO> grantTree();
 
 	/**
 	 * 授权树形结构
@@ -71,14 +74,14 @@ public interface MenuMapper extends BaseMapper<Menu> {
 	 * @param roleId
 	 * @return
 	 */
-	List<TreeNode> grantTreeByRole(List<Long> roleId);
+	List<TreeNodeVO> grantTreeByRole(List<Long> roleId);
 
 	/**
 	 * 顶部菜单树形结构
 	 *
 	 * @return
 	 */
-	List<TreeNode> grantTopTree();
+	List<TreeNodeVO> grantTopTree();
 
 	/**
 	 * 顶部菜单树形结构
@@ -86,21 +89,21 @@ public interface MenuMapper extends BaseMapper<Menu> {
 	 * @param roleId
 	 * @return
 	 */
-	List<TreeNode> grantTopTreeByRole(List<Long> roleId);
+	List<TreeNodeVO> grantTopTreeByRole(List<Long> roleId);
 
 	/**
 	 * 数据权限授权树形结构
 	 *
 	 * @return
 	 */
-	List<TreeNode> grantDataScopeTree();
+	List<TreeNodeVO> grantDataScopeTree();
 
 	/**
 	 * 接口权限授权树形结构
 	 *
 	 * @return
 	 */
-	List<TreeNode> grantApiScopeTree();
+	List<TreeNodeVO> grantApiScopeTree();
 
 	/**
 	 * 数据权限授权树形结构
@@ -108,7 +111,7 @@ public interface MenuMapper extends BaseMapper<Menu> {
 	 * @param roleId
 	 * @return
 	 */
-	List<TreeNode> grantDataScopeTreeByRole(List<Long> roleId);
+	List<TreeNodeVO> grantDataScopeTreeByRole(List<Long> roleId);
 
 	/**
 	 * 接口权限授权树形结构
@@ -116,7 +119,7 @@ public interface MenuMapper extends BaseMapper<Menu> {
 	 * @param roleId
 	 * @return
 	 */
-	List<TreeNode> grantApiScopeTreeByRole(List<Long> roleId);
+	List<TreeNodeVO> grantApiScopeTreeByRole(List<Long> roleId);
 
 	/**
 	 * 所有菜单
@@ -190,4 +193,9 @@ public interface MenuMapper extends BaseMapper<Menu> {
 	 * @return
 	 */
 	List<MenuDTO> authRoutes(List<Long> roleIds);
+
+    List<AuthClient> selectBySysId();
+
+    List<RoleAndMenusVO> allRoleAndMenu(String roleId);
+
 }

+ 12 - 3
blade-service/blade-system/src/main/java/org/springblade/system/mapper/MenuMapper.xml

@@ -40,12 +40,13 @@
         <result column="text_info" property="textInfo"/>
     </resultMap>
 
-    <resultMap id="treeNodeResultMap" type="org.springblade.core.tool.node.TreeNode">
+    <resultMap id="treeNodeResultMap" type="org.springblade.system.user.vo.TreeNodeVO">
         <id column="id" property="id"/>
         <result column="parent_id" property="parentId"/>
         <result column="title" property="title"/>
         <result column="value" property="value"/>
         <result column="key" property="key"/>
+        <result column="sysId" property="sysId"/>
     </resultMap>
 
     <select id="lazyList"  resultMap="menuVOResultMap">
@@ -284,11 +285,11 @@
 
 
     <select id="grantTree" resultMap="treeNodeResultMap">
-        select id, parent_id, name as title, id as "value", id as "key" from blade_menu where is_deleted = 0 order by sort
+        select id, parent_id, name as title, id as "value", id as "key", sys_id AS "sysId" from blade_menu where is_deleted = 0 order by sort
     </select>
 
     <select id="grantTreeByRole" resultMap="treeNodeResultMap">
-        select id, parent_id, name as title, id as "value", id as "key" from blade_menu where is_deleted = 0
+        select id, parent_id, name as title, id as "value", id as "key", sys_id AS "sysId" from blade_menu where is_deleted = 0
         and id in ( select menu_id from blade_role_menu where role_id in
         <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
             #{item}
@@ -538,4 +539,12 @@
         GROUP BY m.path
     </select>
 
+    <select id="selectBySysId" resultType="org.springblade.system.entity.AuthClient">
+        select * from blade_client
+    </select>
+
+    <select id="allRoleAndMenu" resultType="org.springblade.system.vo.RoleAndMenusVO">
+        select * from blade_role_menu where role_id = #{roleId}
+    </select>
+
 </mapper>

+ 9 - 4
blade-service/blade-system/src/main/java/org/springblade/system/service/IMenuService.java

@@ -20,6 +20,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.tool.node.TreeNode;
 import org.springblade.core.tool.support.Kv;
+import org.springblade.system.entity.AuthClient;
+import org.springblade.system.user.vo.TreeNodeVO;
 import org.springblade.system.entity.Menu;
 import org.springblade.system.vo.MenuVO;
 
@@ -82,7 +84,7 @@ public interface IMenuService extends IService<Menu> {
 	 * @param user
 	 * @return
 	 */
-	List<TreeNode> grantTree(BladeUser user);
+	List<TreeNodeVO> grantTree(BladeUser user);
 
 	/**
 	 * 顶部菜单树形结构
@@ -90,7 +92,7 @@ public interface IMenuService extends IService<Menu> {
 	 * @param user
 	 * @return
 	 */
-	List<TreeNode> grantTopTree(BladeUser user);
+	List<TreeNodeVO> grantTopTree(BladeUser user);
 
 	/**
 	 * 数据权限授权树形结构
@@ -98,7 +100,7 @@ public interface IMenuService extends IService<Menu> {
 	 * @param user
 	 * @return
 	 */
-	List<TreeNode> grantDataScopeTree(BladeUser user);
+	List<TreeNodeVO> grantDataScopeTree(BladeUser user);
 
 	/**
 	 * 接口权限授权树形结构
@@ -106,7 +108,7 @@ public interface IMenuService extends IService<Menu> {
 	 * @param user
 	 * @return
 	 */
-	List<TreeNode> grantApiScopeTree(BladeUser user);
+	List<TreeNodeVO> grantApiScopeTree(BladeUser user);
 
 	/**
 	 * 默认选中节点
@@ -164,4 +166,7 @@ public interface IMenuService extends IService<Menu> {
 	 */
 	boolean submit(Menu menu);
 
+	List<AuthClient> getSysId();
+
+
 }

+ 230 - 207
blade-service/blade-system/src/main/java/org/springblade/system/service/impl/MenuServiceImpl.java

@@ -29,6 +29,7 @@ import org.springblade.core.tool.node.TreeNode;
 import org.springblade.core.tool.support.Kv;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.system.user.vo.TreeNodeVO;
 import org.springblade.system.cache.SysCache;
 import org.springblade.system.dto.MenuDTO;
 import org.springblade.system.entity.*;
@@ -38,6 +39,7 @@ import org.springblade.system.service.IRoleMenuService;
 import org.springblade.system.service.IRoleScopeService;
 import org.springblade.system.service.ITopMenuSettingService;
 import org.springblade.system.vo.MenuVO;
+import org.springblade.system.vo.RoleAndMenusVO;
 import org.springblade.system.wrapper.MenuWrapper;
 import org.springframework.cache.annotation.Cacheable;
 import org.springframework.stereotype.Service;
@@ -58,212 +60,233 @@ import static org.springblade.core.cache.constant.CacheConstant.MENU_CACHE;
 @AllArgsConstructor
 public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {
 
-	private final IRoleMenuService roleMenuService;
-	private final IRoleScopeService roleScopeService;
-	private final ITopMenuSettingService topMenuSettingService;
-	private final static String PARENT_ID = "parentId";
-	private final static Integer MENU_CATEGORY = 1;
-
-	@Override
-	public List<MenuVO> lazyList(Long parentId, Map<String, Object> param) {
-		if (Func.isEmpty(Func.toStr(param.get(PARENT_ID)))) {
-			parentId = null;
-		}
-		List<MenuVO> lazyList = baseMapper.lazyList(parentId, param);
-		return lazyList;
-
-	}
-
-	@Override
-	public List<MenuVO> lazyMenuList(Long parentId, Map<String, Object> param) {
-		if (Func.isEmpty(Func.toStr(param.get(PARENT_ID)))) {
-			parentId = null;
-		}
-		return baseMapper.lazyMenuList(parentId, param);
-	}
-
-
-	@Override
-	public List<MenuVO> routes(String roleId, Long topMenuId,String sysType) {
-		if (StringUtil.isBlank(roleId)) {
-			return null;
-		}
-
-		List<Menu> allMenus = baseMapper.allMenuBySysType(sysType);
-
-		List<Menu> roleMenus;
-		// 超级管理员并且不是顶部菜单请求则返回全部菜单
-		if (AuthUtil.isAdministrator() && Func.isEmpty(topMenuId)) {
-			roleMenus = allMenus;
-		}
-		// 非超级管理员并且不是顶部菜单请求则返回对应角色权限菜单
-		else if (!AuthUtil.isAdministrator() && Func.isEmpty(topMenuId)) {
-			roleMenus = tenantPackageMenu(baseMapper.roleMenuByRoleId(Func.toLongList(roleId)));
-		}
-		// 顶部菜单请求返回对应角色权限菜单
-		else {
-			// 角色配置对应菜单
-			List<Menu> roleIdMenus = baseMapper.roleMenuByRoleId(Func.toLongList(roleId));
-			// 反向递归角色菜单所有父级
-			List<Menu> routes = new LinkedList<>(roleIdMenus);
-			roleIdMenus.forEach(roleMenu -> recursion(allMenus, routes, roleMenu));
-			// 顶部配置对应菜单
-			List<Menu> topIdMenus = baseMapper.roleMenuByTopMenuId(topMenuId);
-			// 筛选匹配角色对应的权限菜单
-			roleMenus = topIdMenus.stream().filter(x ->
-				routes.stream().anyMatch(route -> route.getId().longValue() == x.getId().longValue())
-			).collect(Collectors.toList());
-		}
-		return buildRoutes(allMenus, roleMenus);
-	}
-
-	private List<MenuVO> buildRoutes(List<Menu> allMenus, List<Menu> roleMenus) {
-		List<Menu> routes = new LinkedList<>(roleMenus);
-		roleMenus.forEach(roleMenu -> recursion(allMenus, routes, roleMenu));
-		routes.sort(Comparator.comparing(Menu::getSort));
-		MenuWrapper menuWrapper = new MenuWrapper();
-		List<Menu> collect = routes.stream().filter(x -> Func.equals(x.getCategory(), 1)).collect(Collectors.toList());
-		return menuWrapper.listNodeVO(collect);
-	}
-
-	private void recursion(List<Menu> allMenus, List<Menu> routes, Menu roleMenu) {
-		Optional<Menu> menu = allMenus.stream().filter(x -> Func.equals(x.getId(), roleMenu.getParentId())).findFirst();
-		if (menu.isPresent() && !routes.contains(menu.get())) {
-			routes.add(menu.get());
-			recursion(allMenus, routes, menu.get());
-		}
-	}
-
-
-	@Override
-	public List<MenuVO> buttons(String roleId,String clientId) {
-		List<Menu> buttons = (AuthUtil.isAdministrator()) ? baseMapper.allButtons(clientId) : baseMapper.buttonsByClientId(Func.toLongList(roleId),clientId);
-		MenuWrapper menuWrapper = new MenuWrapper();
-		return menuWrapper.listNodeVO(buttons);
-	}
-
-	@Override
-	public List<TreeNode> tree() {
-		return ForestNodeMerger.merge(baseMapper.tree());
-	}
-
-	@Override
-	public List<TreeNode> grantTree(BladeUser user) {
-		List<TreeNode> menuTree = user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantTree() : baseMapper.grantTreeByRole(Func.toLongList(user.getRoleId()));
-		return ForestNodeMerger.merge(tenantPackageTree(menuTree, user.getTenantId()));
-	}
-
-	@Override
-	public List<TreeNode> grantTopTree(BladeUser user) {
-		List<TreeNode> menuTree = user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantTopTree() : baseMapper.grantTopTreeByRole(Func.toLongList(user.getRoleId()));
-		return ForestNodeMerger.merge(tenantPackageTree(menuTree, user.getTenantId()));
-	}
-
-	/**
-	 * 租户菜单权限自定义筛选
-	 */
-	private List<TreeNode> tenantPackageTree(List<TreeNode> menuTree, String tenantId) {
-		TenantPackage tenantPackage = SysCache.getTenantPackage(tenantId);
-		if (!AuthUtil.isAdministrator() && Func.isNotEmpty(tenantPackage) && tenantPackage.getId() > 0L) {
-			List<Long> menuIds = Func.toLongList(tenantPackage.getMenuId());
-			menuTree = menuTree.stream().filter(x -> menuIds.contains(x.getId())).collect(Collectors.toList());
-		}
-		return menuTree;
-	}
-
-	/**
-	 * 租户菜单权限自定义筛选
-	 */
-	private List<Menu> tenantPackageMenu(List<Menu> menu) {
-		TenantPackage tenantPackage = SysCache.getTenantPackage(AuthUtil.getTenantId());
-		if (Func.isNotEmpty(tenantPackage) && tenantPackage.getId() > 0L) {
-			List<Long> menuIds = Func.toLongList(tenantPackage.getMenuId());
-			menu = menu.stream().filter(x -> menuIds.contains(x.getId())).collect(Collectors.toList());
-		}
-		return menu;
-	}
-
-	@Override
-	public List<TreeNode> grantDataScopeTree(BladeUser user) {
-		return ForestNodeMerger.merge(user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantDataScopeTree() : baseMapper.grantDataScopeTreeByRole(Func.toLongList(user.getRoleId())));
-	}
-
-	@Override
-	public List<TreeNode> grantApiScopeTree(BladeUser user) {
-		return ForestNodeMerger.merge(user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantApiScopeTree() : baseMapper.grantApiScopeTreeByRole(Func.toLongList(user.getRoleId())));
-	}
-
-	@Override
-	public List<String> roleTreeKeys(String roleIds) {
-		List<RoleMenu> roleMenus = roleMenuService.list(Wrappers.<RoleMenu>query().lambda().in(RoleMenu::getRoleId, Func.toLongList(roleIds)));
-		return roleMenus.stream().map(roleMenu -> Func.toStr(roleMenu.getMenuId())).collect(Collectors.toList());
-	}
-
-	@Override
-	public List<String> topTreeKeys(String topMenuIds) {
-		List<TopMenuSetting> settings = topMenuSettingService.list(Wrappers.<TopMenuSetting>query().lambda().in(TopMenuSetting::getTopMenuId, Func.toLongList(topMenuIds)));
-		return settings.stream().map(setting -> Func.toStr(setting.getMenuId())).collect(Collectors.toList());
-	}
-
-	@Override
-	public List<String> dataScopeTreeKeys(String roleIds) {
-		List<RoleScope> roleScopes = roleScopeService.list(Wrappers.<RoleScope>query().lambda().eq(RoleScope::getScopeCategory, DATA_SCOPE_CATEGORY).in(RoleScope::getRoleId, Func.toLongList(roleIds)));
-		return roleScopes.stream().map(roleScope -> Func.toStr(roleScope.getScopeId())).collect(Collectors.toList());
-	}
-
-	@Override
-	public List<String> apiScopeTreeKeys(String roleIds) {
-		List<RoleScope> roleScopes = roleScopeService.list(Wrappers.<RoleScope>query().lambda().eq(RoleScope::getScopeCategory, API_SCOPE_CATEGORY).in(RoleScope::getRoleId, Func.toLongList(roleIds)));
-		return roleScopes.stream().map(roleScope -> Func.toStr(roleScope.getScopeId())).collect(Collectors.toList());
-	}
-
-	@Override
-	@Cacheable(cacheNames = MENU_CACHE, key = "'auth:routes:' + #user.roleId")
-	public List<Kv> authRoutes(BladeUser user) {
-		List<MenuDTO> routes = baseMapper.authRoutes(Func.toLongList(user.getRoleId()));
-		List<Kv> list = new ArrayList<>();
-		routes.forEach(route -> list.add(Kv.create().set(route.getPath(), Kv.create().set("authority", Func.toStrArray(route.getAlias())))));
-		return list;
-	}
-
-	@Override
-	public boolean removeMenu(String ids) {
-		Long cnt = baseMapper.selectCount(Wrappers.<Menu>query().lambda().in(Menu::getParentId, Func.toLongList(ids)));
-		if (cnt > 0L) {
-			throw new ServiceException("请先删除子节点!");
-		}
-		return removeByIds(Func.toLongList(ids));
-	}
-
-	@Override
-	public boolean submit(Menu menu) {
-		LambdaQueryWrapper<Menu> menuQueryWrapper = Wrappers.lambdaQuery();
-		if (menu.getId() == null) {
-			menuQueryWrapper.eq(Menu::getCode, menu.getCode()).or(
-				wrapper -> wrapper.eq(Menu::getName, menu.getName()).eq(Menu::getCategory, MENU_CATEGORY)
-			);
-		} else {
-			menuQueryWrapper.ne(Menu::getId, menu.getId()).and(
-				wrapper -> wrapper.eq(Menu::getCode, menu.getCode()).or(
-					o -> o.eq(Menu::getName, menu.getName()).eq(Menu::getCategory, MENU_CATEGORY)
-				)
-			);
-		}
-		Long cnt = baseMapper.selectCount(menuQueryWrapper);
-		if (cnt > 0L) {
-			throw new ServiceException("菜单名或编号已存在!");
-		}
-		if (menu.getParentId() == null && menu.getId() == null) {
-			menu.setParentId(BladeConstant.TOP_PARENT_ID);
-		}
-		if (menu.getParentId() != null && menu.getId() == null) {
-			Menu parentMenu = baseMapper.selectById(menu.getParentId());
-			if (parentMenu != null && parentMenu.getCategory() != 1) {
-				throw new ServiceException("父节点只可选择菜单类型!");
-			}
-		}
-		menu.setIsDeleted(BladeConstant.DB_NOT_DELETED);
-		return saveOrUpdate(menu);
-	}
+    private final IRoleMenuService roleMenuService;
+    private final IRoleScopeService roleScopeService;
+    private final ITopMenuSettingService topMenuSettingService;
+    private final static String PARENT_ID = "parentId";
+    private final static Integer MENU_CATEGORY = 1;
+
+    @Override
+    public List<MenuVO> lazyList(Long parentId, Map<String, Object> param) {
+        if (Func.isEmpty(Func.toStr(param.get(PARENT_ID)))) {
+            parentId = null;
+        }
+        List<MenuVO> lazyList = baseMapper.lazyList(parentId, param);
+        return lazyList;
+
+    }
+
+    @Override
+    public List<MenuVO> lazyMenuList(Long parentId, Map<String, Object> param) {
+        if (Func.isEmpty(Func.toStr(param.get(PARENT_ID)))) {
+            parentId = null;
+        }
+        return baseMapper.lazyMenuList(parentId, param);
+    }
+
+
+    @Override
+    public List<MenuVO> routes(String roleId, Long topMenuId, String sysType) {
+        if (StringUtil.isBlank(roleId)) {
+            return null;
+        }
+
+        //根据类型获取对应菜单
+        List<Menu> allMenusList = baseMapper.allMenuBySysType(sysType);
+
+        //获取该角色与菜单关系信息
+        List<RoleAndMenusVO> resultList = baseMapper.allRoleAndMenu(roleId);
+
+        //获取对应权限的菜单List
+        List<Menu> allMenus = allMenusList.stream().filter(f -> resultList.stream().map(RoleAndMenusVO::getMenuId).collect(Collectors.toList()).contains(f.getId())).collect(Collectors.toList());
+
+        List<Menu> roleMenus;
+        // 超级管理员并且不是顶部菜单请求则返回全部菜单
+        if (AuthUtil.isAdministrator() && Func.isEmpty(topMenuId)) {
+            roleMenus = allMenus;
+        }
+        // 非超级管理员并且不是顶部菜单请求则返回对应角色权限菜单
+        else if (!AuthUtil.isAdministrator() && Func.isEmpty(topMenuId)) {
+            roleMenus = tenantPackageMenu(baseMapper.roleMenuByRoleId(Func.toLongList(roleId)));
+        }
+        // 顶部菜单请求返回对应角色权限菜单
+        else {
+            // 角色配置对应菜单
+            List<Menu> roleIdMenus = baseMapper.roleMenuByRoleId(Func.toLongList(roleId));
+            // 反向递归角色菜单所有父级
+            List<Menu> routes = new LinkedList<>(roleIdMenus);
+            roleIdMenus.forEach(roleMenu -> recursion(allMenus, routes, roleMenu));
+            // 顶部配置对应菜单
+            List<Menu> topIdMenus = baseMapper.roleMenuByTopMenuId(topMenuId);
+            // 筛选匹配角色对应的权限菜单
+            roleMenus = topIdMenus.stream().filter(x ->
+                    routes.stream().anyMatch(route -> route.getId().longValue() == x.getId().longValue())
+            ).collect(Collectors.toList());
+        }
+        return buildRoutes(allMenus, roleMenus);
+    }
+
+    private List<MenuVO> buildRoutes(List<Menu> allMenus, List<Menu> roleMenus) {
+        List<Menu> routes = new LinkedList<>(roleMenus);
+        roleMenus.forEach(roleMenu -> recursion(allMenus, routes, roleMenu));
+        routes.sort(Comparator.comparing(Menu::getSort));
+        MenuWrapper menuWrapper = new MenuWrapper();
+        List<Menu> collect = routes.stream().filter(x -> Func.equals(x.getCategory(), 1)).collect(Collectors.toList());
+        return menuWrapper.listNodeVO(collect);
+    }
+
+    private void recursion(List<Menu> allMenus, List<Menu> routes, Menu roleMenu) {
+        Optional<Menu> menu = allMenus.stream().filter(x -> Func.equals(x.getId(), roleMenu.getParentId())).findFirst();
+        if (menu.isPresent() && !routes.contains(menu.get())) {
+            routes.add(menu.get());
+            recursion(allMenus, routes, menu.get());
+        }
+    }
+
+
+    @Override
+    public List<MenuVO> buttons(String roleId, String clientId) {
+        List<Menu> buttons = (AuthUtil.isAdministrator()) ? baseMapper.allButtons(clientId) : baseMapper.buttonsByClientId(Func.toLongList(roleId), clientId);
+        MenuWrapper menuWrapper = new MenuWrapper();
+        return menuWrapper.listNodeVO(buttons);
+    }
+
+    @Override
+    public List<TreeNode> tree() {
+        return ForestNodeMerger.merge(baseMapper.tree());
+    }
+
+    @Override
+    public List<TreeNodeVO> grantTree(BladeUser user) {
+        List<TreeNodeVO> menuTree = user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantTree() : baseMapper.grantTreeByRole(Func.toLongList(user.getRoleId()));
+        return ForestNodeMerger.merge(tenantPackageTree2(menuTree, user.getTenantId()));
+    }
+
+    @Override
+    public List<TreeNodeVO> grantTopTree(BladeUser user) {
+        List<TreeNodeVO> menuTree = user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantTopTree() : baseMapper.grantTopTreeByRole(Func.toLongList(user.getRoleId()));
+        return ForestNodeMerger.merge(tenantPackageTree2(menuTree, user.getTenantId()));
+    }
+
+    /**
+     * 租户菜单权限自定义筛选
+     */
+    private List<TreeNode> tenantPackageTree(List<TreeNode> menuTree, String tenantId) {
+        TenantPackage tenantPackage = SysCache.getTenantPackage(tenantId);
+        if (!AuthUtil.isAdministrator() && Func.isNotEmpty(tenantPackage) && tenantPackage.getId() > 0L) {
+            List<Long> menuIds = Func.toLongList(tenantPackage.getMenuId());
+            menuTree = menuTree.stream().filter(x -> menuIds.contains(x.getId())).collect(Collectors.toList());
+        }
+        return menuTree;
+    }
+
+    private List<TreeNodeVO> tenantPackageTree2(List<TreeNodeVO> menuTree, String tenantId) {
+        TenantPackage tenantPackage = SysCache.getTenantPackage(tenantId);
+        if (!AuthUtil.isAdministrator() && Func.isNotEmpty(tenantPackage) && tenantPackage.getId() > 0L) {
+            List<Long> menuIds = Func.toLongList(tenantPackage.getMenuId());
+            menuTree = menuTree.stream().filter(x -> menuIds.contains(x.getId())).collect(Collectors.toList());
+        }
+        return menuTree;
+    }
+
+    /**
+     * 租户菜单权限自定义筛选
+     */
+    private List<Menu> tenantPackageMenu(List<Menu> menu) {
+        TenantPackage tenantPackage = SysCache.getTenantPackage(AuthUtil.getTenantId());
+        if (Func.isNotEmpty(tenantPackage) && tenantPackage.getId() > 0L) {
+            List<Long> menuIds = Func.toLongList(tenantPackage.getMenuId());
+            menu = menu.stream().filter(x -> menuIds.contains(x.getId())).collect(Collectors.toList());
+        }
+        return menu;
+    }
+
+    @Override
+    public List<TreeNodeVO> grantDataScopeTree(BladeUser user) {
+        return ForestNodeMerger.merge(user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantDataScopeTree() : baseMapper.grantDataScopeTreeByRole(Func.toLongList(user.getRoleId())));
+    }
+
+    @Override
+    public List<TreeNodeVO> grantApiScopeTree(BladeUser user) {
+        return ForestNodeMerger.merge(user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantApiScopeTree() : baseMapper.grantApiScopeTreeByRole(Func.toLongList(user.getRoleId())));
+    }
+
+    @Override
+    public List<String> roleTreeKeys(String roleIds) {
+        List<RoleMenu> roleMenus = roleMenuService.list(Wrappers.<RoleMenu>query().lambda().in(RoleMenu::getRoleId, Func.toLongList(roleIds)));
+        return roleMenus.stream().map(roleMenu -> Func.toStr(roleMenu.getMenuId())).collect(Collectors.toList());
+    }
+
+    @Override
+    public List<String> topTreeKeys(String topMenuIds) {
+        List<TopMenuSetting> settings = topMenuSettingService.list(Wrappers.<TopMenuSetting>query().lambda().in(TopMenuSetting::getTopMenuId, Func.toLongList(topMenuIds)));
+        return settings.stream().map(setting -> Func.toStr(setting.getMenuId())).collect(Collectors.toList());
+    }
+
+    @Override
+    public List<String> dataScopeTreeKeys(String roleIds) {
+        List<RoleScope> roleScopes = roleScopeService.list(Wrappers.<RoleScope>query().lambda().eq(RoleScope::getScopeCategory, DATA_SCOPE_CATEGORY).in(RoleScope::getRoleId, Func.toLongList(roleIds)));
+        return roleScopes.stream().map(roleScope -> Func.toStr(roleScope.getScopeId())).collect(Collectors.toList());
+    }
+
+    @Override
+    public List<String> apiScopeTreeKeys(String roleIds) {
+        List<RoleScope> roleScopes = roleScopeService.list(Wrappers.<RoleScope>query().lambda().eq(RoleScope::getScopeCategory, API_SCOPE_CATEGORY).in(RoleScope::getRoleId, Func.toLongList(roleIds)));
+        return roleScopes.stream().map(roleScope -> Func.toStr(roleScope.getScopeId())).collect(Collectors.toList());
+    }
+
+    @Override
+    @Cacheable(cacheNames = MENU_CACHE, key = "'auth:routes:' + #user.roleId")
+    public List<Kv> authRoutes(BladeUser user) {
+        List<MenuDTO> routes = baseMapper.authRoutes(Func.toLongList(user.getRoleId()));
+        List<Kv> list = new ArrayList<>();
+        routes.forEach(route -> list.add(Kv.create().set(route.getPath(), Kv.create().set("authority", Func.toStrArray(route.getAlias())))));
+        return list;
+    }
+
+    @Override
+    public boolean removeMenu(String ids) {
+        Long cnt = baseMapper.selectCount(Wrappers.<Menu>query().lambda().in(Menu::getParentId, Func.toLongList(ids)));
+        if (cnt > 0L) {
+            throw new ServiceException("请先删除子节点!");
+        }
+        return removeByIds(Func.toLongList(ids));
+    }
+
+    @Override
+    public boolean submit(Menu menu) {
+        LambdaQueryWrapper<Menu> menuQueryWrapper = Wrappers.lambdaQuery();
+        if (menu.getId() == null) {
+            menuQueryWrapper.eq(Menu::getCode, menu.getCode()).or(
+                    wrapper -> wrapper.eq(Menu::getName, menu.getName()).eq(Menu::getCategory, MENU_CATEGORY)
+            );
+        } else {
+            menuQueryWrapper.ne(Menu::getId, menu.getId()).and(
+                    wrapper -> wrapper.eq(Menu::getCode, menu.getCode()).or(
+                            o -> o.eq(Menu::getName, menu.getName()).eq(Menu::getCategory, MENU_CATEGORY)
+                    )
+            );
+        }
+        Long cnt = baseMapper.selectCount(menuQueryWrapper);
+        if (cnt > 0L) {
+            throw new ServiceException("菜单名或编号已存在!");
+        }
+        if (menu.getParentId() == null && menu.getId() == null) {
+            menu.setParentId(BladeConstant.TOP_PARENT_ID);
+        }
+        if (menu.getParentId() != null && menu.getId() == null) {
+            Menu parentMenu = baseMapper.selectById(menu.getParentId());
+            if (parentMenu != null && parentMenu.getCategory() != 1) {
+                throw new ServiceException("父节点只可选择菜单类型!");
+            }
+        }
+        menu.setIsDeleted(BladeConstant.DB_NOT_DELETED);
+        return saveOrUpdate(menu);
+    }
+
+    @Override
+    public List<AuthClient> getSysId() {
+        return baseMapper.selectBySysId();
+    }
 
 }