关于后台设计断层树形结构方案

背景

我们都知道树形结构,比如菜单,多层的分类等都和树形结构分不开,今天我们要实现的功能是,查询出结构不一定依次关联的,比如:在Oa中我们创建有层级的树形分类,假如有个需求需要根据创建的人来显示相应的层级如图:

在这里插入图片描述

正常系统管理员看到是 五个层级拥有所有权限,但是李四登录要求看到的是如图:
在这里插入图片描述
张三看到自己的显示如图:
在这里插入图片描述
基于这个需求我们分析设计对应方案。

常规设计

假如我们按照常规思路,先按照当前用户id 过滤查询他自己创建的数据,这个时候再去迭代递归组装树形结构,要是他创建的是按照顺序的那可以满足,但是要是出现上面那种情况迭代的时候找不到连续的parentId,没法形成父子节点。

设计方案

由于我们正常设计方案针对断层的树形没法获取parentId,所以在考虑设计的时候加入path 这个字段,他的作用是保存从顶层节点到该节点的路径,比如刚才那个开发语言 他的path 就是职业-互联网-开发语言所对应的id值。这个时候我们可以通过path 一直循环找他上级、上上级……。直到找不到为止。

数据库设计

CREATE TABLE `tb_tree` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `code_num` bigint(20) DEFAULT NULL COMMENT 'code',
  `parent_code_num` bigint(20) DEFAULT NULL COMMENT '父节点code',
  `code_name` varchar(20) DEFAULT NULL COMMENT 'code 名称',
  `path` varchar(1024) DEFAULT NULL COMMENT '树形节点路径',
  `create_id` bigint(20) DEFAULT NULL COMMENT '创建者id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='树形分类';

代码具体实现

public static List<TreeEntity> buildTree(List<TreeEntity> nodes) {
        List<TreeEntity> tree = Lists.newArrayList();
        HashMap<String, TreeEntity> nodeMap = Maps.newHashMap();
        String path;
        // 将path 存放到临时Map中
        for (TreeEntity node : nodes) {
            nodeMap.put(node.getPath(), node);
        }
        for (TreeEntity node : nodes) {
            // 顶级节点直接放到list
            if (node.getParentCodeNum() == 0L) {
                tree.add(node);
            } else {
                path = node.getPath();
                TreeEntity parent = null;
                //  一直循环找上级节点,找到结束循环,没有说明path中所有上级都没有,直接放到list
                while (path.length() - path.replace("/", "").length() > 1) {
                    String parentPath = path.substring(0, path.lastIndexOf("/"));
                    parent = nodeMap.get(parentPath);
                    if (parent != null) {
                        break;
                    }
                    path = parentPath;
                }

                if (parent == null) {
                    tree.add(node);
                } else {
                    //找到后关联到parent 的children 中。
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(node);
                }
            }
        }

        return tree;
    }

显示效果

显示张三
[
	{
		"children":[
			{
				"children":[
					{
						"codeName":"Java",
						"codeNum":3,
						"createId":"1",
						"id":3,
						"parentCodeNum":4,
						"path":"0/1/2/4/3"
					}
				],
				"codeName":"互联网IT",
				"codeNum":2,
				"createId":"1",
				"id":2,
				"parentCodeNum":1,
				"path":"0/1/2"
			}
		],
		"codeName":"职业",
		"codeNum":1,
		"createId":"1",
		"id":1,
		"parentCodeNum":0,
		"path":"0/1"
	}
]

显示李四
[
	{
		"children":[
			{
				"codeName":"spring",
				"codeNum":5,
				"createId":"2",
				"id":5,
				"parentCodeNum":4,
				"path":"0/1/2/4/3/5"
			}
		],
		"codeName":"开发语言",
		"codeNum":4,
		"createId":"2",
		"id":4,
		"parentCodeNum":2,
		"path":"0/1/2/4"
	}
]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

蜗牛乌龟一起走

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

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

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

打赏作者

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

抵扣说明:

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

余额充值