feat(REQ-3488): 完善一批NodeUserApi.list查询条件

This commit is contained in:
周敏 2025-01-03 18:49:58 +08:00
parent 7410b12c35
commit 3b0c7d63a1
11 changed files with 319 additions and 22 deletions

View File

@ -32,7 +32,7 @@ public class NodeUserProfile {
/** /**
* 状态0未激活 1已激活 3已退场 * 状态0未激活 1已激活 3已退场
*/ */
private Integer status; private Integer projectWorkerStatus;
/** /**
* 工种类别 * 工种类别
*/ */

View File

@ -204,19 +204,20 @@ public class ListNodeUserReq extends PageReqV2 {
/** /**
* 状态1未激活 2已激活 3施工中 4已退场 * 状态1未激活 2已激活 3施工中 4已退场
*/ */
private Collection<Integer> projectWorkerStatuses; // TODO: 待实现 private Collection<Integer> projectWorkerStatuses;
/** /**
* orgUserStatus * orgUserStatus
*/ */
private Collection<String> orgUserStatus; // TODO: 待实现 private Collection<Integer> orgUserStatuses; // TODO: 待实现具体看如何使用的 condition还是filter
// ~ 不同部门类型的nodeUser的差异化查询字段 项目内工人 项目班组id平台班组id等 start // ~ 不同部门类型的nodeUser的差异化查询字段 项目内工人 项目班组id平台班组id等 start
private Long platTeamId; // TODO: 待实现 private Long platTeamId;
private Long projectTeamId; // TODO: 待实现 private Long projectTeamId;
private Collection<Long> projectTeamIds; // TODO: 待实现 private Collection<Long> projectTeamIds;
private Long projectWorkerId; // TODO: 待实现 private Long projectWorkerId;
private Long projectGroupId; // TODO: 待实现 private Collection<Long> projectWorkerIds;
private Long projectGroupId;
// ~ 结束 // ~ 结束
@ -224,6 +225,7 @@ public class ListNodeUserReq extends PageReqV2 {
/** /**
* 包含的单位类型 * 包含的单位类型
* XXXfilter的参数会破坏分页如有强分页场景需谨慎使用 * XXXfilter的参数会破坏分页如有强分页场景需谨慎使用
* @see cn.axzo.orgmanax.dto.unit.enums.OrganizationalUnitTypeEnum
*/ */
private Collection<Integer> filterIncludeUnitTypes; private Collection<Integer> filterIncludeUnitTypes;
/** /**
@ -264,7 +266,7 @@ public class ListNodeUserReq extends PageReqV2 {
/** /**
* 数据权限 * 数据权限
*/ */
private String dataPermissionCacheKey; // TODO: 待实现 private String dataPermissionCacheKey;
// ~ 不同部门类型的nodeUser的差异化查询字段 项目内工人 项目班组id平台班组id等 end // ~ 不同部门类型的nodeUser的差异化查询字段 项目内工人 项目班组id平台班组id等 end
/** /**

View File

@ -2,15 +2,22 @@ package cn.axzo.orgmanax.infra.client;
import cn.axzo.foundation.exception.BusinessException; import cn.axzo.foundation.exception.BusinessException;
import cn.axzo.foundation.result.ApiResult; import cn.axzo.foundation.result.ApiResult;
import cn.axzo.foundation.util.TraceUtils;
import cn.axzo.orgmanax.common.config.BizResultCode; import cn.axzo.orgmanax.common.config.BizResultCode;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.http.HttpStatus; import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import java.util.Objects; import java.util.Objects;
import java.util.function.Supplier; import java.util.function.Supplier;
@Slf4j
public class RpcWrapper { public class RpcWrapper {
public static final ImmutableMap<String, String> UN_DESCRIBE_PARAMS = ImmutableMap.of("param", "未定义");
/** /**
* Api result 返回 * Api result 返回
* @param supplier * @param supplier
@ -18,14 +25,49 @@ public class RpcWrapper {
* @param <T> * @param <T>
*/ */
public static <T> T wrapApiResult(Supplier<ApiResult<T>> supplier) { public static <T> T wrapApiResult(Supplier<ApiResult<T>> supplier) {
ApiResult<T> result = supplier.get(); return wrapApiResult(supplier, "", UN_DESCRIBE_PARAMS, false);
if (result == null) { }
throw new BusinessException(BizResultCode.RPC_ERROR);
/**
* Api result 返回
*
* @param supplier
* @param <T>
* @return
*/
public static <T> T wrapApiResult(Supplier<ApiResult<T>> supplier, String desc, Object params) {
return wrapApiResult(supplier, desc, params, true);
}
/**
* Api result 返回
*
* @param supplier
* @param <T>
* @return
*/
public static <T> T wrapApiResult(Supplier<ApiResult<T>> supplier, String desc, Object params, boolean logEnabled) {
ApiResult<T> result = null;
try {
if (logEnabled) {
log.info(TraceUtils.getOrCreateTraceId(), "RPC调用开始接口描述{},入参:{}", desc, JSON.toJSONString(params));
}
result = supplier.get();
if (result == null) {
throw new BusinessException(BizResultCode.RPC_ERROR);
}
if (!Objects.equals(result.getCode(), HttpStatus.HTTP_OK)) {
throw new BusinessException(Convert.toStr(result.getCode()), result.getMsg(), null);
}
T data = result.getData();
if (logEnabled) {
log.info(TraceUtils.getOrCreateTraceId(), "RPC调用结束接口描述{},入参:{}result{}", desc, JSON.toJSONString(params), JSON.toJSONString(result));
}
return data;
} catch (Throwable e) {
log.warn("RPC调用异常接口描述{},入参:{}result{}", desc, JSON.toJSONString(params), JSON.toJSONString(result));
throw e;
} }
if (!Objects.equals(result.getCode(), HttpStatus.HTTP_OK)) {
throw new BusinessException(Convert.toStr(result.getCode()), result.getMsg(), null);
}
return result.getData();
} }
} }

View File

@ -0,0 +1,22 @@
package cn.axzo.orgmanax.infra.client.karma;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class GetMergeMatchDataReq {
/**
* 规则解析后的key
*/
@NotBlank(message = "规则解析后的key不能为空")
private String resultKey;
}

View File

@ -0,0 +1,21 @@
package cn.axzo.orgmanax.infra.client.karma;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
/**
* @author likunpeng
* @version 1.0
* @date 2024/7/15
*/
public interface KarmaDataObjectClient {
/**
* 从缓存中查询数据权限规则解析结果
*
* @param request
* @return
*/
MergeMatchDataResp getCached(@Validated @RequestBody GetMergeMatchDataReq request);
}

View File

@ -0,0 +1,36 @@
package cn.axzo.orgmanax.infra.client.karma;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
@Slf4j
@RequiredArgsConstructor
public class KarmaDataObjectGateway {
private static final MergeMatchDataResp LOAD_PERMISSION_FAILED_DEFAULT_RESP = MergeMatchDataResp.builder()
.dataItems(ImmutableList.of(MergeMatchDataResp.DataItem.builder().nodeId(-10099L).build()))
.build();
private final KarmaDataObjectClient karmaDataObjectClient;
public Optional<MergeMatchDataResp> getCached(String resultKey) {
if (Strings.isNullOrEmpty(resultKey)) {
return Optional.empty();
}
try {
MergeMatchDataResp cached = karmaDataObjectClient.getCached(GetMergeMatchDataReq.builder().resultKey(resultKey).build());
if (cached != null) {
return Optional.of(cached);
}
} catch (Throwable e) {
log.error("缓存中获取数据权限失败resultKey = {}请检查karma服务是否正常。", resultKey, e);
}
log.error("缓存中获取数据权限失败resultKey = {},当次请求无权限。", resultKey);
return Optional.of(LOAD_PERMISSION_FAILED_DEFAULT_RESP);
}
}

View File

@ -0,0 +1,55 @@
package cn.axzo.orgmanax.infra.client.karma;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MergeMatchDataResp {
/**
* 数据权限项
*/
@Builder.Default
private List<DataItem> dataItems = Lists.newArrayList();
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public static class DataItem {
/**
* 单位ID
*/
private Long ouId;
/**
* 部门ID
*/
private Long nodeId;
/**
* 项目ID
*/
private Long workspaceId;
/**
* 工程ID
*/
private List<Long> projectIds;
/**
* 节点状态 1-在场0-退场',
*/
private Integer nodeStatus;
}
}

View File

@ -255,6 +255,9 @@ public interface NodeUserQueryRepository {
@CriteriaField(field = "extra", operator = Operator.JSON_QUERY) @CriteriaField(field = "extra", operator = Operator.JSON_QUERY)
private Collection<MybatisPlusOperatorProcessor.JSONQuery> extraQueries; private Collection<MybatisPlusOperatorProcessor.JSONQuery> extraQueries;
@CriteriaField(field = "profile", operator = Operator.JSON_QUERY)
private Collection<MybatisPlusOperatorProcessor.JSONQuery> profileQueries;
/** /**
* orgUserStatus * orgUserStatus
*/ */
@ -269,6 +272,11 @@ public interface NodeUserQueryRepository {
*/ */
@CriteriaField(ignore = true) @CriteriaField(ignore = true)
private Boolean returnEmpty; private Boolean returnEmpty;
public ListReq markReturnEmpty() {
returnEmpty = true;
return this;
}
} }
@NoArgsConstructor @NoArgsConstructor

View File

@ -65,4 +65,22 @@ public class RpcWrapper {
} }
return result.getData(); return result.getData();
} }
/**
* Foundation Api result 返回
*
* @param supplier
* @param <T>
* @return
*/
public static <T> T wrapFApiResult(Supplier<cn.axzo.foundation.result.ApiResult<T>> supplier) {
cn.axzo.foundation.result.ApiResult<T> result = supplier.get();
if (result == null) {
throw new BusinessException(BizResultCode.RPC_ERROR);
}
if (!Objects.equals(result.getCode(), HttpStatus.HTTP_OK)) {
throw new BusinessException(Convert.toStr(result.getCode()), result.getMsg(), null);
}
return result.getData();
}
} }

View File

@ -0,0 +1,25 @@
package cn.axzo.orgmanax.integration.sdk.karma;
import cn.axzo.karma.client.feign.tyr.DataObjectApi;
import cn.axzo.orgmanax.infra.client.karma.GetMergeMatchDataReq;
import cn.axzo.orgmanax.infra.client.karma.KarmaDataObjectClient;
import cn.axzo.orgmanax.infra.client.karma.MergeMatchDataResp;
import cn.axzo.orgmanax.integration.core.RpcWrapper;
import cn.hutool.core.bean.BeanUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@RequiredArgsConstructor
public class KarmaDataObjectClientImpl implements KarmaDataObjectClient {
private final DataObjectApi dataObjectApi;
@Override
public MergeMatchDataResp getCached(GetMergeMatchDataReq request) {
cn.axzo.karma.client.feign.tyr.response.MergeMatchDataResp resp = RpcWrapper.wrapFApiResult(
() -> dataObjectApi.getCached(BeanUtil.toBean(request, cn.axzo.karma.client.feign.tyr.request.GetMergeMatchDataReq.class)));
return BeanUtil.toBean(resp, MergeMatchDataResp.class);
}
}

View File

@ -20,6 +20,8 @@ import cn.axzo.orgmanax.dto.nodeuser.req.ProcessNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.req.SearchEntNodeUserReq; import cn.axzo.orgmanax.dto.nodeuser.req.SearchEntNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.resp.SearchEntNodeUserResp; import cn.axzo.orgmanax.dto.nodeuser.resp.SearchEntNodeUserResp;
import cn.axzo.orgmanax.dto.unit.dto.OrgUnitBriefDTO; import cn.axzo.orgmanax.dto.unit.dto.OrgUnitBriefDTO;
import cn.axzo.orgmanax.infra.client.karma.KarmaDataObjectGateway;
import cn.axzo.orgmanax.infra.client.karma.MergeMatchDataResp;
import cn.axzo.orgmanax.infra.client.profile.PersonProfileGateway; import cn.axzo.orgmanax.infra.client.profile.PersonProfileGateway;
import cn.axzo.orgmanax.infra.client.profile.dto.ProfileGetPersonProfileListReq; import cn.axzo.orgmanax.infra.client.profile.dto.ProfileGetPersonProfileListReq;
import cn.axzo.orgmanax.infra.client.workspace.WorkspaceGateway; import cn.axzo.orgmanax.infra.client.workspace.WorkspaceGateway;
@ -41,6 +43,7 @@ import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -70,6 +73,7 @@ public class NodeUserServiceImpl implements NodeUserService {
private final ApplicationContext applicationContext; private final ApplicationContext applicationContext;
private final NodeUserFoundationService nodeUserFoundationService; private final NodeUserFoundationService nodeUserFoundationService;
private final NodeService nodeService; private final NodeService nodeService;
private final KarmaDataObjectGateway karmaDataObjectGateway;
@Override @Override
public NodeUserProcessor.ProcessResult process(ProcessNodeUserReq req) { public NodeUserProcessor.ProcessResult process(ProcessNodeUserReq req) {
@ -144,8 +148,7 @@ public class NodeUserServiceImpl implements NodeUserService {
.searchCount(false) .searchCount(false)
.build()).stream().map(OrgJobQueryRepository.JobResp::getId).collect(Collectors.toSet()); .build()).stream().map(OrgJobQueryRepository.JobResp::getId).collect(Collectors.toSet());
if (jobIds.isEmpty()) { if (jobIds.isEmpty()) {
listReq.setReturnEmpty(true); return listReq.markReturnEmpty();
return listReq;
} }
listReq.setOrganizationalJobIds(QueryConditionAssembler.assemble(listReq.getOrganizationalJobIds(), jobIds)); listReq.setOrganizationalJobIds(QueryConditionAssembler.assemble(listReq.getOrganizationalJobIds(), jobIds));
} }
@ -161,8 +164,7 @@ public class NodeUserServiceImpl implements NodeUserService {
.build()).stream() .build()).stream()
.map(NodeUserQueryRepository.NodeUserResp::getOrganizationalNodeId).collect(Collectors.toSet()); .map(NodeUserQueryRepository.NodeUserResp::getOrganizationalNodeId).collect(Collectors.toSet());
if (managedOrgNodeId.isEmpty()) { if (managedOrgNodeId.isEmpty()) {
listReq.setReturnEmpty(true); return listReq.markReturnEmpty();
return listReq;
} }
listReq.setOrganizationalNodeIds(QueryConditionAssembler.assemble(listReq.getOrganizationalNodeIds(), managedOrgNodeId)); listReq.setOrganizationalNodeIds(QueryConditionAssembler.assemble(listReq.getOrganizationalNodeIds(), managedOrgNodeId));
} }
@ -177,8 +179,7 @@ public class NodeUserServiceImpl implements NodeUserService {
.build()) .build())
.stream().map(NodeUserQueryRepository.NodeUserResp::getOrganizationalNodeId).collect(Collectors.toSet()); .stream().map(NodeUserQueryRepository.NodeUserResp::getOrganizationalNodeId).collect(Collectors.toSet());
if (nodeIds.isEmpty()) { if (nodeIds.isEmpty()) {
listReq.setReturnEmpty(true); return listReq.markReturnEmpty();
return listReq;
} }
// 查询 subordinatePersonId 所在节点的管理员 // 查询 subordinatePersonId 所在节点的管理员
listReq.setOrganizationalNodeIds(QueryConditionAssembler.assemble(listReq.getOrganizationalNodeIds(), nodeIds)); listReq.setOrganizationalNodeIds(QueryConditionAssembler.assemble(listReq.getOrganizationalNodeIds(), nodeIds));
@ -191,6 +192,73 @@ public class NodeUserServiceImpl implements NodeUserService {
.data(req.getDirectManagerPersonId()) .data(req.getDirectManagerPersonId())
.build()))); .build())));
} }
// dataPermissionCacheKey
if (StrUtil.isNotBlank(req.getDataPermissionCacheKey())) {
karmaDataObjectGateway.getCached(req.getDataPermissionCacheKey())
.filter(dp -> CollUtil.isNotEmpty(dp.getDataItems())).ifPresent(dp -> {
Set<Long> allowQueryNodeIds = dp.getDataItems().stream().map(MergeMatchDataResp.DataItem::getNodeId).collect(Collectors.toSet());
listReq.setOrganizationalNodeIds(QueryConditionAssembler.assemble(listReq.getOrganizationalNodeIds(), allowQueryNodeIds));
});
}
// projectWorkerStatuses
if (CollUtil.isNotEmpty(req.getProjectWorkerStatuses())) {
listReq.setProfileQueries(QueryConditionAssembler.assemble(listReq.getProfileQueries(),
ImmutableSet.of(MybatisPlusOperatorProcessor.JSONQuery.builder()
.jsonPath("$.projectWorkerStatus")
.operator(Operator.IN)
.data(req.getProjectWorkerStatuses())
.build())));
}
// platTeamId
if (req.getPlatTeamId() != null) {
listReq.setProfileQueries(QueryConditionAssembler.assemble(listReq.getProfileQueries(),
ImmutableSet.of(MybatisPlusOperatorProcessor.JSONQuery.builder()
.jsonPath("$.platTeamId")
.data(req.getPlatTeamId())
.build())));
}
// projectTeamIds
if (CollUtil.isNotEmpty(req.getProjectTeamIds())) {
listReq.setProfileQueries(QueryConditionAssembler.assemble(listReq.getProfileQueries(),
ImmutableSet.of(MybatisPlusOperatorProcessor.JSONQuery.builder()
.jsonPath("$.projectTeamId")
.operator(Operator.IN)
.data(req.getProjectTeamIds())
.build())));
}
// projectTeamId
if (req.getProjectTeamId() != null) {
listReq.setProfileQueries(QueryConditionAssembler.assemble(listReq.getProfileQueries(),
ImmutableSet.of(MybatisPlusOperatorProcessor.JSONQuery.builder()
.jsonPath("$.projectTeamId")
.data(req.getProjectTeamId())
.build())));
}
// projectWorkerIds
if (CollUtil.isNotEmpty(req.getProjectWorkerIds())) {
listReq.setProfileQueries(QueryConditionAssembler.assemble(listReq.getProfileQueries(),
ImmutableSet.of(MybatisPlusOperatorProcessor.JSONQuery.builder()
.jsonPath("$.projectWorkerId")
.operator(Operator.IN)
.data(req.getProjectWorkerIds())
.build())));
}
// projectWorkerId
if (req.getProjectWorkerId() != null) {
listReq.setProfileQueries(QueryConditionAssembler.assemble(listReq.getProfileQueries(),
ImmutableSet.of(MybatisPlusOperatorProcessor.JSONQuery.builder()
.jsonPath("$.projectWorkerId")
.data(req.getProjectWorkerId())
.build())));
}
// projectGroupId
if (req.getProjectGroupId() != null) {
listReq.setProfileQueries(QueryConditionAssembler.assemble(listReq.getProfileQueries(),
ImmutableSet.of(MybatisPlusOperatorProcessor.JSONQuery.builder()
.jsonPath("$.projectGroupId")
.data(req.getProjectGroupId())
.build())));
}
return listReq; return listReq;
} }