淘先锋技术网

首页 1 2 3 4 5 6 7

需要实现的效果

在这里插入图片描述

前端需要的json格式:一定是一个完整的树结构

错误

错误的返回格式

在这里插入图片描述

错误的返回格式实现的效果

在这里插入图片描述

正确

正确的返回格式

在这里插入图片描述

正确的展示画面

在这里插入图片描述

后端

逻辑分析

1. 根据搜索条件,查出符合的数据

在这里插入图片描述
这一步不能直接返回给前端的,因为前端的组件是需要完整的一个树结构。
从图中可以看到,我们 id in(70,71,72)的父节点 id = 17 没有找到,所以 这就不是一个完整的树结构。

2. 符合的数据里面我们需要发现还需要找到几个父节点数据

// parentId = 0,表示他已经没有父节点了
Set<Long> collect = list.stream().filter(x -> x.getParentId() != 0).map(ReproductiveCycleInfo::getParentId).collect(Collectors.toSet());

在这里插入图片描述
3. 开始找父节点的信息

        if (StringUtils.isNotEmpty(collect)) {
            for (Long x : collect) {
                getParentInfoByParentId(x, list);
            }
        }

3.1 根据节点的id找到节点

    /**
     * 根据节点id找出节点,并添加到结果集里面
     *
     * @param nodeId 当前需要找的节点id
     * @param list 返回的结果集
     */
    private void getNodeByParentId(Long nodeId, List<ReproductiveCycleInfo> list) {
        // 1. 如果当前需要找的节点
        if (nodeId != 0) {
            // 2. 为了避免父节点也已经出现在 所有的节点信息 里面
            // 2.1 找出当前所有的节点信息
            List<Long> ids = list.stream().map(ReproductiveCycleInfo::getId).collect(Collectors.toList());
            // 2.2 当前所有的节点信息不包含当前需要找的节点
            if (!ids.contains(nodeId)) {
                // 3. 从数据库里面,根据父节点的id,找到父节点信息
                ReproductiveCycleInfo one = reproductiveCycleInfoMapper.selectReproductiveCycleInfoById(nodeId);
                // 4. 把当前节点放到所有节点里面
                list.add(one);
                // 5. 如果当前节点还存在父节点
                if (one.getParentId() != 0) {
                    // 6. 递归去找父节点信息
                    getNodeByParentId(one.getParentId(), list);
                }
            }
        }
    }

以找17节点为例子:
在这里插入图片描述

代码总览

从这里也可以看出我这里其实代码已经有逻辑耦合了。毕竟 node != 0 判断了两次了,这其实没必要。还可以优化一下。

    @Override
    public List<ReproductiveCycleInfo> selectReproductiveCycleInfoListByName(ReproductiveCycleInfoDto reproductiveCycleInfo) {
        List<ReproductiveCycleInfo> list = reproductiveCycleInfoMapper.selectReproductiveCycleInfoList(reproductiveCycleInfo);
        Set<Long> collect = list.stream().filter(x -> x.getParentId() != 0).map(ReproductiveCycleInfo::getParentId).collect(Collectors.toSet());
        if (StringUtils.isNotEmpty(collect)) {
            for (Long x : collect) {
                getNodeByParentId(x, list);
            }
        }
        return list;
    }

    /**
     * 根据节点id找出节点,并添加到结果集里面
     *
     * @param nodeId 当前需要找的节点id
     * @param list 返回的结果集
     */
    private void getNodeByParentId(Long nodeId, List<ReproductiveCycleInfo> list) {
        // 1. 如果当前需要找的节点
        if (nodeId != 0) {
            // 2. 为了避免父节点也已经出现在 所有的节点信息 里面
            // 2.1 找出当前所有的节点信息
            List<Long> ids = list.stream().map(ReproductiveCycleInfo::getId).collect(Collectors.toList());
            // 2.2 当前所有的节点信息不包含当前需要找的节点
            if (!ids.contains(nodeId)) {
                // 3. 从数据库里面,根据父节点的id,找到父节点信息
                ReproductiveCycleInfo one = reproductiveCycleInfoMapper.selectReproductiveCycleInfoById(nodeId);
                // 4. 把当前节点放到所有节点里面
                list.add(one);
                // 5. 如果当前节点还存在父节点
                if (one.getParentId() != 0) {
                    // 6. 递归去找父节点信息
                    getNodeByParentId(one.getParentId(), list);
                }
            }
        }
    }

数据库表结构

起码得满足有这些极端并约定 parentId = 0 是表示是首节点了.
在这里插入图片描述