若依框架-部门树状图

 若依部门树状图的实现

95bc123b094a46978a4cd198e45a159c.png

1、数据库表 

0073025d22e24184aee75caa9589e111.png

 2、具体的实现代码

先找到这个接口

    /**
     * 查询部门树结构信息
     * 
     * @param dept 部门信息
     * @return 部门树信息集合
     */
    public List<TreeSelect> selectDeptTreeList(SysDept dept);

然后我们进入他具体的实现类,如下代码

    /**
     * 查询部门树结构信息
     * 
     * @param dept 部门信息
     * @return 部门树信息集合
     */
    @Override
    public List<TreeSelect> selectDeptTreeList(SysDept dept)
    {
        List<SysDept> depts = SpringUtils.getAopProxy(this).selectDeptList(dept);
        return buildDeptTreeSelect(depts);
    }

框选的代码它是去查询了所有的部门信息然后存进去一个list里面

63d7f466a5be451fbd6dba8a8bef6465.png

进入maaper层查询,就可以查询到所有的部门信息

<select id="selectDeptList" parameterType="SysDept" resultMap="SysDeptResult">
        <include refid="selectDeptVo"/>
        where d.del_flag = '0'
		<if test="deptId != null and deptId != 0">
			AND dept_id = #{deptId}
		</if>
        <if test="parentId != null and parentId != 0">
			AND parent_id = #{parentId}
		</if>
		<if test="deptName != null and deptName != ''">
			AND dept_name like concat('%', #{deptName}, '%')
		</if>
		<if test="status != null and status != ''">
			AND status = #{status}
		</if>
		<!-- 数据范围过滤 -->
		${params.dataScope}
		order by d.parent_id, d.order_num
    </select>

就可以获取到所有的部门信息,然后去构建树结构d20e5b893033414698fa858123be1d05.png

进入上图框选的buildDeptTreeSelect方法里面,在进入buildDeptTree方法里查看树的构建,它参数传的是我们刚才查询的所有部门的信息

6eb8d3bc1dc64a798e3a8bfb6b190c97.png

    /**
     * 构建前端所需要下拉树结构
     * 
     * @param depts 部门列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts)
    {
        List<SysDept> deptTrees = buildDeptTree(depts);
        return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

 进入我们可以看到构建前端树结构的方法,首先它把所有部门里面的部门编号遍历出来存入一个tempList的集合里面,然后去遍历我们刚才传进来部门信息,它去获取了tempList集合里面的部门编号是否包含了部门集合(depts 传进来的参数集合)的父节点编号,如果不包含的话,那他肯定是顶级节点,那就遍历该父节点的所有子节点

e12a5a7b61234a0bb7091d16eab82841.png

    /**
     * 构建前端所需要树结构
     * 
     * @param depts 部门列表
     * @return 树结构列表
     */
    @Override
    public List<SysDept> buildDeptTree(List<SysDept> depts)
    {
        List<SysDept> returnList = new ArrayList<SysDept>();
        List<Long> tempList = depts.stream().map(SysDept::getDeptId).collect(Collectors.toList());
        for (SysDept dept : depts)
        {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId()))
            {
                recursionFn(depts, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = depts;
        }
        return returnList;
    }

 我们进入recursionFn方法里面,参数传的是部门的集合和部门

f8649968a23643df9fb78e24fefa946e.png

 recursionFn方法如下,我们可以看到它是用递归的方法去实现的

     /**
     * 递归列表
     */
    private void recursionFn(List<SysDept> list, SysDept t)
    {
        // 得到子节点列表
        List<SysDept> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysDept tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                recursionFn(list, tChild);
            }
        }
    }

我们先进去getChildList方法里去查看,如下,主要代码为下面红色框框选的代码,它是用迭代器去遍历这个集合,一直去获取下个节点,条件是当它的父节点和子节点相等的情况下,把这个部门加进去部门对象的子部门里面,也就是集合tlist,一直找直到没有然后退出循环

8fffd0d55ea0444b9bb8185052f2c826.png

    /**
     * 得到子节点列表
     */
    private List<SysDept> getChildList(List<SysDept> list, SysDept t)
    {
        List<SysDept> tlist = new ArrayList<SysDept>();
        Iterator<SysDept> it = list.iterator();
        while (it.hasNext())
        {
            SysDept n = (SysDept) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().longValue() == t.getDeptId().longValue())
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

返回回去一个子节点列表的集合,到下图方法这里,然后把它刚才子节点列表的集合set进去部门里面,再去遍历它的子节点

cce355c0c8e445bb818c1062346baea1.png

用hasChild方法再去做判断,跟进去方法看一下,如下,它又去调用了我们刚才的那个getChildList的方法去找有没有子节点的列表,如果有那他的集合就是大于0,也就是返回true,到我们的recursionFn的方法中,然后是true的话它又会去再次调用recursionFn这个方法,把子节点的集合传进去,实现了递归,这样就能把所有的部门信息查出来,然后实现树状结构

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SysDept> list, SysDept t)
    {
        return getChildList(list, t).size() > 0;
    }

 最后,在遍历放进去 TreeSelect里面,返回给前端就实现了这个功能

b52eaa6e84d447ff804da79d343b5f95.png

可以看到他用stream流,存进去这个树结构的实体类里面,在这里面看到下面这个构造函数,id是的等于部门的id,label节点名称等于部门的部门名字,孩子节点就再去用stream流存进去这个属结构里面

/**
 * Treeselect树结构实体类
 * 
 * @author ruoyi
 */
public class TreeSelect implements Serializable
{
    private static final long serialVersionUID = 1L;

    /** 节点ID */
    private Long id;

    /** 节点名称 */
    private String label;

    /** 子节点 */
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private List<TreeSelect> children;

    public TreeSelect(SysDept dept)
    {
        this.id = dept.getDeptId();
        this.label = dept.getDeptName();
        this.children=dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
    }

总结

1、先查询除所有的部门放在一个集合List里面,再去new一个returnList存放顶级部门数据

2、再拿一个tempList取出集合里面所有部门的ID

3、遍历这个所有部门的集合,遍历的过程中判断每个部门的父节点有没有包含tempList的部门ID

        3.1.如果没有包含的话,那这个部门就肯定是顶级节点,就应该去遍历该顶级节点下的所有节点

                3.1.1.先获取该节点下的子节点列表,先new除一个tlist去存放子节点的数据,然后用迭代器Iterator去遍历传进来的list集合,如果这个部门对象的父节点不为空并且它父节点的id等于这个部门的id,那这个部门就是这个传进来部门的子部门,把他存进去list里面,在返回存放子节点的list

                3.1.2.在把返回的子节点的list存进去这个部门对象的children孩子属性里面

                3.1.3.再去遍历这个返回的子节点列表,判断他有没有孩子,判断的步骤里面其实还是再去执行了一次getChildList这个方法,去判断返回来的孩子节点的size有没有大于0,大于0肯定就是有孩子,就再去递归recursionFn这个方法,以此类推

        3.2.如果有包含的话,那就不用做处理

4.再去判断这个returnList是不是为空

        4.1.如果为空的话,那就直接就是传进来的部门数据

        4.2.如果不为空的话直接把returnList返回出去就好了

5、最后用stream流把对象变成树结构返回出去就可以了

  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
JooLun微信管理平台是一个 Java EE 企业级微信快速开发平台,基于经典技术组合(Spring Boot、Spring Security、MyBatis、Jwt、Vue),内置模块如:公众号管理、部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、代码生成等。在线定时任务配置;支持集群,支持多数据源。 在RuoYi-Vue基础上集成了MybatisPlus和Avue,微信接口统一使用了WxJava SDK。 系统需求: JDK >= 1.8 MySQL >= 5.8 Maven >= 3.0 内置功能: 1、公众号用户标签管理 2、公众号用户管理 3、公众号用户消息管理 4、公众号素材管理 5、公众号自定义菜单管理 6、公众号消息自动回复管理 7、公众号营销数据统计 8、用户管理:用户是系统操作者,该功能主要完成系统用户配置。 9、部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。 10、岗位管理:配置系统用户所属担任职务。 11、菜单管理:配置系统菜单,操作权限,按钮权限标识等。 12、角色管理:角色菜单权限分配、设置角色按机构进行数据范围权限划分。 13、字典管理:对系统中经常使用的一些较为固定的数据进行维护。 14、参数管理:对系统动态配置常用参数。 15、通知公告:系统通知公告信息发布维护。 16、操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 17、登录日志:系统登录日志记录查询包含登录异常。 18、在线用户:当前系统中活跃用户状态监控。 19、定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 20、代码生成:前后端代码的生成(java、html、xml、sql)支持CRUD下载 。 21、系统接口:根据业务代码自动生成相关的api接口文档。 22、服务监控:监视当前系统CPU、内存、磁盘、堆栈等相关信息。 23、在线构建器:拖动表单元素生成相应的HTML代码。 24、连接池监视:监视当前系统数据库连

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小小王w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值