diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/dto/NodeUserProfile.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/dto/NodeUserProfile.java index 387072d..7f57e4d 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/dto/NodeUserProfile.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/dto/NodeUserProfile.java @@ -32,7 +32,7 @@ public class NodeUserProfile { /** * 状态:0、未激活 1、已激活 3已退场 */ - private Integer status; + private Integer projectWorkerStatus; /** * 工种类别 */ diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/ListNodeUserReq.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/ListNodeUserReq.java index d157336..36dd9af 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/ListNodeUserReq.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/ListNodeUserReq.java @@ -204,19 +204,20 @@ public class ListNodeUserReq extends PageReqV2 { /** * 状态:1未激活 2、已激活 3、施工中 4、已退场 */ - private Collection projectWorkerStatuses; // TODO: 待实现 + private Collection projectWorkerStatuses; /** * orgUserStatus */ - private Collection orgUserStatus; // TODO: 待实现 + private Collection orgUserStatuses; // TODO: 待实现,具体看如何使用的,是 condition还是filter // ~ 不同部门类型的nodeUser的差异化查询字段。如 项目内工人 的 项目班组id,平台班组id等。 start - private Long platTeamId; // TODO: 待实现 - private Long projectTeamId; // TODO: 待实现 - private Collection projectTeamIds; // TODO: 待实现 - private Long projectWorkerId; // TODO: 待实现 - private Long projectGroupId; // TODO: 待实现 + private Long platTeamId; + private Long projectTeamId; + private Collection projectTeamIds; + private Long projectWorkerId; + private Collection projectWorkerIds; + private Long projectGroupId; // ~ 结束。 @@ -224,6 +225,7 @@ public class ListNodeUserReq extends PageReqV2 { /** * 包含的单位类型 * XXX:filter的参数会破坏分页。如有强分页场景,需谨慎使用 + * @see cn.axzo.orgmanax.dto.unit.enums.OrganizationalUnitTypeEnum */ private Collection filterIncludeUnitTypes; /** @@ -264,7 +266,7 @@ public class ListNodeUserReq extends PageReqV2 { /** * 数据权限 */ - private String dataPermissionCacheKey; // TODO: 待实现 + private String dataPermissionCacheKey; // ~ 不同部门类型的nodeUser的差异化查询字段。如 项目内工人 的 项目班组id,平台班组id等。 end /** diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/RpcWrapper.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/RpcWrapper.java index 69aff49..3a87ad0 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/RpcWrapper.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/RpcWrapper.java @@ -2,15 +2,22 @@ package cn.axzo.orgmanax.infra.client; import cn.axzo.foundation.exception.BusinessException; import cn.axzo.foundation.result.ApiResult; +import cn.axzo.foundation.util.TraceUtils; import cn.axzo.orgmanax.common.config.BizResultCode; import cn.hutool.core.convert.Convert; 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.function.Supplier; +@Slf4j public class RpcWrapper { + public static final ImmutableMap UN_DESCRIBE_PARAMS = ImmutableMap.of("param", "未定义"); + /** * Api result 返回 * @param supplier @@ -18,14 +25,49 @@ public class RpcWrapper { * @param */ public static T wrapApiResult(Supplier> supplier) { - ApiResult result = supplier.get(); - if (result == null) { - throw new BusinessException(BizResultCode.RPC_ERROR); + return wrapApiResult(supplier, "", UN_DESCRIBE_PARAMS, false); + } + + /** + * Api result 返回 + * + * @param supplier + * @param + * @return + */ + public static T wrapApiResult(Supplier> supplier, String desc, Object params) { + return wrapApiResult(supplier, desc, params, true); + } + + /** + * Api result 返回 + * + * @param supplier + * @param + * @return + */ + public static T wrapApiResult(Supplier> supplier, String desc, Object params, boolean logEnabled) { + ApiResult 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(); } } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/GetMergeMatchDataReq.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/GetMergeMatchDataReq.java new file mode 100644 index 0000000..ce24fec --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/GetMergeMatchDataReq.java @@ -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; +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/KarmaDataObjectClient.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/KarmaDataObjectClient.java new file mode 100644 index 0000000..92ea494 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/KarmaDataObjectClient.java @@ -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); +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/KarmaDataObjectGateway.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/KarmaDataObjectGateway.java new file mode 100644 index 0000000..fd20ca6 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/KarmaDataObjectGateway.java @@ -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 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); + } +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/MergeMatchDataResp.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/MergeMatchDataResp.java new file mode 100644 index 0000000..6ff857e --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/MergeMatchDataResp.java @@ -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 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 projectIds; + + /** + * 节点状态 1-在场,0-退场', + */ + private Integer nodeStatus; + + } +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserQueryRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserQueryRepository.java index c5ef062..6c13b40 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserQueryRepository.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserQueryRepository.java @@ -255,6 +255,9 @@ public interface NodeUserQueryRepository { @CriteriaField(field = "extra", operator = Operator.JSON_QUERY) private Collection extraQueries; + @CriteriaField(field = "profile", operator = Operator.JSON_QUERY) + private Collection profileQueries; + /** * orgUserStatus */ @@ -269,6 +272,11 @@ public interface NodeUserQueryRepository { */ @CriteriaField(ignore = true) private Boolean returnEmpty; + + public ListReq markReturnEmpty() { + returnEmpty = true; + return this; + } } @NoArgsConstructor diff --git a/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/core/RpcWrapper.java b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/core/RpcWrapper.java index 588bd8b..b5bd1b9 100644 --- a/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/core/RpcWrapper.java +++ b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/core/RpcWrapper.java @@ -65,4 +65,22 @@ public class RpcWrapper { } return result.getData(); } + + /** + * Foundation Api result 返回 + * + * @param supplier + * @param + * @return + */ + public static T wrapFApiResult(Supplier> supplier) { + cn.axzo.foundation.result.ApiResult 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(); + } } diff --git a/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/karma/KarmaDataObjectClientImpl.java b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/karma/KarmaDataObjectClientImpl.java new file mode 100644 index 0000000..1f36d70 --- /dev/null +++ b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/karma/KarmaDataObjectClientImpl.java @@ -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); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserServiceImpl.java index a75a547..eba899e 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserServiceImpl.java @@ -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.resp.SearchEntNodeUserResp; 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.dto.ProfileGetPersonProfileListReq; 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.JSONObject; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -70,6 +73,7 @@ public class NodeUserServiceImpl implements NodeUserService { private final ApplicationContext applicationContext; private final NodeUserFoundationService nodeUserFoundationService; private final NodeService nodeService; + private final KarmaDataObjectGateway karmaDataObjectGateway; @Override public NodeUserProcessor.ProcessResult process(ProcessNodeUserReq req) { @@ -144,8 +148,7 @@ public class NodeUserServiceImpl implements NodeUserService { .searchCount(false) .build()).stream().map(OrgJobQueryRepository.JobResp::getId).collect(Collectors.toSet()); if (jobIds.isEmpty()) { - listReq.setReturnEmpty(true); - return listReq; + return listReq.markReturnEmpty(); } listReq.setOrganizationalJobIds(QueryConditionAssembler.assemble(listReq.getOrganizationalJobIds(), jobIds)); } @@ -161,8 +164,7 @@ public class NodeUserServiceImpl implements NodeUserService { .build()).stream() .map(NodeUserQueryRepository.NodeUserResp::getOrganizationalNodeId).collect(Collectors.toSet()); if (managedOrgNodeId.isEmpty()) { - listReq.setReturnEmpty(true); - return listReq; + return listReq.markReturnEmpty(); } listReq.setOrganizationalNodeIds(QueryConditionAssembler.assemble(listReq.getOrganizationalNodeIds(), managedOrgNodeId)); } @@ -177,8 +179,7 @@ public class NodeUserServiceImpl implements NodeUserService { .build()) .stream().map(NodeUserQueryRepository.NodeUserResp::getOrganizationalNodeId).collect(Collectors.toSet()); if (nodeIds.isEmpty()) { - listReq.setReturnEmpty(true); - return listReq; + return listReq.markReturnEmpty(); } // 查询 subordinatePersonId 所在节点的管理员 listReq.setOrganizationalNodeIds(QueryConditionAssembler.assemble(listReq.getOrganizationalNodeIds(), nodeIds)); @@ -191,6 +192,73 @@ public class NodeUserServiceImpl implements NodeUserService { .data(req.getDirectManagerPersonId()) .build()))); } + // dataPermissionCacheKey + if (StrUtil.isNotBlank(req.getDataPermissionCacheKey())) { + karmaDataObjectGateway.getCached(req.getDataPermissionCacheKey()) + .filter(dp -> CollUtil.isNotEmpty(dp.getDataItems())).ifPresent(dp -> { + Set 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; }