项目中遇到一个接口,需要根据部门级别返回一个树状结构,包括部门,子部门,和部门下的员工,其结构如下:
{
"code": 0,
"data": [{
"nodeId": 0,
"label": "第一级部门",
"choiced": 0,
"children": [{
"nodeId": 1,
"label": "第二级部门",
"choiced": 1,
"children": [
{
"nodeId": 2,
"label": "第三级部门",
"choiced": 0,
"children": []
},
{
"nodeId": 3,
"label": "第二级部门的人员",
"choiced": 1
}
]
}]
}]
}
仔细分析一下,每一级的结构基本都相同,有"nodeId","label","choiced"这三个基本的信息,需要注意的是,部门有"children"字段,即子部门,而员工没有这个字段。
难点分析:
这个结构的难点一个在于我们不知道这个部门的结构有几层,普通的循环无法实现这个功能,需要使用递归。另一个难点就是这个结构的children既有部门又有员工,但员工的数据结构与部门的结构又不太一样。
实现思路:
使用递归的方式遍历部门列表数据,首先获得所有一级部门,然后在每个一级部门,去查找该部门下的二级部门和该部门下的员工......。最底层员工层我们可以写一个父类,然后部门去继承这个类并添一个children属性。
实现方法:
父类NodeVo:
public class NodeVo {
//省略get/set方法
private Integer node_id;
private String label;
private Integer choiced;
}
子类AuthTreeVo:
public class AuthTreeVo extends NodeVo{
//省略get/set方法
private List<NodeVo> children;
}
实现类AuthTree:
构造方法:根据业务需求传参
public AuthTree(List<PersonWithDept> personList,List<PersonWithDept> personAuthList, List<Department> departmentList, List<Department> departmentAuthList){
this.personList = personList;
this.personAuthList = personAuthList;
this.departmentList = departmentList;
this.departmentAuthList = departmentAuthList;
}
获取所有一级部门:getRootNode()
public List<Department> getRootNode(){
List<Department> departments = new ArrayList<>();
for(Department department:departmentList){
if(department.getParentId().equals(0)){
departments.add(department);
}
}
return departments;
}
实现树状结构的方法:makeTree()
public List<AuthTreeVo> makeTree(){
List<AuthTreeVo> authTreeVos = new ArrayList<>();
for(Department department:getRootNode()){
AuthTreeVo authTreeVo = new AuthTreeVo();
authTreeVo.setNode_id(department.getDepartmentId());
authTreeVo.setLabel(department.getDepartmentName());
authTreeVo=loopTree(department);
authTreeVos.add(authTreeVo);
}
return authTreeVos;
}
递归方法:loopTree()
public AuthTreeVo loopTree(Department department){
AuthTreeVo authTreeVo = new AuthTreeVo();
authTreeVo.setNode_id(department.getDepartmentId());
authTreeVo.setLabel(department.getDepartmentName());
authTreeVo.setChoiced(0);
for(Department authDepartment: departmentAuthList) {
if (authDepartment.getDepartmentId().equals(department.getDepartmentId())) {
authTreeVo.setChoiced(1);
break;
}
}
List<NodeVo> authTreeVos = new ArrayList<>();
for(Department departmentChild:departmentList){
if(departmentChild.getParentId().equals(department.getDepartmentId())){
authTreeVos.add(loopTree(departmentChild));
}
}
for(PersonWithDept person: personList){
if(person.getDepartmentId().equals(department.getDepartmentId())){
NodeVo nodeVo = new NodeVo();
nodeVo.setNode_id(person.getPersonId());
nodeVo.setLabel(person.getName());
nodeVo.setChoiced(0);
for(PersonWithDept authPerson:personAuthList){
if(authPerson.getPersonId().equals(person.getPersonId())){
nodeVo.setChoiced(1);
break;
}
}
authTreeVos.add(nodeVo);
}
}
authTreeVo.setChildren(authTreeVos);
return authTreeVo;
}