一、三层架构代码
可能很多人都没写过关于tree的代码,今天我来演示一下,步骤很全,放心观看。
 首先来看element-ui官网关于tree的示例:
<el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
<script>
  export default {
    data() {
      return {
        data: [{
          label: '一级 1',
          children: [{
            label: '二级 1-1',
            children: [{
              label: '三级 1-1-1'
            }]
          }]
        }, {
          label: '一级 2',
          children: [{
            label: '二级 2-1',
            children: [{
              label: '三级 2-1-1'
            }]
          }, {
            label: '二级 2-2',
            children: [{
              label: '三级 2-2-1'
            }]
          }]
        }, {
          label: '一级 3',
          children: [{
            label: '二级 3-1',
            children: [{
              label: '三级 3-1-1'
            }]
          }, {
            label: '二级 3-2',
            children: [{
              label: '三级 3-2-1'
            }]
          }]
        }],
        defaultProps: {
          children: 'children',
          label: 'label'
        }
      };
    },
    methods: {
      handleNodeClick(data) {
        console.log(data);
      }
    }
  };
</script>可以看得出来其底层为:
[{
 label: '一级 1',
 children: [{
    label: '二级 1-1',
    children: [{
        label: '三级 1-1-1'
        }]
    }]
}]这么一看是不是清晰明了?那么我们该返回什么样的数据是不是也清楚明白了?
 话不多说我们来看后端与数据库,首先是数据库:
对应的是   部门ID、  部门名称  、  部门层级   、 上级部门ID
  接着来看实体类:(有lombok记得装)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DepartmentDTO {
    private Integer departmentId; // ID
    private String dname; // 部门名称
    private Integer dindex; // 所属级别
    private Integer dparent; // 上级部门ID
    List<DepartmentDTO> dchildren; // 下级部门集合
}这里dchildren正好对应的是子节点,可以无限的递归下去。也符合上面官网给出的示例。思想也很简单,如果是子节点就用dchildren.add添加进去即可。
 然后看controller与service层代码:
@GetMapping("/getDepartmentTree")
public Result getCategory(){
    List<DepartmentDTO> departmentDTOS = departmentService.quertListTree();
    return Result.success(departmentDTOS);
}
public interface DepartmentService {
    public List<DepartmentDTO> quertListTree();
}
@Mapper
public interface DepartmentMapper {
    @Select("select department_id, dname, dindex, dparent from department order by dparent")
    List<DepartmentDTO> queryList();
}接下来是重头戏,看业务层的代码:
- //获取全部的部门数据
 List<DepartmentDTO> departments = departmentMapper.queryList();
 这一步就是从mapper层中获取数据库中的数据,然后封装到List<DepartmentDTO> departments中
- //初始化每个部门儿子节点
 for (DepartmentDTO department : departments) {
 department.setDchildren(new ArrayList<>());
 }
 这一步很重要,第一步获取的数据中是没有儿子节点的,也就说List<DepartmentDTO> departments中每一个部门的dchildren就将为null,这是mybatis的正常操作,对于没有的数据就映射为null,但是list集合如果为null的话,add的时候就会报空指针异常,所以需要进行初始化,用setDchildren(new ArrayList<>())来重新创建 ArrayList集合来进行add操作。
- 然后就没啥东西了,如果看得懂但是不理解可以学一下java的引用传递机制。
@Override
public List<DepartmentDTO> quertListTree() {
    //获取全部的部门数据
    List<DepartmentDTO> departments = departmentMapper.queryList();
    //初始化每个部门儿子节点
    for (DepartmentDTO department : departments) {
        department.setDchildren(new ArrayList<>());
    }
    // 传递一个空的 将要返回的集合
    List<DepartmentDTO> resuletDeptDTOs = new ArrayList<>();
    // 开始构建树
    for (DepartmentDTO dept : departments) {
        // 1. 如果获取的dparent 为 0 则是第一层节点 直接放进resuletDeptDTOs中
        if(dept.getDparent().equals(0)){
            resuletDeptDTOs.add(dept);
        }else {
            // 2. 如果不是0 则至少是一个子节点或者是孙子节点
            // 3. 找到当前循环的dept的父亲节点
            // 4. 根据java的引用传递机制,你这里修改了其实是修改了引用,你后面获取到的就是有子节点的数据,不必担心,如果不理解可以去看看引用传递机制
            DepartmentDTO fatherDept = findDepartmentDTOById(departments, dept.getDparent());
            if(fatherDept!=null){
                fatherDept.getDchildren().add(dept);
            }
        }
    }
    return resuletDeptDTOs;
}
private static DepartmentDTO findDepartmentDTOById(List<DepartmentDTO> dtoList, Integer id) {
    for (DepartmentDTO dto : dtoList) {
        if (dto.getDepartmentId().equals(id)) {
            return dto;
        }
    }
    return null;
} 最后来看看前端:
  
<template>
	<div>
		<div>
			<h1>树形结构图实验开始</h1>
		</div>
		<div>
			<el-tree :data="treedata" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
		</div>
	</div>
</template>
<script>
	export default {
		data() {
			return {
				treedata:[],
				defaultProps: {
					children: 'dchildren',
					label: 'dname'
				}
			};
		},
		methods: {
			handleNodeClick(data) {
				console.log(data);
			},
			getAllClothesByUserID() {
				this.$axios.get('/admin/department/getDepartmentTree').then(res => {
					if (res.data.code === 1) {
						console.log(res.data.data);
						this.treedata=res.data.data;
					}
				})
			},
		},
		mounted() {
			this.getAllClothesByUserID();
		}
	};
</script>
<style>
</style> 运行结果:
二、test模拟:
public class StringTest {
    public static void main(String[] args) {
        List<DepartmentDTO> departments = Arrays.asList(
                new DepartmentDTO(19, "精工汽车", 1, 0,new ArrayList<>()),
                new DepartmentDTO(18, "精工底盘", 2, 19,new ArrayList<>()),
                new DepartmentDTO(17, "精工压铸", 2, 19,new ArrayList<>()),
                new DepartmentDTO(16, "泰州底盘", 3, 18,new ArrayList<>()),
                new DepartmentDTO(15, "徐水底盘", 3, 18,new ArrayList<>()),
                new DepartmentDTO(14, "荆门压铸", 3, 17,new ArrayList<>()),
                new DepartmentDTO(13, "徐水压铸", 3, 17,new ArrayList<>()),
                new DepartmentDTO(12, "徐水制造部", 4, 15,new ArrayList<>())
        );
        // 构建部门树
        List<DepartmentDTO> departmentTree = buildDepartmentTree(departments);
        printDepartmentTree(departmentTree, 0);
    }
    private static List<DepartmentDTO> buildDepartmentTree(List<DepartmentDTO> departments) {
        // 1. 创建一个新的返回集合
        List<DepartmentDTO> resultDeptDTOs = new ArrayList<>();
        for(int i=0;i<departments.size();i++){
            if(departments.get(i).getDparent()==0){
                resultDeptDTOs.add(departments.get(i));
            }else {
                DepartmentDTO chileDTO = findDTO(departments,departments.get(i).getDparent());
                chileDTO.getDchildren().add(departments.get(i));
            }
        }
        return resultDeptDTOs;
    }
    private static DepartmentDTO findDTO(List<DepartmentDTO> departments,Integer id){
        for (DepartmentDTO department : departments) {
            if(department.getDepartmentId()==id){
                return department;
            }
        }
        return null;
    }
    private static void printDepartmentTree(List<DepartmentDTO> departments, int level) {
        for (DepartmentDTO department : departments) {
            for (int i = 0; i < level; i++) {
                System.out.print("  ");
            }
            System.out.println(department.getDname());
            printDepartmentTree(department.getDchildren(), level + 1);
        }
    }
}


















