关键代码
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);
}