需求:按组织树和岗位树查询。(组织org 和岗位都在机构下)
问题是:机构树查询出来的是全部的组织机构,需求是按人员所在机构,岗位展示树(把不在学员列表多余的组织和岗位节点删除):
上图可理解如下图: nodepath 会显示当前节点的所有父节点:nodePath=1785.1786.1787.1788
如标记的无效节点为:
2021-12-02 13:20:06.117 INFO 40468 --- [qtp335196473-36] c.g.b.m.service.impl.AgencyServiceImpl : invalidPostList:[PostTreeResponse(id=1785, name=默认岗位组, title=默认岗位组, key=1785, level=1, postType=group, userNum=4, nodePath=1785, parentId=0, disabled=true, children=[PostTreeResponse(id=1786, name=默认岗位组, title=默认岗位组, key=1786, level=2, postType=group, userNum=4, nodePath=1785.1786, parentId=1785, disabled=true, children=[PostTreeResponse(id=1787, name=默认岗位组, title=默认岗位组, key=1787, level=3, postType=group, userNum=4, nodePath=1785.1786.1787, parentId=1786, disabled=true, children=[PostTreeResponse(id=1788, name=默认岗位, title=默认岗位, key=1788, level=4, postType=post, userNum=4, nodePath=1785.1786.1787.1788, parentId=1787, disabled=false, children=[])])])]), PostTreeResponse(id=1801, name=高顿机构, title=高顿机构, key=1801, level=1, postType=group, userNum=40, nodePath=1801, parentId=0, disabled=true, children=[PostTreeResponse(id=1802, name=高顿机构, title=高顿机构, key=1802, level=2, postType=post, userNum=40, nodePath=1801.1802, parentId=1801, disabled=false, children=[])]), PostTreeResponse(id=9502, name=哈哈哈, title=哈哈哈, key=9502, level=1, postType=group, userNum=2, nodePath=9502, parentId=0, disabled=true, children=[PostTreeResponse(id=9503, name=发发发, title=发发发, key=9503, level=2, postType=post, userNum=2, nodePath=9502.9503, parentId=9502, disabled=false, children=[])])]
/**
* @Title: 根据班级id批量查询学员岗位
* @Author: ken
* @Description:
* @Date: 2021/9/17 19:41
* @Param: [gradeId]
* @return com.gaodun.bcloud.mstat.response.BaseResponse<java.util.List<com.gaodun.bcloud.mstat.controller.response.agency.AgencyPostResponse>>
**/
@Override
public BaseResponse<List<AgencyPostResponse>> getPostListByGradeId(Long gradeId) {
BaseResponse<List<AgencyPostResponse>> result = agencySvcClient.getPostListByAgencyIdList(gradeMemberRepository.findAgencyIdsByGradeId(gradeId));
List<AgencyPostResponse> agencyPostResponseList = result.getResult();
if(CollectionUtils.isEmpty(agencyPostResponseList)) {
return BaseResponse.failureEnum(HttpErrorCodes.NO_DATA);
}
List<Long> userIdList = gradeMemberRepository.findAllByGradeId(gradeId);
Pageable pageable = PageUtil.getPageable(1, Constants.DEFAULT_MAX_PAGE_SIZE);
Page<BaseUserInfoDTO> userInfoPage = agcUsersEntityRepository.findPageByCondition(userIdList, null, null,
null, null, pageable);
if (Objects.isNull(userInfoPage) || CollectionUtils.isEmpty(userInfoPage.getContent())) {
return BaseResponse.failureEnum(HttpErrorCodes.NO_DATA);
}
List<BaseUserInfoDTO> content = userInfoPage.getContent();
Set<Long> postIdSet = content.stream().map(BaseUserInfoDTO::getPostId).filter(Objects::nonNull).collect(Collectors.toSet());
// 查找岗位节点
List<AgcPostListEntity> postList = postListRepository.findAllAgcPostList(postIdSet);
if(CollectionUtils.isEmpty(postList)){
return BaseResponse.failureEnum(HttpErrorCodes.NO_DATA);
}
List<String> nodePathList = postList.stream().map(AgcPostListEntity::getNodePath).collect(Collectors.toList());
// 标记删除节点
List<PostTreeResponse> invalidPostList = Lists.newArrayList();
for (AgencyPostResponse agencyPostResponse : agencyPostResponseList) {
List<PostTreeResponse> postTreeResponseList = agencyPostResponse.getPost();
markDelPostNode(nodePathList, postTreeResponseList, invalidPostList);
}
log.info("invalidPostList:{}",invalidPostList.toString());
// 删除节点
for(PostTreeResponse invalidNode: invalidPostList) {
for (AgencyPostResponse agencyPostResponse : agencyPostResponseList) {
List<PostTreeResponse> postTreeResponseList = agencyPostResponse.getPost();
deletePostNode(invalidNode, postTreeResponseList);
}
}
agencyPostResponseList.removeIf(s -> CollectionUtils.isEmpty(s.getPost()));
return BaseResponse.success(agencyPostResponseList);
}
/**
* @Title: 根据机构id批量查询学员组织
* @Author: ken
* @Description: 遍历traverse
* @Date: 2021/9/17 19:57
* @Param: [gradeId]
* @return com.gaodun.bcloud.mstat.response.BaseResponse<java.util.List<com.gaodun.bcloud.mstat.controller.response.agency.AgencyOrganizationResponse>>
**/
@Override
public BaseResponse<List<AgencyOrganizationResponse>> getOrganizationListByGradeId(Long gradeId) {
List<Long> userIdList = gradeMemberRepository.findAllByGradeId(gradeId);
//批量查询用户组织(部门)信息
List<UserOrganizationDTO> userOrganizationDTOList = agcUserOrganizationRepository.findByUserIdsOrAgencyId(userIdList, null);
if(CollectionUtils.isEmpty(userOrganizationDTOList)){
return BaseResponse.failureEnum(HttpErrorCodes.NO_DATA);
}
//查询用户组织树
Set<Long> orgIds = userOrganizationDTOList.stream().map(i -> i.getOrgId()).collect(Collectors.toSet());
BaseResponse<List<AgencyOrganizationResponse>> result = agencySvcClient.getOrganizationListByAgencyIdList(gradeMemberRepository.findAgencyIdsByGradeId(gradeId));
if(Objects.isNull(result) || CollectionUtils.isEmpty(result.getResult())){
return BaseResponse.failureEnum(HttpErrorCodes.NO_DATA);
}
List<AgencyOrganizationResponse> agencyOrganizationResponseList = result.getResult();
// 查找学员组织节点
List<String> nodePathList = Lists.newArrayList();
for(Long orgId: orgIds) {
for (AgencyOrganizationResponse agencyOrganizationResponse : agencyOrganizationResponseList) {
List<OrganizationResponse> organizationList = agencyOrganizationResponse.getOrganization();
traverseOrgTree(nodePathList, orgId, organizationList);
}
}
// 标记删除节点
List<OrganizationResponse> invalidNodeList = Lists.newArrayList();
for (AgencyOrganizationResponse agencyOrganizationResponse : agencyOrganizationResponseList) {
List<OrganizationResponse> organizationList = agencyOrganizationResponse.getOrganization();
markDelOrgNode(nodePathList, organizationList, invalidNodeList);
}
//log.info("invalidNodeList:{}",invalidNodeList.toString());
// 删除节点
for(OrganizationResponse invalidNode: invalidNodeList) {
for (AgencyOrganizationResponse agencyOrganizationResponse : agencyOrganizationResponseList) {
List<OrganizationResponse> organizationList = agencyOrganizationResponse.getOrganization();
deleteOrgNode(invalidNode, organizationList);
}
}
//log.info("agencyOrganizationResponseList:{}",agencyOrganizationResponseList.toString());
return BaseResponse.success(agencyOrganizationResponseList);
}
/**
* @Title: 遍历树
* @Author: ken
* @Description:
* @Date: 2021/12/2 10:35
* @Param: [nodePathList, orgId, organizationList]
* @return void
**/
private void traverseOrgTree(List<String> nodePathList, Long orgId, List<OrganizationResponse> organizationList) {
for(OrganizationResponse organizationResponse :organizationList){
if(organizationResponse.getNodePath().endsWith(String.valueOf(orgId))){
nodePathList.add(organizationResponse.getNodePath());
continue;
}else if(CollectionUtils.isEmpty(organizationResponse.getChildren())){
continue;
}else{
traverseOrgTree(nodePathList,orgId,organizationResponse.getChildren());
}
}
}
/**
* @Title: 标记无效节点
* @Author: ken
* @Description:
* @Date: 2021/12/2 10:34
* @Param: [nodePathList, organizationList, invalidNodeList]
* @return void
**/
private void markDelOrgNode(List<String> nodePathList, List<OrganizationResponse> organizationList, List<OrganizationResponse> invalidNodeList) {
for(OrganizationResponse organizationResponse : organizationList){
// 是否在路径标识
boolean pathFlag = nodePathList .stream().anyMatch(x-> x.startsWith(organizationResponse.getNodePath()));
if(!pathFlag){
invalidNodeList.add(organizationResponse);
continue;
}else if(CollectionUtils.isEmpty(organizationResponse.getChildren())){
continue;
}else{
markDelOrgNode(nodePathList,organizationResponse.getChildren(),invalidNodeList);
}
}
}
/**
* @Title: 删除节点
* @Author: ken
* @Description:
* @Date: 2021/12/2 10:34
* @Param: [invalidNode, organizationList]
* @return void
**/
private void deleteOrgNode(OrganizationResponse invalidNode, List<OrganizationResponse> organizationList) {
for(OrganizationResponse organizationResponse :organizationList){
//找到父节点
if(organizationResponse.getId().equals(invalidNode.getParentId())){
List<OrganizationResponse> childList = organizationResponse.getChildren();
//移除无效节点
childList.removeIf(s -> s.getId().equals(invalidNode.getId()));
organizationResponse.setChildren(childList);
continue;
}else if(CollectionUtils.isEmpty(organizationResponse.getChildren())){
continue;
}else{
deleteOrgNode(invalidNode, organizationResponse.getChildren());
}
}
}
/**
* @Title: 遍历过滤组织(部门)树
* @Author: ken
* @Description:
* @Date: 2021/12/1 11:12
* @Param: [orgId, organizationList]
* @return java.util.List<com.gaodun.bcloud.mstat.controller.response.agency.OrganizationResponse>
**/
private List<OrganizationResponse> traverseOrgTree(Long orgId, List<OrganizationResponse> organizationList,
List<OrganizationResponse> organizationResponseLists) {
for(OrganizationResponse organizationResponse : organizationList){
if(orgId.equals(organizationResponse.getId())){
organizationResponse.setChildren(null);
organizationResponseLists.add(organizationResponse);
}else if(!CollectionUtils.isEmpty(organizationResponse.getChildren())){
traverseOrgTree(orgId, organizationResponse.getChildren(),organizationResponseLists);
}else{
log.info("@@ no node");
}
}
return organizationResponseLists;
}
/**
* @Title: 标记无效节点
* @Author: ken
* @Description:
* @Date: 2021/12/2 13:18
* @Param: [nodePathList, postTreeResponseList, invalidPostList]
* @return void
**/
private void markDelPostNode(List<String> nodePathList, List<PostTreeResponse> postTreeResponseList, List<PostTreeResponse> invalidPostList) {
for(PostTreeResponse postTreeResponse :postTreeResponseList){
// 是否在路径标识
boolean pathFlag = nodePathList .stream().anyMatch(x-> x.startsWith(postTreeResponse.getNodePath()));
if(!pathFlag){
invalidPostList.add(postTreeResponse);
continue;
}else if(CollectionUtils.isEmpty(postTreeResponse.getChildren())){
continue;
}else{
markDelPostNode(nodePathList,postTreeResponse.getChildren(),invalidPostList);
}
}
}
/**
* @Title: 删除无效节点
* @Author: ken
* @Description:
* @Date: 2021/12/2 13:18
* @Param: [invalidNode, postTreeResponseList]
* @return void
**/
private void deletePostNode(PostTreeResponse invalidNode, List<PostTreeResponse> postTreeResponseList) {
//对于没有父节点的 特殊处理
postTreeResponseList.removeIf(s -> s.getParentId().equals(0L) && s.getNodePath().equals(invalidNode.getNodePath()));
if(CollectionUtils.isEmpty(postTreeResponseList)){
return;
}
for(PostTreeResponse postTreeResponse :postTreeResponseList){
//对于没有父节点的
postTreeResponseList.removeIf(s -> s.getParentId().equals(0L) && s.getNodePath().equals(invalidNode.getNodePath()));
//找到父节点
if(postTreeResponse.getId().equals(invalidNode.getParentId())){
List<PostTreeResponse> childList = postTreeResponse.getChildren();
//移除无效节点
childList.removeIf(s -> s.getId().equals(invalidNode.getId()));
postTreeResponse.setChildren(childList);
continue;
}else if(CollectionUtils.isEmpty(postTreeResponse.getChildren())){
continue;
}else{
deletePostNode(invalidNode, postTreeResponse.getChildren());
}
}
}
核心思路:
① 找到节点
② 标记删除的节点
③ 删除节点。(切断当前节点跟父节点的联系,注意判断是否是父节点)
最终效果图: