Merge remote-tracking branch 'origin/feature/REQ-3282' into feature/REQ-3282

This commit is contained in:
zhanghonghao 2024-12-23 13:47:13 +08:00
commit 64b344310b
6 changed files with 222 additions and 59 deletions

View File

@ -15,58 +15,54 @@ import java.util.Set;
@Data @Data
@Builder @Builder
public class ListOrgCooperateShipReq { public class ListOrgCooperateShipReq {
public static final int FILTER_PERSON_TYPE_CURRENT_NODE = 1;
public static final int FILTER_PERSON_TYPE_CURRENT_AND_BELOW_NODE = 2;
/** /**
* 协同关系集合 * 协同关系集合
*/ */
@CriteriaField(field = "id", operator = Operator.IN)
@Builder.Default @Builder.Default
private Set<Long> ids = Collections.emptySet(); private Set<Long> ids = Collections.emptySet();
/** /**
* 工作台id * 工作台id
*/ */
@CriteriaField(field = "workspaceId", operator = Operator.IN)
@Builder.Default @Builder.Default
private Set<Long> workspaceIds = Collections.emptySet(); private Set<Long> workspaceIds = Collections.emptySet();
/** /**
* 工作台类型 * 工作台类型
*/ */
@CriteriaField(field = "workspaceType", operator = Operator.IN)
@Builder.Default @Builder.Default
private Set<Integer> workspaceTypes = Collections.emptySet(); private Set<Integer> workspaceTypes = Collections.emptySet();
/** /**
* 单位id集合(如果是班组则插入队伍id) * 单位id集合(如果是班组则插入队伍id)
*/ */
@CriteriaField(field = "organizationalUnitId", operator = Operator.IN)
@Builder.Default @Builder.Default
private Set<Long> ouIds = Collections.emptySet(); private Set<Long> ouIds = Collections.emptySet();
/** /**
* 指定的协同关系类型 * 指定的协同关系类型
*/ */
@CriteriaField(field = "cooperateType", operator = Operator.IN)
@Builder.Default @Builder.Default
private Set<Integer> includeCooperateTypes = Collections.emptySet(); private Set<Integer> includeCooperateTypes = Collections.emptySet();
/** /**
* 待排除的协同关系类型 * 待排除的协同关系类型
*/ */
@CriteriaField(field = "cooperateType", operator = Operator.NOT_IN)
@Builder.Default @Builder.Default
private Set<Integer> excludeCooperateTypes = Collections.emptySet(); private Set<Integer> excludeCooperateTypes = Collections.emptySet();
/** /**
* 节点id * 节点id
*/ */
@CriteriaField(field = "organizationalNodeId", operator = Operator.IN)
@Builder.Default @Builder.Default
private Set<Long> organizationNodeIds = Collections.emptySet(); private Set<Long> organizationNodeIds = Collections.emptySet();
/** /**
* 合作关系 1.合作 2.直属 * 合作关系 1.合作 2.直属
*/ */
@CriteriaField(field = "partnerShip", operator = Operator.IN)
@Builder.Default @Builder.Default
private Set<Integer> partnerShips = Collections.emptySet(); private Set<Integer> partnerShips = Collections.emptySet();
@ -74,62 +70,69 @@ public class ListOrgCooperateShipReq {
/** /**
* 在场状态集合 * 在场状态集合
*/ */
@CriteriaField(field = "status", operator = Operator.IN)
@Builder.Default @Builder.Default
private Set<Integer> statuses = Collections.emptySet(); private Set<Integer> statuses = Collections.emptySet();
@CriteriaField(field = "path", operator = Operator.SW) /**
* 查询策略使用取模方式自由组合进行数据查询
* 参数说明1当前节点 2父节点 4祖父节点 8子节点 16孙节点
* 案例查询当前节点及子孙节点则传3, 当前节点及祖父节点则传5当前节点
*/
@Builder.Default @Builder.Default
private Set<String> pathRight = Collections.emptySet(); private Integer selectStrategy = 1;
/** /**
* 需要过滤的personId * 需要过滤的personId
* personId * personId
*/ */
@CriteriaField(ignore = true) private Long filterByPersonId ;
private Long filterPersonId ;
/** /**
* 当personId有值时为必填项 * 当personId有值时为必填项
* 1只过滤当前节点数据 2过滤当前节点及以下数据 * 1只过滤当前节点数据 2过滤当前节点及以下数据
*/ */
@CriteriaField(ignore = true)
private Integer filterPersonType; private Integer filterPersonType;
/** /**
* 是否过滤工人 * 是否过滤工人
*/ */
@CriteriaField(ignore = true)
@Builder.Default @Builder.Default
private Boolean isFilterWorker = false; private Boolean isFilterWorker = false;
/** /**
* 人员过滤是否包含已退场 * 人员过滤是否包含已退场
*/ */
@CriteriaField(ignore = true)
@Builder.Default @Builder.Default
private Boolean includeExitPerson = false; private Boolean includeExitPerson = false;
/** /**
* 是否查询祖先节点 * 是否包含祖先节点
*/ */
@CriteriaField(ignore = true)
@Builder.Default @Builder.Default
private Boolean isSelectAncestors = false; private Boolean includeAncestors = false;
/** /**
* 是否查询子孙节点 * 是否包含子孙节点
*/ */
@CriteriaField(ignore = true)
@Builder.Default @Builder.Default
private Boolean isSelectDescendants = false; private Boolean includeDescendants = false;
/**
* 是否包含父节点
*/
@Builder.Default
private Boolean includeParent = false;
/**
* 是否包含子节点
*/
@Builder.Default
private Boolean includeChildren = false;
/** /**
* 条件当需要查询上下级数据时启用 * 条件当需要查询上下级数据时启用
* 是否只查一级 * 是否只查一级
*/ */
@CriteriaField(ignore = true)
@Builder.Default @Builder.Default
private Boolean isSelectLevelOne = false; private Boolean isSelectLevelOne = false;

View File

@ -1,21 +1,22 @@
package cn.axzo.orgmanax.infra.dao.cooperateship.repository; package cn.axzo.orgmanax.infra.dao.cooperateship.repository;
import cn.axzo.foundation.dao.support.wrapper.CriteriaField;
import cn.axzo.foundation.dao.support.wrapper.Operator;
import cn.axzo.orgmanax.api.cooperateship.req.ListOrgCooperateShipReq; import cn.axzo.orgmanax.api.cooperateship.req.ListOrgCooperateShipReq;
import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip; import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import lombok.AllArgsConstructor; import lombok.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder; import lombok.experimental.SuperBuilder;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
public interface CooperateShipQueryRepository { public interface CooperateShipQueryRepository {
List<SaasCooperateShip> list(ListOrgCooperateShipReq req); List<SaasCooperateShip> list(ListReq req);
default SaasCooperateShip one(OneReq req) { default SaasCooperateShip one(OneReq req) {
return oneOpt(req).orElse(null); return oneOpt(req).orElse(null);
@ -23,7 +24,7 @@ public interface CooperateShipQueryRepository {
default Optional<SaasCooperateShip> oneOpt(OneReq req) { default Optional<SaasCooperateShip> oneOpt(OneReq req) {
req.check(); req.check();
ListOrgCooperateShipReq listReq = BeanUtil.toBean(req, ListOrgCooperateShipReq.class); ListReq listReq = BeanUtil.toBean(req, ListReq.class);
return list(listReq).stream().findFirst(); return list(listReq).stream().findFirst();
} }
@ -50,4 +51,87 @@ public interface CooperateShipQueryRepository {
private String todo; private String todo;
} }
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
class ListReq {
/**
* 协同关系集合
*/
@CriteriaField(field = "id", operator = Operator.IN)
@Builder.Default
private Set<Long> ids = Collections.emptySet();
/**
* 工作台id
*/
@CriteriaField(field = "workspaceId", operator = Operator.IN)
@Builder.Default
private Set<Long> workspaceIds = Collections.emptySet();
/**
* 工作台类型
*/
@CriteriaField(field = "workspaceType", operator = Operator.IN)
@Builder.Default
private Set<Integer> workspaceTypes = Collections.emptySet();
/**
* 单位id集合(如果是班组则插入队伍id)
*/
@CriteriaField(field = "organizationalUnitId", operator = Operator.IN)
@Builder.Default
private Set<Long> ouIds = Collections.emptySet();
/**
* 指定的协同关系类型
*/
@CriteriaField(field = "cooperateType", operator = Operator.IN)
@Builder.Default
private Set<Integer> includeCooperateTypes = Collections.emptySet();
/**
* 待排除的协同关系类型
*/
@CriteriaField(field = "cooperateType", operator = Operator.NOT_IN)
@Builder.Default
private Set<Integer> excludeCooperateTypes = Collections.emptySet();
/**
* 节点id
*/
@CriteriaField(field = "organizationalNodeId", operator = Operator.IN)
@Builder.Default
private Set<Long> organizationNodeIds = Collections.emptySet();
/**
* 合作关系 1.合作 2.直属
*/
@CriteriaField(field = "partnerShip", operator = Operator.IN)
@Builder.Default
private Set<Integer> partnerShips = Collections.emptySet();
/**
* 在场状态集合
*/
@CriteriaField(field = "status", operator = Operator.IN)
@Builder.Default
private Set<Integer> statuses = Collections.emptySet();
/**
* path右值
*/
@CriteriaField(field = "path", operator = Operator.IN)
@Builder.Default
private Set<String> pathsRight = Collections.emptySet();
/**
* path右值
*/
@CriteriaField(field = "parentId", operator = Operator.IN)
@Builder.Default
private Set<Long> parentIds = Collections.emptySet();
}
} }

View File

@ -8,6 +8,8 @@ import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip;
import cn.axzo.orgmanax.infra.dao.cooperateship.repository.CooperateShipQueryRepository; import cn.axzo.orgmanax.infra.dao.cooperateship.repository.CooperateShipQueryRepository;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository; import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -27,26 +29,36 @@ public class CooperateShipQueryRepositoryImpl implements CooperateShipQueryRepos
private final NodeUserQueryRepository nodeUserQueryRepository; private final NodeUserQueryRepository nodeUserQueryRepository;
@Override @Override
public List<SaasCooperateShip> list(ListOrgCooperateShipReq req) { public List<SaasCooperateShip> list(CooperateShipQueryRepository.ListReq req) {
QueryWrapper<SaasCooperateShip> wrapper = QueryWrapperHelper.fromBean(req, SaasCooperateShip.class); QueryWrapper<SaasCooperateShip> wrapper = QueryWrapperHelper.fromBean(req, SaasCooperateShip.class);
if (wrapper.isEmptyOfWhere()) { if (wrapper.isEmptyOfWhere()) {
// //
log.warn("CooperateShipResp empty of where query. return empty list. req = {}", req); log.warn("CooperateShipResp empty of where query. return empty list. req = {}", req);
return Collections.emptyList(); return Collections.emptyList();
} }
// 查询子集
if (CollUtil.isNotEmpty(req.getPathsRight())) {
// 遍历pathsRight转换成wrapper
wrapper.and(w -> {
for (String pathRight : req.getPathsRight()) {
w.or().likeRight("path", pathRight);
}
});
}
return cooperateShipDao.list(wrapper) return cooperateShipDao.list(wrapper)
.stream().map(e -> BeanUtil.toBean(e, SaasCooperateShip.class)).collect(Collectors.toList()); .stream().map(e -> BeanUtil.toBean(e, SaasCooperateShip.class)).collect(Collectors.toList());
} }
private List<SaasCooperateShip> filterByPersonIds(List<SaasCooperateShip> results, ListOrgCooperateShipReq req) { private List<SaasCooperateShip> filterByPersonIds(List<SaasCooperateShip> results, ListOrgCooperateShipReq req) {
if (req.getFilterPersonId() == null) { if (req.getFilterByPersonId() == null) {
// filter by personIds // filter by personIds
return results; return results;
} }
Set<Long> organizationalNodeIds = results.stream().map(SaasCooperateShip::getOrganizationalNodeId).collect(Collectors.toSet()); Set<Long> organizationalNodeIds = results.stream().map(SaasCooperateShip::getOrganizationalNodeId).collect(Collectors.toSet());
Set<Long> personInNodeIds = nodeUserQueryRepository.list(ListNodeUserReq.builder() Set<Long> personInNodeIds = nodeUserQueryRepository.list(ListNodeUserReq.builder()
.personId(req.getFilterPersonId()) .personId(req.getFilterByPersonId())
.organizationalNodeIds(organizationalNodeIds) .organizationalNodeIds(organizationalNodeIds)
.build()) .build())
.stream().map(NodeUserQueryRepository.NodeUserResp::getTopNodeId).collect(Collectors.toSet()); .stream().map(NodeUserQueryRepository.NodeUserResp::getTopNodeId).collect(Collectors.toSet());

View File

@ -20,4 +20,19 @@ public interface CooperateShipFoundationService {
* @return * @return
*/ */
Set<Long> extractAncestorIds(List<SaasCooperateShip> list); Set<Long> extractAncestorIds(List<SaasCooperateShip> list);
/**
* 提取path数据
* @param list 当前节点
* @param suffix 后缀
* @return
*/
Set<String> extractPaths(List<SaasCooperateShip> list, String suffix);
/**
* 提取父级id
* @param currentNodeList
* @return
*/
Set<Long> extractParentIds(List<SaasCooperateShip> currentNodeList);
} }

View File

@ -4,6 +4,7 @@ import cn.axzo.orgmanax.api.nodeuser.req.ListNodeUserReq;
import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip; import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository; import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository;
import cn.axzo.orgmanax.server.cooperateship.foundation.CooperateShipFoundationService; import cn.axzo.orgmanax.server.cooperateship.foundation.CooperateShipFoundationService;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -41,4 +42,14 @@ public class CooperateShipFoundationServiceImpl implements CooperateShipFoundati
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
@Override
public Set<String> extractPaths(List<SaasCooperateShip> list, String suffix) {
return list.stream().map(t -> StrUtil.isNotBlank(suffix) ? StrUtil.concat(true, t.getPath(), suffix) : t.getPath()).collect(Collectors.toSet());
}
@Override
public Set<Long> extractParentIds(List<SaasCooperateShip> list) {
return list.stream().filter(t -> t.getParentId() != 0).map(SaasCooperateShip::getParentId).collect(Collectors.toSet());
}
} }

View File

@ -126,44 +126,82 @@ public class CooperateShipServiceImpl implements CooperateShipService {
@Override @Override
public List<OrgCooperateShipDTO> list(ListOrgCooperateShipReq req) { public List<OrgCooperateShipDTO> list(ListOrgCooperateShipReq req) {
// 是否查询当前节点的人员 // 全局变量定义是否查询当前节点的人员
boolean isFilterCurrentNodeByPerson = ObjectUtil.isNotNull(req.getFilterPersonId()) && Objects.equals(req.getFilterPersonType(), 1); boolean isFilterCurrentNodeByPerson = ObjectUtil.isNotNull(req.getFilterByPersonId()) &&
// 是否查询当前节点及以下节点的人员 Objects.equals(req.getFilterPersonType(), ListOrgCooperateShipReq.FILTER_PERSON_TYPE_CURRENT_NODE);
boolean isFilterCurrentAndBelowByPerson = !isFilterCurrentNodeByPerson && ObjectUtil.isNotNull(req.getFilterPersonId()) && Objects.equals(req.getFilterPersonType(), 2); // 全局变量定义是否查询当前节点及以下节点的人员
boolean isFilterCurrentAndBelowByPerson = !isFilterCurrentNodeByPerson && ObjectUtil.isNotNull(req.getFilterByPersonId())
&& Objects.equals(req.getFilterPersonType(), ListOrgCooperateShipReq.FILTER_PERSON_TYPE_CURRENT_AND_BELOW_NODE);
// 1. 根据入参查询数据 // 根据入参查询数据
List<SaasCooperateShip> list = cooperateShipQueryRepository.list(req); List<SaasCooperateShip> currentNodeList = cooperateShipQueryRepository.list(
if (CollUtil.isEmpty(list)) { CooperateShipQueryRepository.ListReq.builder()
.ids(req.getIds())
.workspaceIds(req.getWorkspaceIds())
.workspaceTypes(req.getWorkspaceTypes())
.ouIds(req.getOuIds())
.includeCooperateTypes(req.getIncludeCooperateTypes())
.excludeCooperateTypes(req.getExcludeCooperateTypes())
.organizationNodeIds(req.getOrganizationNodeIds())
.partnerShips(req.getPartnerShips())
.statuses(req.getStatuses())
.build());
if (CollUtil.isEmpty(currentNodeList)) {
return Collections.emptyList(); return Collections.emptyList();
} }
// 根据person过滤当前节点 // 根据person过滤当前节点
if (isFilterCurrentNodeByPerson) { if (isFilterCurrentNodeByPerson) {
cooperateShipFoundationService.filterByPerson(req.getFilterPersonId(), list); cooperateShipFoundationService.filterByPerson(req.getFilterByPersonId(), currentNodeList);
if (CollUtil.isEmpty(currentNodeList)) {
return Collections.emptyList();
}
} }
// 是否查询祖先 // 构建结果节点集合
if (BooleanUtil.isTrue(req.getIsSelectAncestors())) { List<SaasCooperateShip> resultNodeList = new ArrayList<>(currentNodeList);
Set<Long> ancestorIds = cooperateShipFoundationService.extractAncestorIds(list);
List<SaasCooperateShip> ancestorShipNodes = cooperateShipQueryRepository.list(ListOrgCooperateShipReq.builder().ids(ancestorIds).build()); // 是否查询祖先节点
list.addAll(ancestorShipNodes); if (BooleanUtil.isTrue(req.getIncludeParent())) {
Set<Long> parentIds = cooperateShipFoundationService.extractParentIds(currentNodeList);
List<SaasCooperateShip> ancestorShipNodes = cooperateShipQueryRepository.list(CooperateShipQueryRepository.ListReq.builder().ids(parentIds).build());
resultNodeList.addAll(ancestorShipNodes);
} }
// 是否查询子孙 // 是否查询父级节点
if (BooleanUtil.isTrue(req.getIsSelectDescendants())) { if (BooleanUtil.isTrue(req.getIncludeAncestors())) {
List<SaasCooperateShip> descendantShipNodes = cooperateShipQueryRepository.list(ListOrgCooperateShipReq.builder().build()); Set<Long> ancestorIds = cooperateShipFoundationService.extractAncestorIds(currentNodeList);
// list.addAll(descendantShipNodes); List<SaasCooperateShip> ancestorShipNodes = cooperateShipQueryRepository.list(CooperateShipQueryRepository.ListReq.builder().ids(ancestorIds).build());
resultNodeList.addAll(ancestorShipNodes);
}
// 是否查询子节点
if (BooleanUtil.isTrue(req.getIncludeChildren())) {
Set<String> paths = cooperateShipFoundationService.extractPaths(currentNodeList, ",");
List<SaasCooperateShip> descendantShipNodes = cooperateShipQueryRepository.list(
CooperateShipQueryRepository.ListReq.builder()
.pathsRight(paths).build());
resultNodeList.addAll(descendantShipNodes);
// 是否查询当前节点及以下节点的人员
if (isFilterCurrentAndBelowByPerson) {
cooperateShipFoundationService.filterByPerson(req.getFilterByPersonId(), resultNodeList);
}
}
// 是否查询子孙节点
if (BooleanUtil.isTrue(req.getIncludeDescendants())) {
Set<Long> parentIds = cooperateShipFoundationService.extractParentIds(currentNodeList);
List<SaasCooperateShip> descendantShipNodes = cooperateShipQueryRepository.list(
CooperateShipQueryRepository.ListReq.builder()
.parentIds(parentIds).build());
resultNodeList.addAll(descendantShipNodes);
// 是否查询当前节点及以下节点的人员
if (isFilterCurrentAndBelowByPerson) {
cooperateShipFoundationService.filterByPerson(req.getFilterByPersonId(), resultNodeList);
}
} }
return BeanUtil.copyToList(resultNodeList, OrgCooperateShipDTO.class);
// 根据person过滤当前节点及以下节点
if (isFilterCurrentAndBelowByPerson) {
cooperateShipFoundationService.filterByPerson(req.getFilterPersonId(), list);
}
return BeanUtil.copyToList(list, OrgCooperateShipDTO.class);
} }
} }