03【若依框架解读】Tree树形结构的控制(菜单,部门)

朴灿烈づ我的快乐病毒、 2022-12-27 01:24 1812阅读 0赞

背景

若依管理框架中包含了不少菜单树和权限树的控制,主要实现的方式是递归,比较容易阅读和理解。构建属性结构本身是开发中非常常见的场景。掌握后非常容易在工作中使用。

属性结构控制

  1. 后端返回列表,前端控制
  2. 后端直接返回

处理方法

1. 根据角色获取部门

接口:/roleDeptTreeselect/{roleId}

查询角色具有的部门权限
deptCheckStrictly模式下只查询子菜单

  1. <select id="selectDeptListByRoleId" resultType="Integer">
  2. select d.dept_id
  3. from sys_dept d
  4. left join sys_role_dept rd on d.dept_id = rd.dept_id
  5. where rd.role_id = #{roleId}
  6. <if test="deptCheckStrictly">
  7. and d.dept_id not in (select d.parent_id from sys_dept d inner join sys_role_dept rd on d.dept_id = rd.dept_id and rd.role_id = #{roleId})
  8. </if>
  9. order by d.parent_id, d.order_num
  10. </select>

2. 获取部门下拉树

接口:/system/dept/treeselect

step1 : 获取部门列表

  1. List<SysDept> depts = deptService.selectDeptList(dept);

step2: 构建树形结构(重点)

  1. deptService.buildDeptTreeSelect(depts)

生成树形结构

  1. 获取传入部门列表中的顶级部门
  2. 遍历顶级部门获取每个部门的子部门列表

    1. 获取子部门列表
    2. 递归遍历子部门列表,获取每个子部门的子部门列表
    3. 退出条件:当前部门没有子部门

    /**

    1. * 构建前端所需要树结构
    2. *
    3. * @param depts 部门列表
    4. * @return 树结构列表
    5. */
    6. @Override
    7. public List<SysDept> buildDeptTree(List<SysDept> depts)
    8. {
    9. List<SysDept> returnList = new ArrayList<SysDept>();
    10. //保存所有的dept_id
    11. List<Long> tempList = new ArrayList<Long>();
    12. for (SysDept dept : depts)
    13. {
    14. tempList.add(dept.getDeptId());
    15. }
    16. for (Iterator<SysDept> iterator = depts.iterator(); iterator.hasNext();)
    17. {
    18. SysDept dept = (SysDept) iterator.next();
    19. // 如果是顶级节点, 遍历该父节点的所有子节点
    20. <!--// 如果一个部门的父节点不在templist中,说明这个部门在当前数据集中是顶级部门,否则说明该部门是子部门-->
    21. <!--注:不是所有的树都是从root部门,也可能是某个叶子节点遍历的树形结构-->
    22. if (!tempList.contains(dept.getParentId()))
    23. {
    24. recursionFn(depts, dept);
    25. returnList.add(dept);
    26. }
    27. }
    28. if (returnList.isEmpty())
    29. {
    30. returnList = depts;
    31. }
    32. return returnList;
    33. }

递归获取子部门列表树形结构

  1. 获取子部门列表
  2. 递归遍历子部门列表,获取每个子部门的子部门列表
  3. 退出条件:当前部门没有子部门

    /**

    1. * 递归列表
    2. */
    3. private void recursionFn(List<SysDept> list, SysDept t)
    4. {
    5. // 得到子节点列表
    6. List<SysDept> childList = getChildList(list, t);
    7. t.setChildren(childList);
    8. for (SysDept tChild : childList)
    9. {
    10. if (hasChild(list, tChild))
    11. {
    12. recursionFn(list, tChild);
    13. }
    14. }
    15. }

获取子部门

  • 入参:部门列表+部门
  • 输出:查询部门的所有子部门列表

    /**

    1. * 得到子节点列表
    2. */
    3. private List<SysDept> getChildList(List<SysDept> list, SysDept t)
    4. {
    5. List<SysDept> tlist = new ArrayList<SysDept>();
    6. Iterator<SysDept> it = list.iterator();
    7. while (it.hasNext())
    8. {
    9. SysDept n = (SysDept) it.next();
    10. if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue())
    11. {
    12. tlist.add(n);
    13. }
    14. }
    15. return tlist;
    16. }

每个函数只做一件简单的事情

  1. /**
  2. * 判断是否有子节点
  3. */
  4. private boolean hasChild(List<SysDept> list, SysDept t)
  5. {
  6. return getChildList(list, t).size() > 0 ? true : false;
  7. }

最终统一格式

  1. /**
  2. * 构建前端所需要下拉树结构
  3. *
  4. * @param depts 部门列表
  5. * @return 下拉树结构列表
  6. */
  7. @Override
  8. public List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts)
  9. {
  10. List<SysDept> deptTrees = buildDeptTree(depts);
  11. return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
  12. }

发表评论

表情:
评论列表 (有 0 条评论,1812人围观)

还没有评论,来说两句吧...

相关阅读