使用Map生成权限树形菜单, 避免递归

关键代码

       List<SysMenu> menus = sysMenuRepository.findAuthUserMenuTree(userId);//查询用户所有菜单

        Map<Integer, SysMenu> map = new HashMap<>();
        menus.forEach(e -> map.put(e.getMenuId(), e));//将菜单放入map,菜单ID作为key,对象作为value

        map.forEach((key, value)->{
			if(value.getParentId() != null){//判断父节点是否为空
				if (map.get(value.getParentId()) != null){
					ArrayList<SysMenu> children = (ArrayList<SysMenu>)map.get(value.getParentId()).getChildren();//获取子节点
					if(children == null){//如果子节点为空,new一个
						children = new ArrayList<>();
						map.get(value.getParentId()).setChildren(children);//把子节点放到父节点下面
					}
					children.add(value);
					//需要复写compareTo
					Collections.sort(children);//排序
				}
			}
		});
		List<SysMenu> combineMenus = map.values().stream().filter(e -> e.getParentId() == null).sorted().collect(Collectors.toList());//父节点排序

表设计

CREATE TABLE `sys_menu` (
  `menu_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '菜单id',
  `name` varchar(50) DEFAULT NULL COMMENT '菜单名称',
  `url` varchar(100) DEFAULT NULL COMMENT '菜单url',
  `parent_id` int(11) DEFAULT NULL COMMENT '父级菜单id',
  `type` tinyint(4) DEFAULT NULL COMMENT '0:菜单 1:按钮',
  `icon` varchar(100) DEFAULT NULL COMMENT '菜单图标',
  `order_num` tinyint(4) DEFAULT NULL COMMENT '排序',
  `menu_level` tinyint(4) DEFAULT NULL,
  `menu_code` varchar(20) DEFAULT NULL COMMENT '菜单编码',
  PRIMARY KEY (`menu_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1266 DEFAULT CHARSET=utf8mb4;

实体

@Data
@Entity
@Table(name = "sys_menu", catalog = "xxx")
public class SysMenu implements Serializable,Comparable<SysMenu>{
    private static final long serialVersionUID = 6374660580699037343L;
    @Id
    @Column(name = "menu_id")
    private Integer menuId;
    @Column(name = "menu_code")
    private String menuCode;
    @Column(name = "name")
    private String name;
    @Column(name = "url")
    private String url;
    @Column(name = "parent_id")
    private Integer parentId;
    @Column(name = "type")
    private Byte type;
    @Column(name = "icon")
    private String icon;
    @Column(name = "order_num")
    private Byte orderNum;
    @Column(name = "menu_level")
    private Byte menuLevel;

    @Transient
    private Collection<SysMenu> children;

	@Override
	public int compareTo(SysMenu sysMenu) {
		return this.orderNum.compareTo(sysMenu.orderNum);
	}
}

查询菜单SQL

@Query(nativeQuery = true,value = "select sm.* from sys_menu sm " +
            "left join sys_role_menu_mapping srm on sm.menu_id = srm.menu_id " +
            "left join sys_user_role sur on srm.role_id = sur.id " +
            "left join sys_user_role_mapping urm on sur.id = urm.role_id " +
            "where urm.user_id = :userId and sur.status = 1 " +
            "group by sm.menu_id,sur.id")
    List<SysMenu> findAuthUserMenuTree(@Param("userId")Long userId);

树形结构组装

    @RequestMapping("/tree")
    public String authMenus(HttpServletRequest request){
        Long userId = 1L;
        List<SysMenu> menus = sysMenuRepository.findAuthUserMenuTree(userId);//查询用户所有菜单

        Map<Integer, SysMenu> map = new HashMap<>();
        menus.forEach(e -> map.put(e.getMenuId(), e));//将菜单放入map,菜单ID作为key,对象作为value

        map.forEach((key, value)->{
			if(value.getParentId() != null){//判断父节点是否为空
				if (map.get(value.getParentId()) != null){
					ArrayList<SysMenu> children = (ArrayList<SysMenu>)map.get(value.getParentId()).getChildren();//获取子节点
					if(children == null){//如果子节点为空,new一个
						children = new ArrayList<>();
						map.get(value.getParentId()).setChildren(children);//把子节点放到父节点下面
					}
					children.add(value);
					//需要复写compareTo
					Collections.sort(children);//子节点排序
				}
			}
		});
		List<SysMenu> combineMenus = map.values().stream().filter(e -> e.getParentId() == null).sorted().collect(Collectors.toList());//父节点排序
        Map<String, Object> result = new HashMap<>(1);
        result.put("authMenus", combineMenus);
        return JSON.toJSONString(result);
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值