在开发的时候我们会遇到树状的结构,例如 部门、菜单等信息。
我们先进行数据库中的设计
@Data
public class Department implements Serializable {
private Integer id;
private String name;
private String nameEn;
private Integer parentId;
@TableField("`order`")
private Integer order;
/**
* 存储格式英文逗号分隔1,8,9
*/
private String childIds;
private Integer createBy;
private String createDate;
private Integer updateBy;
private String updateDate;
/**
* 0正常-1删除
*/
private Integer delFlag;
@TableField(exist = false)
List<Department> child = new ArrayList<>();
private String parentRelation;//父部门简称
private String parentRelationIds;//父部门id 链路 1,2,3
@TableField(exist = false)
List<User> userList = new ArrayList<>();
public Department(Integer id) {
this.id = id;
}
public Department() {
}
}
Controller
@GetMapping("/deptTreeUser")
public ApiResponse<Department> deptTreeUser(Integer id) {
return ApiResponse.success(departmentService.deptTreeUser(id));
}
Service
public Department deptTree(Integer deptRootId) {
if (deptRootId == null) {
return deptTree();
}
//order只是保证了同级部门之间的相对顺序
List<Department> departmentList = listByCache().stream().sorted(Comparator.comparing(v -> v.getOrder())).collect(Collectors.toList());
Department root = departmentList.stream().filter(v -> v.getId().equals(deptRootId)).findFirst().get();
root.setChild(departmentList.stream().filter(v -> v.getParentId().equals(root.getId())).collect(Collectors.toList()));
return getDepartments(departmentList,root.getChild(), root);
}
这个方法的目的是从数据库中查询出部门信息后,将信息按照order进行排序构建树,然后查询出它的子部门
listByCache方法
private List<Department> listByCache() {
List<Department> departmentList=redisTemplate.opsForList().range(DEPARTMENT_KEY,0,-1);
if (CollectionUtil.isEmpty(departmentList)) {
// 获取所有部门的信息
departmentList = list();
redisTemplate.opsForList().leftPushAll(DEPARTMENT_KEY, departmentList);
}
return departmentList;
}
这个方法的目的就是从数据库中查询部门信息
private Department getDepartments(List<Department> departmentAllList,List<Department> departmentList, Department root) {
if (CollectionUtil.isNotEmpty(departmentList)) {
for (Department department : departmentList) {
List<Department> tempList2 = departmentAllList.stream().filter(v -> v.getParentId().equals(department.getId())).collect(Collectors.toList());
department.setChild(tempList2);
getDepartments(departmentAllList, tempList2, department);
}
}
return root;
}
这个方法的目的就是构建树,构建子部门的树。这样返回root就可以把部门按照树形的结构进行展示了。
如果我们想在相应的部门下面进行添加人员呢?
这个时候,我们我们只需要在部门实体里面增加上
@TableField(exist = false)
List<User> userList = new ArrayList<>();
这个字段,然后通过遍历,将用户的信息添加进去即可。
获取所有的用户信息
public Department deptTreeUser(Integer deptRootId) {
Department department=deptTree(deptRootId);
List<User> list= userDepartmentService.listUserByLocal();
addUserForDept(department.getChild(), list);
department.setUserList(list.stream().filter(v -> v.getMainDepartment().equals(department.getId())).collect(Collectors.toList()));
return department;
}
private void addUserForDept(List<Department> child, List<User> list) {
for (Department department : child) {
List<User> tempList=list.stream().filter(v -> v.getMainDepartment().equals(department.getId())).collect(Collectors.toList());
department.setUserList(tempList);
addUserForDept(department.getChild(), list);
}
}