欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

将扁平型组织结构调整为树状架构:上下级部门关系的与转化

最编程 2024-07-24 20:57:49
...

概要:

比如企业微信API中获取部门列表的接口(https://work.weixin.qq.com/api/doc/90000/90135/90208),该接口返回的部门列表中,每个部门有一个字段关联其上级部门,很多时候需要根据返回的列表获取某个部门的所有上级部门、子部门,以及转换成树形结构。

 

代码:

部门实体类:

package com.example.study.entity;

import lombok.Data;

/**
 * 部门实体类
 */
@Data
public class DepartmentEntity {
    /**
     * 部门id
     */
    private Integer id;
    /**
     * 部门名称
     */
    private String name;
    /**
     * 上级部门id
     */
    private Integer parentId;
}

部门Vo类:

package com.example.study.vo;

import com.example.study.entity.DepartmentEntity;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Objects;
import java.util.Set;

/**
 * 部门Vo类
 * 由于部门树一般只存在于给前端展示的Vo中,所以将子部门集合放在Vo中
 */
@Data
@NoArgsConstructor
public class DepartmentVo extends DepartmentEntity {
    /**
     * 子部门集合
     */
    private Set<DepartmentVo> childDepartments;

    public DepartmentVo(DepartmentEntity entity) {
        super.setId(entity.getId());
        super.setName(entity.getName());
        super.setParentId(entity.getParentId());
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        if (!super.equals(o)) return false;
        DepartmentVo that = (DepartmentVo) o;
        return Objects.equals(childDepartments, that.childDepartments);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), childDepartments);
    }
}

Util类:

package com.example.study.util;

import com.example.study.entity.DepartmentEntity;
import com.example.study.entity.DepartmentVo;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 部门常用方法
 * 所有方法均未作入参校验,使用时请根据实际情况加上入参校验
 */
@Slf4j
public class DepartmentUtil {
    /**
     * 获取最上层部门
     *
     * @param departments 部门列表
     * @return 最上层部门
     */
    public static DepartmentEntity getTopDepartment(List<DepartmentEntity> departments) {
        if (departments == null || departments.size() == 0) {
            throw new RuntimeException("未获取到最上层部门!");
        }
        Set<Integer> departmentIdSet = departments.stream().map(o -> o.getId()).collect(Collectors.toSet());
        for (DepartmentEntity department : departments) {
            if (!departmentIdSet.contains(department.getParentId())) {
                return department;
            }
        }
        log.error("未获取到最上层部门!");
        throw new RuntimeException("未获取到最上层部门!");
    }

    /**
     * 获取所有上级部门
     *
     * @param departments       部门列表
     * @param currentDepartment 当前部门
     * @return 当前部门的所有上级部门列表
     */
    public static Set<DepartmentEntity> getParentDepartments(List<DepartmentEntity> departments, DepartmentEntity currentDepartment) {
        Set<DepartmentEntity> parentDepartmentSet = new HashSet<>();
        if (departments == null || departments.size() == 0 || currentDepartment == null) {
            // 当前部门为空时,认为当前部门为最上层部门
            return parentDepartmentSet;
        }
        DepartmentEntity topDepartment = getTopDepartment(departments);
        Map<Integer, DepartmentEntity> idDepartmentMap = departments.stream().collect(Collectors.toMap(DepartmentEntity::getId, Function.identity()));
        DepartmentEntity parentDepartment = idDepartmentMap.get(currentDepartment.getParentId());
        while (parentDepartment != null) {
            parentDepartmentSet.add(parentDepartment);
            if (parentDepartment.getId().equals(topDepartment.getId())) {
                break;
            }
            parentDepartment = idDepartmentMap.get(parentDepartment.getParentId());
        }
        return parentDepartmentSet;
    }


    /**
     * 获取所有下级部门
     *
     * @param departments       部门列表
     * @param currentDepartment 当前部门
     * @return 当前部门的所有下级部门列表
     */
    public static Set<DepartmentEntity> getChildDepartments(List<DepartmentEntity> departments, DepartmentEntity currentDepartment) {
        Set<DepartmentEntity> childDepartmentSet = new HashSet<>();
        if (departments == null || departments.size() == 0) {
            return childDepartmentSet;
        }
        if (currentDepartment == null) {
            // 当前部门为空时,认为当前部门为最上层部门
            childDepartmentSet.addAll(departments);
            return childDepartmentSet;
        }

        Map<Integer, Set<DepartmentEntity>> parentChildMap = getParentChildMap(departments);
        doGetChildDepartments(parentChildMap, currentDepartment, childDepartmentSet);
        return childDepartmentSet;
    }

    /**
     * 获取父部门id -> 子部门 Map
     *
     * @param departments 部门列表
     * @return 部门id -> 子部门 Map
     */
    private static Map<Integer, Set<DepartmentEntity>> getParentChildMap(List<DepartmentEntity> departments) {
        Map<Integer, Set<DepartmentEntity>> parentChildMap = new HashMap<>();
        for (DepartmentEntity department : departments) {
            Set<DepartmentEntity> childDepartmentSet = parentChildMap.get(department.getParentId());
            if (childDepartmentSet == null) {
                childDepartmentSet = new HashSet<>();
                childDepartmentSet.add(department);
                parentChildMap.put(department.getParentId(), childDepartmentSet);
            } else {
                childDepartmentSet.add(department);
            }
        }
        return parentChildMap;
    }

    /**
     * 递归获取当前部门的所有子部门
     *
     * @param parentChildMap     部门id -> 子部门 Map
     * @param currentDepartment  当前部门
     * @param childDepartmentSet 子部门Set
     */
    private static void doGetChildDepartments(Map<Integer, Set<DepartmentEntity>> parentChildMap, DepartmentEntity currentDepartment, Set<DepartmentEntity> childDepartmentSet) {
        Set<DepartmentEntity> childSet = parentChildMap.get(currentDepartment.getId());
        if (childSet != null) {
            childDepartmentSet.addAll(childSet);
            for (DepartmentEntity child : childSet) {
                doGetChildDepartments(parentChildMap, child, childDepartmentSet);
            }
        }
    }

    /**
     * 获取部门树
     *
     * @param departments 部门列表
     * @return 部门树
     */
    public static DepartmentVo getDepartmentTree(List<DepartmentEntity> departments) {
        if (departments == null || departments.size() == 0) {
            return new DepartmentVo();
        }
        Map<Integer, Set<DepartmentEntity>> parentChildMap = getParentChildMap(departments);
        DepartmentEntity topDepartment = getTopDepartment(departments);
        DepartmentVo rootNode = new DepartmentVo(topDepartment);
        doGetDepartmentTree(parentChildMap, rootNode);
        return rootNode;
    }


    /**
     * 递归设置所有子部门的子部门
     *
     * @param parentChildMap 部门id -> 子部门 Map
     * @param rootNode       根部门(对最外一层递归,根部门即为最上层部门)
     */
    private static void doGetDepartmentTree(Map<Integer, Set<DepartmentEntity>> parentChildMap, DepartmentVo rootNode) {
        Set<DepartmentEntity> childSet = parentChildMap.get(rootNode.getId());
        Set<DepartmentVo> childVoSet = new HashSet<>();
        if (childSet != null) {
            childSet.forEach(o -> childVoSet.add(new DepartmentVo(o)));
            rootNode.setChildDepartments(childVoSet);
            for (DepartmentVo childVo : childVoSet) {
                doGetDepartmentTree(parentChildMap, childVo);
            }
        } else {
            rootNode.setChildDepartments(childVoSet);
        }
    }


    /**
     * 获取部门集合
     *
     * @param rootNode 根部门
     * @return 部门集合
     */
    public static Set<DepartmentEntity> getDepartmentSet(DepartmentVo rootNode) {
        Set<DepartmentEntity> set = new HashSet<>();
        if (rootNode == null) {
            return set;
        }
        doGetDepartmentSet(set, rootNode);
        return set;
    }


    /**
     * 深度遍历所有部门
     *
     * @param set      部门set
     * @param rootNode 根部门
     */
    private static void doGetDepartmentSet(Set<DepartmentEntity> set, DepartmentVo rootNode) {
        if (rootNode != null) {
            set.add(new DepartmentVo(rootNode));
            for (DepartmentVo childDepartment : rootNode.getChildDepartments()) {
                doGetDepartmentSet(set, childDepartment);
            }
        }
    }
}

测试类:

package com.example.study.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.study.entity.DepartmentEntity;
import com.example.study.entity.DepartmentVo;
import com.example.study.util.DepartmentUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;

public class DepartmentTest {
    public static void main(String[] args) {
        String departmentsStr = "[ { \"id\": 0, \"name\": \"部门0(根部门)\", \"parentId\": -1 }, { \"id\": 1, \"name\": \"部门1\", \"parentId\": 0 }, { \"id\": 2, \"name\": \"部门2\", \"parentId\": 0 }, { \"id\": 3, \"name\": \"部门3\", \"parentId\": 0 }, { \"id\": 4, \"name\": \"部门4\", \"parentId\": 2 }, { \"id\": 5, \"name\": \"部门5\", \"parentId\": 2 }, { \"id\": 6, \"name\": \"部门6\", \"parentId\": 3 }, { \"id\": 7, \"name\": \"部门7\", \"parentId\": 3 }, { \"id\": 8, \"name\": \"部门8\", \"parentId\": 6 }, { \"id\": 9, \"name\": \"部门9\", \"parentId\": 7 }, { \"id\": 10, \"name\": \"部门10\", \"parentId\": 9 }, { \"id\": 11, \"name\": \"部门11\", \"parentId\": 9 } ]";
        List<DepartmentEntity> departments = JSONArray.parseArray(departmentsStr, DepartmentEntity.class);
        System.out.println("all:" + JSON.toJSONString(departments));
        DepartmentEntity topDepartment = DepartmentUtil.getTopDepartment(departments);
        System.out.println("top:" + JSON.toJSONString(topDepartment));
        Integer index = new Random().nextInt(departments.size());
        DepartmentEntity currentDepartment = departments.get(index);
        System.out.println("current:" + JSON.toJSONString(currentDepartment));
        Set<DepartmentEntity> parentDepartments = DepartmentUtil.getParentDepartments(departments, currentDepartment);
        System.out.println("parents:" + JSON.toJSONString(parentDepartments));
        Set<DepartmentEntity> childDepartments = DepartmentUtil.getChildDepartments(departments, currentDepartment);
        System.out.println("child:" + JSON.toJSONString(childDepartments));
        DepartmentVo departmentTree = DepartmentUtil.getDepartmentTree(departments);
        String treeStr = JSON.toJSONString(departmentTree);
        System.out.println("tree:" + treeStr);
        System.out.println("all:" + JSON.toJSONString(departments));
        DepartmentVo departmentVo = JSONObject.parseObject(treeStr, DepartmentVo.class);
        Set<DepartmentEntity> departmentSet = DepartmentUtil.getDepartmentSet(departmentVo);
        System.out.println("set:" + JSON.toJSONString(departmentSet));
        List<DepartmentEntity> nList = new ArrayList<>(departmentSet);
        DepartmentEntity nTopDepartment = DepartmentUtil.getTopDepartment(nList);
        System.out.println("new Top:" + JSON.toJSONString(nTopDepartment));
        DepartmentVo nDepartmentTree = DepartmentUtil.getDepartmentTree(nList);
        System.out.println("new Tree:" + JSON.toJSONString(nDepartmentTree));
        System.out.println("all:" + JSON.toJSONString(departments));
    }
}

测试结果:

C:\software\Java\jdk1.8.0_261\bin\java.exe "-javaagent:C:\software\JetBrains\IntelliJ IDEA 2019.2.4\lib\idea_rt.jar=51715:C:\software\JetBrains\IntelliJ IDEA 2019.2.4\bin" -Dfile.encoding=UTF-8 -classpath C:\software\Java\jdk1.8.0_261\jre\lib\charsets.jar;C:\software\Java\jdk1.8.0_261\jre\lib\deploy.jar;C:\software\Java\jdk1.8.0_261\jre\lib\ext\access-bridge-64.jar;C:\software\Java\jdk1.8.0_261\jre\lib\ext\cldrdata.jar;C:\software\Java\jdk1.8.0_261\jre\lib\ext\dnsns.jar;C:\software\Java\jdk1.8.0_261\jre\lib\ext\jaccess.jar;C:\software\Java\jdk1.8.0_261\jre\lib\ext\jfxrt.jar;C:\software\Java\jdk1.8.0_261\jre\lib\ext\localedata.jar;C:\software\Java\jdk1.8.0_261\jre\lib\ext\nashorn.jar;C:\software\Java\jdk1.8.0_261\jre\lib\ext\sunec.jar;C:\software\Java\jdk1.8.0_261\jre\lib\ext\sunjce_provider.jar;C:\software\Java\jdk1.8.0_261\jre\lib\ext\sunmscapi.jar;C:\software\Java\jdk1.8.0_261\jre\lib\ext\sunpkcs11.jar;C:\software\Java\jdk1.8.0_261\jre\lib\ext\zipfs.jar;C:\software\Java\jdk1.8.0_261\jre\lib\javaws.jar;C:\software\Java\jdk1.8.0_261\jre\lib\jce.jar;C:\software\Java\jdk1.8.0_261\jre\lib\jfr.jar;C:\software\Java\jdk1.8.0_261\jre\lib\jfxswt.jar;C:\software\Java\jdk1.8.0_261\jre\lib\jsse.jar;C:\software\Java\jdk1.8.0_261\jre\lib\management-agent.jar;C:\software\Java\jdk1.8.0_261\jre\lib\plugin.jar;C:\software\Java\jdk1.8.0_261\jre\lib\resources.jar;C:\software\Java\jdk1.8.0_261\jre\lib\rt.jar;D:\studyCode\study\target\classes;C:\software\apache-maven-3.6.3\repo\com\squareup\okhttp3\okhttp\3.11.0\okhttp-3.11.0.jar;C:\software\apache-maven-3.6.3\repo\com\squareup\okio\okio\1.14.0\okio-1.14.0.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\boot\spring-boot-starter-validation\2.4.0\spring-boot-starter-validation-2.4.0.jar;C:\software\apache-maven-3.6.3\repo\org\glassfish\jakarta.el\3.0.3\jakarta.el-3.0.3.jar;C:\software\apache-maven-3.6.3\repo\org\hibernate\validator\hibernate-validator\6.1.6.Final\hibernate-validator-6.1.6.Final.jar;C:\software\apache-maven-3.6.3\repo\jakarta\validation\jakarta.validation-api\2.0.2\jakarta.validation-api-2.0.2.jar;C:\software\apache-maven-3.6.3\repo\org\jboss\logging\jboss-logging\3.4.1.Final\jboss-logging-3.4.1.Final.jar;C:\software\apache-maven-3.6.3\repo\com\fasterxml\classmate\1.5.1\classmate-1.5.1.jar;C:\software\apache-maven-3.6.3\repo\org\aspectj\aspectjweaver\1.9.6\aspectjweaver-1.9.6.jar;C:\software\apache-maven-3.6.3\repo\org\apache\commons\commons-lang3\3.4\commons-lang3-3.4.jar;C:\software\apache-maven-3.6.3\repo\redis\clients\jedis\3.0.0\jedis-3.0.0.jar;C:\software\apache-maven-3.6.3\repo\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;C:\software\apache-maven-3.6.3\repo\org\apache\commons\commons-pool2\2.9.0\commons-pool2-2.9.0.jar;C:\software\apache-maven-3.6.3\repo\org\apache\rocketmq\rocketmq-client\4.7.1\rocketmq-client-4.7.1.jar;C:\software\apache-maven-3.6.3\repo\org\apache\rocketmq\rocketmq-common\4.7.1\rocketmq-common-4.7.1.jar;C:\software\apache-maven-3.6.3\repo\org\apache\rocketmq\rocketmq-remoting\4.7.1\rocketmq-remoting-4.7.1.jar;C:\software\apache-maven-3.6.3\repo\com\alibaba\fastjson\1.2.69\fastjson-1.2.69.jar;C:\software\apache-maven-3.6.3\repo\io\netty\netty-all\4.1.54.Final\netty-all-4.1.54.Final.jar;C:\software\apache-maven-3.6.3\repo\org\apache\rocketmq\rocketmq-logging\4.7.1\rocketmq-logging-4.7.1.jar;C:\software\apache-maven-3.6.3\repo\io\netty\netty-tcnative-boringssl-static\2.0.34.Final\netty-tcnative-boringssl-static-2.0.34.Final.jar;C:\software\apache-maven-3.6.3\repo\commons-validator\commons-validator\1.6\commons-validator-1.6.jar;C:\software\apache-maven-3.6.3\repo\commons-beanutils\commons-beanutils\1.9.2\commons-beanutils-1.9.2.jar;C:\software\apache-maven-3.6.3\repo\commons-digester\commons-digester\1.8.1\commons-digester-1.8.1.jar;C:\software\apache-maven-3.6.3\repo\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;C:\software\apache-maven-3.6.3\repo\commons-collections\commons-collections\3.2.2\commons-collections-3.2.2.jar;C:\software\apache-maven-3.6.3\repo\org\projectlombok\lombok\1.18.16\lombok-1.18.16.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\boot\spring-boot-starter\2.4.0\spring-boot-starter-2.4.0.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\boot\spring-boot\2.4.0\spring-boot-2.4.0.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\spring-context\5.3.1\spring-context-5.3.1.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\boot\spring-boot-autoconfigure\2.4.0\spring-boot-autoconfigure-2.4.0.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\boot\spring-boot-starter-logging\2.4.0\spring-boot-starter-logging-2.4.0.jar;C:\software\apache-maven-3.6.3\repo\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\software\apache-maven-3.6.3\repo\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\software\apache-maven-3.6.3\repo\org\apache\logging\log4j\log4j-to-slf4j\2.13.3\log4j-to-slf4j-2.13.3.jar;C:\software\apache-maven-3.6.3\repo\org\apache\logging\log4j\log4j-api\2.13.3\log4j-api-2.13.3.jar;C:\software\apache-maven-3.6.3\repo\org\slf4j\jul-to-slf4j\1.7.30\jul-to-slf4j-1.7.30.jar;C:\software\apache-maven-3.6.3\repo\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\spring-core\5.3.1\spring-core-5.3.1.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\spring-jcl\5.3.1\spring-jcl-5.3.1.jar;C:\software\apache-maven-3.6.3\repo\org\yaml\snakeyaml\1.27\snakeyaml-1.27.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\boot\spring-boot-starter-web\2.4.0\spring-boot-starter-web-2.4.0.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\boot\spring-boot-starter-json\2.4.0\spring-boot-starter-json-2.4.0.jar;C:\software\apache-maven-3.6.3\repo\com\fasterxml\jackson\core\jackson-databind\2.11.3\jackson-databind-2.11.3.jar;C:\software\apache-maven-3.6.3\repo\com\fasterxml\jackson\core\jackson-annotations\2.11.3\jackson-annotations-2.11.3.jar;C:\software\apache-maven-3.6.3\repo\com\fasterxml\jackson\core\jackson-core\2.11.3\jackson-core-2.11.3.jar;C:\software\apache-maven-3.6.3\repo\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.11.3\jackson-datatype-jdk8-2.11.3.jar;C:\software\apache-maven-3.6.3\repo\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.11.3\jackson-datatype-jsr310-2.11.3.jar;C:\software\apache-maven-3.6.3\repo\com\fasterxml\jackson\module\jackson-module-parameter-names\2.11.3\jackson-module-parameter-names-2.11.3.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\boot\spring-boot-starter-tomcat\2.4.0\spring-boot-starter-tomcat-2.4.0.jar;C:\software\apache-maven-3.6.3\repo\org\apache\tomcat\embed\tomcat-embed-core\9.0.39\tomcat-embed-core-9.0.39.jar;C:\software\apache-maven-3.6.3\repo\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.39\tomcat-embed-websocket-9.0.39.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\spring-web\5.3.1\spring-web-5.3.1.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\spring-beans\5.3.1\spring-beans-5.3.1.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\spring-webmvc\5.3.1\spring-webmvc-5.3.1.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\spring-aop\5.3.1\spring-aop-5.3.1.jar;C:\software\apache-maven-3.6.3\repo\org\springframework\spring-expression\5.3.1\spring-expression-5.3.1.jar com.example.study.common.DepartmentTest
all:[{"id":0,"name":"部门0(根部门)","parentId":-1},{"id":1,"name":"部门1","parentId":0},{"id":2,"name":"部门2","parentId":0},{"id":3,"name":"部门3","parentId":0},{"id":4,"name":"部门4","parentId":2},{"id":5,"name":"部门5","parentId":2},{"id":6,"name":"部门6","parentId":3},{"id":7,"name":"部门7","parentId":3},{"id":8,"name":"部门8","parentId":6},{"id":9,"name":"部门9","parentId":7},{"id":10,"name":"部门10","parentId":9},{"id":11,"name":"部门11","parentId":9}]
top:{"id":0,"name":"部门0(根部门)","parentId":-1}
current:{"id":5,"name":"部门5","parentId":2}
parents:[{"id":2,"name":"部门2","parentId":0},{"id":0,"name":"部门0(根部门)","parentId":-1}]
child:[]
tree:{"childDepartments":[{"childDepartments":[],"id":1,"name":"部门1","parentId":0},{"childDepartments":[{"childDepartments":[{"childDepartments":[{"childDepartments":[],"id":10,"name":"部门10","parentId":9},{"childDepartments":[],"id":11,"name":"部门11","parentId":9}],"id":9,"name":"部门9","parentId":7}],"id":7,"name":"部门7","parentId":3},{"childDepartments":[{"childDepartments":[],"id":8,"name":"部门8","parentId":6}],"id":6,"name":"部门6","parentId":3}],"id":3,"name":"部门3","parentId":0},{"childDepartments":[{"childDepartments":[],"id":4,"name":"部门4","parentId":2},{"childDepartments":[],"id":5,"name":"部门5","parentId":2}],"id":2,"name":"部门2","parentId":0}],"id":0,"name":"部门0(根部门)","parentId":-1}
all:[{"id":0,"name":"部门0(根部门)","parentId":-1},{"id":1,"name":"部门1","parentId":0},{"id":2,"name":"部门2","parentId":0},{"id":3,"name":"部门3","parentId":0},{"id":4,"name":"部门4","parentId":2},{"id":5,"name":"部门5","parentId":2},{"id":6,"name":"部门6","parentId":3},{"id":7,"name":"部门7","parentId":3},{"id":8,"name":"部门8","parentId":6},{"id":9,"name":"部门9","parentId":7},{"id":10,"name":"部门10","parentId":9},{"id":11,"name":"部门11","parentId":9}]
set:[{"id":1,"name":"部门1","parentId":0},{"id":9,"name":"部门9","parentId":7},{"id":3,"name":"部门3","parentId":0},{"id":10,"name":"部门10","parentId":9},{"id":7,"name":"部门7","parentId":3},{"id":4,"name":"部门4","parentId":2},{"id":0,"name":"部门0(根部门)","parentId":-1},{"id":8,"name":"部门8","parentId":6},{"id":2,"name":"部门2","parentId":0},{"id":6,"name":"部门6","parentId":3},{"id":5,"name":"部门5","parentId":2},{"id":11,"name":"部门11","parentId":9}]
new Top:{"id":0,"name":"部门0(根部门)","parentId":-1}
new Tree:{"childDepartments":[{"childDepartments":[],"id":1,"name":"部门1","parentId":0},{"childDepartments":[{"childDepartments":[{"childDepartments":[{"childDepartments":[],"id":10,"name":"部门10","parentId":9},{"childDepartments":[],"id":11,"name":"部门11","parentId":9}],"id":9,"name":"部门9","parentId":7}],"id":7,"name":"部门7","parentId":3},{"childDepartments":[{"childDepartments":[],"id":8,"name":"部门8","parentId":6}],"id":6,"name":"部门6","parentId":3}],"id":3,"name":"部门3","parentId":0},{"childDepartments":[{"childDepartments":[],"id":4,"name":"部门4","parentId":2},{"childDepartments":[],"id":5,"name":"部门5","parentId":2}],"id":2,"name":"部门2","parentId":0}],"id":0,"name":"部门0(根部门)","parentId":-1}
all:[{"id":0,"name":"部门0(根部门)","parentId":-1},{"id":1,"name":"部门1","parentId":0},{"id":2,"name":"部门2","parentId":0},{"id":3,"name":"部门3","parentId":0},{"id":4,"name":"部门4","parentId":2},{"id":5,"name":"部门5","parentId":2},{"id":6,"name":"部门6","parentId":3},{"id":7,"name":"部门7","parentId":3},{"id":8,"name":"部门8","parentId":6},{"id":9,"name":"部门9","parentId":7},{"id":10,"name":"部门10","parentId":9},{"id":11,"name":"部门11","parentId":9}]

Process finished with exit code 0