0,循环实现3层树结构
// 查询所有主包项目数据
Cwdemc_yx_lxsqPagination baseMain = new Cwdemc_yx_lxsqPagination();
baseMain.setXmlx("01");
List<Cwdemc_yx_lxsqTreeVO> mainProject = this.selectProjectData(baseMain);
// 查询所有内包项目数据
Cwdemc_yx_lxsqPagination baseInner = new Cwdemc_yx_lxsqPagination();
baseInner.setXmlx("02");
List<Cwdemc_yx_lxsqTreeVO> innerProject = this.selectProjectData(baseInner);
// 查询所有专包项目数据
Cwdemc_yx_lxsqPagination baseProf = new Cwdemc_yx_lxsqPagination();
baseProf.setXmlx("03");
List<Cwdemc_yx_lxsqTreeVO> profProject = this.selectProjectData(baseProf);
//查询所有数据组成主专内三层项目树,先定义主包项目集合
List<Cwdemc_yx_lxsqTreeVO> mainPackageList = new ArrayList();
//2,先把内包放进专包中,在把专包放进主包中,最后再把主包放进list中,返回的list即是树形结构了
if (mainProject.size()>0 && profProject.size()>0 && profProject.size()>0){
mainProject.forEach(main ->{
mainPackageList.add(main);
List<Cwdemc_yx_lxsqTreeVO> profProjectList = new ArrayList<>();
profProject.forEach(prof -> {
if (prof.getSjxmid().equals(main.getXmid())){
profProjectList.add(prof);
main.setChildrenList(profProjectList);
List<Cwdemc_yx_lxsqTreeVO> innerProjectList = new ArrayList<>();
innerProject.forEach(inner -> {
innerProjectList.add(inner);
prof.setChildrenList(innerProjectList);
});
}
});
});
}
1, 典型递归构建树型列表
案例一
public List<Cwdemc_yx_lxsqEntity> getProjectListByXmid(String xmid) {
QueryWrapper<Cwdemc_yx_lxsqEntity> queryWrapper = new QueryWrapper<>();
UserInfo userInfo = userProvider.get();
// 默认查询条件:默认查询当前所在机构(orgid=)审批通过(flowstatus=2)并且未删除(delete!=1)的数据
queryWrapper.lambda()
.eq(Cwdemc_yx_lxsqEntity::getOrgid, userInfo.getOrganizeId())
.eq(Cwdemc_yx_lxsqEntity::getFlowstatus, FlowTaskStatusEnum.Adopt.getCode())
.ne(Cwdemc_yx_lxsqEntity::getDel, 1)
.eq(Cwdemc_yx_lxsqEntity::getChangeStatus, Constants.CHANGE_STATUS_NORMAL)
.isNotNull(Cwdemc_yx_lxsqEntity::getSjxmid);
List<Cwdemc_yx_lxsqEntity> list = this.list(queryWrapper);
List<Cwdemc_yx_lxsqEntity> sonList = new ArrayList<>();
findSon(xmid, list, sonList);
return sonList;
}
private void findSon(String sjxmid, List<Cwdemc_yx_lxsqEntity> allList, List<Cwdemc_yx_lxsqEntity> sonList) {
allList.forEach(son -> {
if (son.getSjxmid().equals(sjxmid)) {
sonList.add(son);
findSon(son.getXmid(), allList, sonList);
}
});
}
@ApiOperation("根据公司id获取下级公司及下级部门所有数据")
@GetMapping("/TreeById/{id}")
public ActionResult<ListVO<OrganizeTreeVO>> TreeById(@PathVariable("id") String id) {
// 查询选中机构
OrganizeEntity org = organizeService.getById(id);
//准备树结构VO
OrganizeTreeVO parent = new OrganizeTreeVO();
//把entity对象转为准备好的树结构对象
BeanUtils.copyProperties(org,parent);
//查询所有组织
List<OrganizeEntity> allList = organizeService.getList();
// 过滤无效数据
Iterator<OrganizeEntity> iterator = allList.iterator();
while (iterator.hasNext()) {
OrganizeEntity organizeEntity = iterator.next();
if (organizeEntity.getEnabledMark() != 1) {
iterator.remove();
}
if (organizeEntity.getDeleteMark() != null){
iterator.remove();
}
}
//把所有组织entity对象转为VO树结构对象
List<OrganizeTreeVO> allListVO = JsonUtil.getJsonToList(allList, OrganizeTreeVO.class);
// 遍历集合
allListVO.forEach(node->{
//找到所有数据中,我们要的顶级id
if(node.getId().equals(parent.getId())){
//找到顶级,开始递归找自己(需要两个容器:1,带children属性和顶级数据的树形对象。2,带所有数据的树形对象)
this.buildTree(parent,allListVO);
}
});
return ActionResult.success(parent);
}
//构建树的私有方法
private void buildTree(OrganizeTreeVO parent,List<OrganizeTreeVO> allListVO){
//实例化children对象
List<OrganizeTreeVO> children = new ArrayList<>();
//循环遍历传过来的所有数据
allListVO.forEach(node->{
//逐条,拿parentId,对比
if(node.getParentId().equals(parent.getId())){
//如果拿到的parentId等于顶级id,则拿到子数据,进入if
//将子数据加入进children对象中
children.add(node);
//每条数据都有可能有子数据,调用自己,把自己当做parent
buildTree(node,allListVO);
}
});
parent.setChildren(children);
}
2, 构建有层级编号的树结构
@Override
public List<ComfortEventTypesVO> getTreeList(ComfortEventTypesQuery query) {
if (StringUtils.isBlank(query.getTypeName())) {
// 直接查询全部未删除节点构建完整树
List<ComfortEventTypes> allNodes = baseMapper.selectList(
Wrappers.lambdaQuery(ComfortEventTypes.class)
.eq(ComfortEventTypes::getIsDelete, DELETE_0)
);
List<ComfortEventTypesVO> tree = buildTree(allNodes, "0", 1);
populateCreatorNames(tree);
return tree;
}
// 模糊查询符合条件的节点(可能是子节点)
LambdaQueryWrapper<ComfortEventTypes> wrapper = Wrappers.lambdaQuery(ComfortEventTypes.class)
.eq(ComfortEventTypes::getIsDelete, DELETE_0)
.like(StringUtils.isNotBlank(query.getTypeName()), ComfortEventTypes::getTypeName, query.getTypeName());
List<ComfortEventTypes> matchedNodes = baseMapper.selectList(wrapper);
if (matchedNodes.isEmpty()) {
return Collections.emptyList();
}
// 收集所有父节点ID(通过解析 pids 字段)
Set<String> parentIds = new HashSet<>();
for (ComfortEventTypes node : matchedNodes) {
if (StringUtils.isNotBlank(node.getPids())) {
Collections.addAll(parentIds, node.getPids().split(","));
}
}
// 获取已匹配节点的ID集合
Set<String> matchedNodeIds = matchedNodes.stream()
.map(ComfortEventTypes::getId)
.collect(Collectors.toSet());
// 查询所有父节点(排除已匹配的节点)
List<ComfortEventTypes> parentNodes = baseMapper.selectList(
Wrappers.lambdaQuery(ComfortEventTypes.class)
.in(ComfortEventTypes::getId, parentIds)
.eq(ComfortEventTypes::getIsDelete, DELETE_0)
.notIn(!matchedNodeIds.isEmpty(), ComfortEventTypes::getId, matchedNodeIds)
);
// 使用Map进行ID去重合并
Map<String, ComfortEventTypes> nodeMap = new LinkedHashMap<>();
matchedNodes.forEach(node -> nodeMap.put(node.getId(), node));
parentNodes.forEach(node -> nodeMap.putIfAbsent(node.getId(), node));
// 构建完整树形结构
List<ComfortEventTypesVO> tree = buildTree(new ArrayList<>(nodeMap.values()), "0", 1);
populateCreatorNames(tree);
return tree;
}
@Override
public Page<ComfortEventTypesVO> pageList(ComfortEventTypesPage query) {
return baseMapper.selectVoPage(Querys.page(query.getPageModel()), Querys.wrapper(query, ComfortEventTypes.class));
}
// 递归构建树形结构
private List<ComfortEventTypesVO> buildTree(List<ComfortEventTypes> nodes, String parentId, Integer level) {
return nodes.stream()
.filter(node -> parentId.equals(node.getParentId()))
.sorted(Comparator.comparing(ComfortEventTypes::getCreateTime).reversed())
.map(node -> {
ComfortEventTypesVO vo = convertToVO(node);
vo.setChildren(buildTree(nodes, node.getId(), level + 1));
vo.setLevel(level);
return vo;
}).collect(Collectors.toList());
}
// 实体转 VO
private ComfortEventTypesVO convertToVO(ComfortEventTypes entity) {
ComfortEventTypesVO vo = new ComfortEventTypesVO();
vo.setId(entity.getId());
vo.setTypeName(entity.getTypeName());
vo.setParentId(entity.getParentId());
vo.setPids(entity.getPids());
vo.setCreateTime(entity.getCreateTime());
vo.setCreateBy(entity.getCreateBy());
return vo;
}
用map纵横定位的方式实现树结构
Map<String,Cwdemc_yx_lxsqTreeVO> map = new HashMap();
List<Cwdemc_yx_lxsqTreeVO> mainPackageList = new ArrayList<>();
List<Cwdemc_yx_lxsqTreeVO> allProject = this.selectProjectData(cwdemc_yx_lxsqPagination);
allProject.forEach(all -> {
map.put(all.getXmid(),all);
});
allProject.forEach(project -> {
String pid = project.getSjxmid();
if (StringUtil.isNotEmpty(pid)) {
Cwdemc_yx_lxsqTreeVO o = map.get(pid);
if(Objects.nonNull(o)){
//上级对象的子级加入当前对象
o.getChildrenList().add(project);
}else{
if(StringUtil.isBlank(pid)){
//把当前对象加入定义好的list
mainPackageList.add(project);
}
}
} else {
mainPackageList.add(project);
}
});