基于hutool工具类返回树状列表

前言

        做系统的时候,页面有时需要展示树状列表。在前端代码里构造有点麻烦,最好是后端构造好后直接给前端用。Hutool里有个TreeUtil 可以构造树状列表,这里简单记录一下使用。

一、数据库设计

        参考ruoyi项目的部门表设计即可,字段有id,parent_id,ancestors这三个就可以了,其他的可以根据业务酌情添加。

二、构造树状结构

        先查询出集合来,然后使用TreeUtil来构造树状结构

    public List<Tree<Long>> buildCombatTreeSelect(List<SysDept> list) {
        if (CollUtil.isEmpty(list)) {
            return CollUtil.newArrayList();
        }
        return TreeBuildUtils.build(list, 0L, (dept, tree) -> {
                    tree.setId(dept.getId());
                    tree.setParentId(dept.getParentId());
                    tree.setName(dept.getDeptName());
                    tree.setWeight(dept.getOrderNum());
                    tree.putExtra("total", dept.getUserCount());
                });
    }

SysDept中的userCount是每个部门的用户数量,可以查询用户表获得。

三、添加数量

3.1、计算子节点的数量

        有时候需要展示子节点的数量,但是工具类中没有提供相关方法,所以需要我们自己计算

    public List<Tree<Long>> updateTreeChildrenTotal(List<Tree<Long>> treeList) {
        for(Tree<Long> tree : treeList) {
            List<Tree<Long>> children = tree.getChildren();
            if(CollectionUtil.isNotEmpty(children)) {
                long total = 0;
                for(Tree<Long> child : children) {
                    total += MapUtil.getLong(updateTreeCount(Collections.singletonList(child)).get(0), "total");
                }
                tree.putExtra("total", total);
                updateTreeCount(children);
            } else {
                tree.putExtra("total", 0L);
            }
        }
        return treeList;
    }

        如果字节点还区分类型,比如人员和部门,部门只计算子节点下人员的数量,不计算部门。那么在此代码上加上节点类型的判断即可

    public List<Tree<Long>> updateTreeChilderTotal(List<Tree<Long>> treeList) {
        for(Tree<Long> tree : treeList) {
            List<Tree<Long>> children = tree.getChildren();
            if(CollectionUtil.isNotEmpty(children)) {
                long total = 0;
                for(Tree<Long> child : children) {
                    String type = MapUtil.getStr(child, "type");
                    if (StringUtils.equals(type, "person")){
                        total ++;
                    }
                    total += MapUtil.getLong(updateTreeCount(Collections.singletonList(child)).get(0), "total");
                }
                tree.putExtra("total", total);
                updateTreeCount(children);
            } else {
                tree.putExtra("total", 0L);
            }
        }
        return treeList;
    }

3.2、计算子节点下的数据量

        有时候树状结构里需要展示该条目下的数据总量,而不是子节点的数量

    /**
     * 计算父节点的数据量
     *
     * @param treeList 树列表
     */
    public List<Tree<Long>> calculateParentTotal(List<Tree<Long>> treeList) {
        if (CollUtil.isEmpty(treeList)) {
            return treeList;
        }
        for(Tree<Long> node : treeList) {
            calculateNodeTotal(node);
        }
        return treeList;
    }

    /**
     * 计算子节点的数数量
     *
     * @param node 节点
     */
    private void calculateNodeTotal(Tree<Long> node) {
        if (CollUtil.isEmpty(node.getChildren())) {
            return;
        }
        int total = MapUtil.getInt(node, Constants.TOTAL);
        for (Tree<Long> child : node.getChildren()) {
            if (Objects.nonNull(child.get(Constants.TOTAL))) {
                // 递归计算子节点的 total
                calculateNodeTotal(child);
                total += MapUtil.getInt(child, Constants.TOTAL);
            }
        }
        node.putExtra(Constants.TOTAL, total);
    }

写在最后的话

        树状结构好构造,就是计算数据量有点绕,绕来绕去就晕了

猜你喜欢

转载自blog.csdn.net/WayneLee0809/article/details/131831642