一、生成樹形結構
1、TreeUtil
傳入一個list集合,根據父ID(pid)來判斷是否有子節點,返回一個List類型
public class TreeUtil { private List<PermissionVo> menuCommon; /** * service層調用的方法,並將數據以list的形式返回 * * @param menu 菜單集合 * @return list */ public List<Object> menuList(List<PermissionVo> menu) { this.menuCommon = menu; List<Object> list = new ArrayList<>(); for (PermissionVo ps : menu) { Map<String, Object> map = new LinkedHashMap<>(); //判斷根節點是否是0 if (ps.getPid().equals(0)) { setTreeData(map, ps); list.add(map); } } return list; } /** * 不判斷根節點遍歷 * * @param pList * @return */ public List<Object> userMenuList(List<PermissionVo> pList) { this.menuCommon = pList; List<Object> list = new ArrayList<>(); for (PermissionVo ps : pList) { Map<String, Object> map = new LinkedHashMap<>(); setTreeData(map, ps); list.add(map); } return list; } /** * 子集查找遍歷 * 遞歸遍歷,直到沒有子節點為止 * * @param id 父id * @return list */ private List<Object> menuChild(Integer id) { List<Object> list = new ArrayList<>(); for (PermissionVo ps : menuCommon) { Map<String, Object> map = new LinkedHashMap<>(); if (ps.getPid().equals(id)) { setTreeData(map, ps); list.add(map); } } return list; } /** * 賦值 * id 當前id * title 標題 * field 權限值 * href 跳轉路徑 * children 子節點數據 */ private void setTreeData(Map<String, Object> map, PermissionVo ps) { map.put("id", ps.getId()); map.put("title", ps.getName()); map.put("field", ps.getValue()); map.put("href", ps.getUri()); map.put("children", menuChild(ps.getId())); } }
2、service層調用
從數據庫查詢一個list集合,調用TreeUtil工具類
@Override public Map<String, Object> findMenuTree(Integer type) { Map<String, Object> map = new HashMap<>(); //查詢所有菜單 List<Permission> lists = new LambdaQueryChainWrapper<>(permissionMapper) .eq(Permission::getType, 0) .or() .eq(Permission::getType, type) .list(); TreeUtil menuTree = new TreeUtil(); List<PermissionVo> pList = new ArrayList<>(); //遍歷賦值,拷貝 setPmsData(lists, pList); List<Object> menuList = menuTree.menuList(pList); map.put("list", menuList); return map; }
/** * 賦值 * @param list * @param pList */ private void setPmsData(List<Permission> list, List<PermissionVo> pList) { for (Permission p : list) { PermissionVo t = new PermissionVo(); t.setId(p.getId()); t.setName(p.getName()); t.setValue(p.getValue()); t.setUri(p.getUri()); t.setPid(p.getPid()); pList.add(t); } }
3、controller層返回
/** * 菜單生成樹 */ @PreAuthorize("hasAuthority('method:pms:read')") @GetMapping("/findMenuTree") public CommonResult findMenuTree(Integer type) { Map<String, Object> map = permissionService.findMenuTree(type); return CommonResult.success(map); }
4、permission
permissionVo和permission字段差不多
@Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = false) public class Permission implements GrantedAuthority { private static final long serialVersionUID = 1L; /** * id */ @TableId(value = "id", type = IdType.AUTO) private Integer id; /** * 權限編號 */ private String code; /** * 父id 0根節點 */ private Integer pid; /** * 權限名 */ private String name; /** * 權限值 */ private String value; /** * 類型 1菜單 2方法 */ private Integer type; /** * 方法路徑 */ private String uri; /** * 創建時間 */ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date createTime; /** * 是否可用 */ private String dataEnable; @Override public String getAuthority() { return this.value; }
二、解析樹形結構
1、TreeVo
@Data @AllArgsConstructor @NoArgsConstructor public class TreeVo implements Serializable { /** * id */ private Integer id; /** * 標題 */ private String title; /** * 權限值 */ private String field; /** * 跳轉路徑 */ private String href; /** * 子節點 */ private List<TreeVo> children; }
2、controller接收數據
/** * 分配菜單權限 */ @PreAuthorize("hasAuthority('method:pms:create')") @PostMapping("/getMenuTreeData") public CommonResult getMenuTreeData(@RequestBody List<TreeVo> treeVo, @RequestParam String roleCode, @RequestParam Integer type) { return permissionService.getMenuTreeData(treeVo, roleCode, type); }
3、service層解析樹形結構數據
@Override public CommonResult getMenuTreeData(List<TreeVo> treeVo, String roleCode, Integer type) { //獲取樹節點Id List<Integer> pmsIds = new ArrayList<>(); for (TreeVo t : treeVo) { pmsIds.add(t.getId()); getChildrenId(t, pmsIds); } } /** * 遞歸遍歷 直到沒有子節點為止 * * @param t TreeVo * @param pmsIds list */ private void getChildrenId(TreeVo t, List<Integer> pmsIds) { for (TreeVo tr : t.getChildren()) { pmsIds.add(tr.getId()); getChildrenId(tr, pmsIds); } }