feat(REQ-3714): 批量删除人员检查接口实现

This commit is contained in:
zhanghonghao 2025-03-07 14:40:29 +08:00
parent 346d99646e
commit d911db5166
9 changed files with 556 additions and 48 deletions

View File

@ -1,6 +1,8 @@
package cn.axzo.orgmanax.dto.node.dto;
import cn.axzo.foundation.result.ResultCode;
import cn.axzo.orgmanax.dto.cooperateship.dto.OrgCooperateShipDTO;
import cn.axzo.orgmanax.dto.node.enums.NodeTypeEnum;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -10,6 +12,7 @@ import lombok.experimental.SuperBuilder;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@NoArgsConstructor
@ -154,4 +157,18 @@ public class OrgNodeDTO implements Serializable {
}
return (T) Optional.ofNullable(profile).map(p -> JSONObject.parseObject(p.toString(), clazz)).orElse(null);
}
/**
* 获取项目内小组节点配置信息
* @return 是否合作小组true 独立false 非独立
*/
public Boolean independentGroup() {
if (!Objects.equals(this.nodeType, NodeTypeEnum.PROJECT_GROUP.getValue())) {
throw ResultCode.INVALID_PARAMS.toException("小组节点类型错误");
}
if (Objects.nonNull(this.profile) && !this.profile.isEmpty()) {
return this.profile.getBooleanValue("independentGroup");
}
return null;
}
}

View File

@ -4,14 +4,34 @@ import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum CheckInfoTypeEnum {
SUPER_ADMIN(1, "超级管理员"),
IN_PROJECT(2, "在项目中"),
TEAM_LEADER(3, "班组长");
SUPER_ADMIN(1, "超级管理员", "【%s】是超级管理员无法删除", 0),
IN_PROJECT(2, "在项目中", "【%s】在项目中无法删除", 0),
TEAM_LEADER(3, "班组长", "【%s】是班组长无法删除", 0),
PROJECT_GROUP_LEADER(4, "合作小组小组长", "【%s】是项目组组长无法删除", 0),
NOT_IN_JURISDICTION(5, "不在管辖范围", "【%s】,不在你的管辖范围,无法删除!", 0),
ANY_ADMIN(6, "单位负责人", "【%s】是项目单位负责人无法删除", 0),
TASK_ORDER(7, "任务单", "当前人员有未完成的任务单:%d单。无法删除", 2),
RECTIFY_ORDERS(8, "整改单", "当前人员有未完成的整改单:%d单。无法删除", 6),
ACCEPTANCE_PROCESS(9, "验收流程", "当前人员有未完成的验收单:%d单。无法删除", 7);
private final Integer value;
private final String desc;
}
private final String msg;
private final Integer thirdType;
private static final Map<Integer, CheckInfoTypeEnum> thirdTypeMap = Arrays.stream(CheckInfoTypeEnum.values())
.collect(Collectors.toMap(CheckInfoTypeEnum::getThirdType, Function.identity(), (key1, key2) -> key2));
public static CheckInfoTypeEnum getByThirdType(Integer type) {
return thirdTypeMap.get(type);
}
}

View File

@ -1,7 +1,9 @@
package cn.axzo.orgmanax.dto.nodeuser.resp;
import cn.axzo.orgmanax.dto.nodeuser.enums.CheckInfoTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@ -17,6 +19,8 @@ public class BatchDeleteNodeUserCheckResp {
private List<CheckFailInfo> failInfos;
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class CheckFailInfo {
private CheckInfoTypeEnum type;

View File

@ -0,0 +1,10 @@
package cn.axzo.orgmanax.infra.client.karma;
import java.util.List;
import java.util.Map;
import java.util.Set;
public interface KarmaThirdApiClient {
Map<Long, List<ThirdCheckFailResp>> getThirdCheckFail(Long workspaceId, Set<Long> personIds);
}

View File

@ -0,0 +1,17 @@
package cn.axzo.orgmanax.infra.client.karma;
import cn.axzo.orgmanax.dto.nodeuser.enums.CheckInfoTypeEnum;
import lombok.Data;
/**
* @author : zhanghonghao@axzo.cn
* @since : 2025/3/7
*/
@Data
public class ThirdCheckFailResp {
private CheckInfoTypeEnum type;
private Integer count;
}

View File

@ -0,0 +1,50 @@
package cn.axzo.orgmanax.integration.sdk.karma;
import cn.axzo.karma.client.feign.team.ThirdApiCheckServiceApi;
import cn.axzo.karma.client.model.request.ThirdApiPersonNormalCheckReq;
import cn.axzo.karma.client.model.vo.OpFailVO;
import cn.axzo.orgmanax.dto.nodeuser.enums.CheckInfoTypeEnum;
import cn.axzo.orgmanax.infra.client.karma.KarmaThirdApiClient;
import cn.axzo.orgmanax.infra.client.karma.ThirdCheckFailResp;
import cn.axzo.orgmanax.integration.core.RpcWrapper;
import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author : zhanghonghao@axzo.cn
* @since : 2025/3/7
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class KarmaThirdApiClientImpl implements KarmaThirdApiClient {
private final ThirdApiCheckServiceApi thirdApiCheckServiceApi;
@Override
public Map<Long, List<ThirdCheckFailResp>> getThirdCheckFail(Long workspaceId, Set<Long> personIds) {
ThirdApiPersonNormalCheckReq checkReq = new ThirdApiPersonNormalCheckReq();
checkReq.setWorkspaceId(workspaceId);
checkReq.setPersonIdList(new ArrayList<>(personIds));
Map<Long, List<OpFailVO>> checkMap = RpcWrapper.commonRes(() -> thirdApiCheckServiceApi.thirdApiNormalCheckPerson(checkReq));
if (CollUtil.isEmpty(checkMap)) {
return Collections.emptyMap();
}
Map<Long, List<ThirdCheckFailResp>> failInfoMap = new HashMap<>();
checkMap.forEach((key, opFailVOs) -> {
List<ThirdCheckFailResp> personList = opFailVOs.stream().map(opFailVO -> {
ThirdCheckFailResp thirdCheckFailResp = new ThirdCheckFailResp();
thirdCheckFailResp.setType(CheckInfoTypeEnum.getByThirdType(opFailVO.getType()));
thirdCheckFailResp.setCount(opFailVO.getCount());
return thirdCheckFailResp;
}).collect(Collectors.toList());
failInfoMap.put(key, personList);
});
return failInfoMap;
}
}

View File

@ -0,0 +1,30 @@
package cn.axzo.orgmanax.server.nodeuser.dto;
import cn.axzo.foundation.result.ResultCode;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import java.util.Set;
/**
* @author : zhanghonghao@axzo.cn
* @since : 2025/3/7
*/
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class CheckUserOperateParam {
private Long operatorId;
private Set<Long> personIds;
private Long workspaceId;
public void check() {
if (ObjectUtils.anyNull(personIds, workspaceId, operatorId)) {
throw ResultCode.INVALID_PARAMS.toException("参数异常,您暂无权限!");
}
}
}

View File

@ -1,28 +1,33 @@
package cn.axzo.orgmanax.server.nodeuser.service.impl;
import cn.axzo.apollo.workspace.api.v2.participating.feign.ParticipatingUnitV2Api;
import cn.axzo.apollo.workspace.api.v2.participating.req.ParticipatingUnitListReq;
import cn.axzo.apollo.workspace.api.v2.participating.resp.ParticipatingUnitResp;
import cn.axzo.basics.common.exception.ServiceException;
import cn.axzo.basics.common.util.NumberUtil;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.foundation.result.ResultCode;
import cn.axzo.orgmanax.dto.common.IdentityType;
import cn.axzo.orgmanax.dto.common.util.NumberUtil;
import cn.axzo.orgmanax.dto.cooperateship.dto.OrgCooperateShipDTO;
import cn.axzo.orgmanax.dto.cooperateship.enums.CooperateShipTypeEnum;
import cn.axzo.orgmanax.dto.cooperateship.req.ListOrgCooperateShipReq;
import cn.axzo.orgmanax.dto.node.dto.OrgNodeDTO;
import cn.axzo.orgmanax.dto.node.enums.NodeTypeEnum;
import cn.axzo.orgmanax.dto.node.req.ListNodeReq;
import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO;
import cn.axzo.orgmanax.dto.nodeuser.enums.CheckInfoTypeEnum;
import cn.axzo.orgmanax.dto.nodeuser.req.BatchDeleteNodeUserCheckReq;
import cn.axzo.orgmanax.dto.nodeuser.req.ListNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.resp.BatchDeleteNodeUserCheckResp;
import cn.axzo.orgmanax.infra.client.profile.PersonProfileGateway;
import cn.axzo.orgmanax.infra.client.profile.dto.model.PersonProfileDto;
import cn.axzo.orgmanax.infra.client.karma.KarmaThirdApiClient;
import cn.axzo.orgmanax.infra.client.karma.ThirdCheckFailResp;
import cn.axzo.orgmanax.infra.client.tyr.RoleUserGateway;
import cn.axzo.orgmanax.infra.client.workspace.WorkspaceGateway;
import cn.axzo.orgmanax.infra.client.workspace.dto.Workspace;
import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip;
import cn.axzo.orgmanax.server.cooperateship.service.CooperateShipService;
import cn.axzo.orgmanax.server.node.service.NodeService;
import cn.axzo.orgmanax.server.nodeuser.dto.CheckUserOperateParam;
import cn.axzo.orgmanax.server.nodeuser.service.NodeUserCheckService;
import cn.axzo.orgmanax.server.nodeuser.service.NodeUserService;
import cn.axzo.orgmanax.server.util.constants.JobCodeConstants;
import cn.axzo.tyr.feign.enums.IdentityTypeEnum;
import cn.axzo.tyr.feign.enums.RoleTypeEnum;
import cn.axzo.tyr.feign.req.PageRoleUserReq;
@ -30,7 +35,9 @@ import cn.axzo.tyr.feign.resp.RoleUserResp;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.RequiredArgsConstructor;
@ -39,7 +46,8 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.stream.Collectors;
@Slf4j
@ -51,25 +59,32 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService {
private final RoleUserGateway roleUserGateway;
private final PersonProfileGateway profileGateway;
private final CooperateShipService cooperateShipService;
private final NodeUserService nodeUserService;
private final NodeService nodeService;
private final KarmaThirdApiClient karmaThirdApiClient;
// 单位类型默认角色关系,后面可以座位管理员的逻辑进行迭代
@Value("#{${participateUnitDefaultRoleId:{}}}")
public Map<Integer, Long> participateUnitDefaultRoleId;
/**
* 小组长角色分组编码
*/
@Value("${projectTeamGPLeader:projectTeamGPLeader}")
private String projectTeamGPLeader;
// 企业内班组长岗位编码
@Value("${entTeamLeader:entTeamLeader}")
private String entTeamLeader;
// 班组管理员岗位编码
@Value("${entTeamManager:entTeamManager}")
private String entTeamManager;
// 企业内班组工人岗位编码
@Value("${entWorker:entWorker}")
private String entWorker;
@Override
public List<BatchDeleteNodeUserCheckResp> checkUnit(BatchDeleteNodeUserCheckReq req) {
List<BatchDeleteNodeUserCheckResp> resultList = new ArrayList<>();
@ -120,23 +135,11 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService {
nodeUserQueryVO.setNeeds(ListNodeUserReq.Needs.builder().job(true).build());
//查询人所在的部门节点列表
List<NodeUserDTO> organizationalNodeUserList = nodeUserService.list(nodeUserQueryVO);
AtomicBoolean isWorker = new AtomicBoolean(false);
AtomicBoolean isPractitioner = new AtomicBoolean(false);
List<Long> teamLeader = Lists.newArrayList();
List<Long> workerOrgNodeIds = Lists.newArrayList();
Set<Long> teamLeader = Sets.newHashSet();
organizationalNodeUserList.forEach(organizationalNodeUserVO -> {
if (IdentityTypeEnum.WORKER_LEADER.getCode().equals(organizationalNodeUserVO.getIdentityType()) ||
entTeamLeader.equals(organizationalNodeUserVO.getJob().getCode())) {
if (IdentityTypeEnum.WORKER_LEADER.getCode().equals(organizationalNodeUserVO.getIdentityType()) || entTeamLeader.equals(organizationalNodeUserVO.getJob().getCode())) {
teamLeader.add(organizationalNodeUserVO.getPersonId());
}
if (IdentityTypeEnum.WORKER.getCode().equals(organizationalNodeUserVO.getIdentityType()) ||
entWorker.equals(organizationalNodeUserVO.getJob().getCode())) {
isWorker.set(true);
workerOrgNodeIds.add(organizationalNodeUserVO.getOrganizationalNodeId());
}
if (IdentityTypeEnum.PRACTITIONER.getCode().equals(organizationalNodeUserVO.getIdentityType())) {
isPractitioner.set(true);
}
});
if (CollUtil.isNotEmpty(teamLeader)) {
teamLeader.forEach(e -> {
@ -145,14 +148,11 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService {
addFailInfo(failInfoMap, e, checkFailInfo);
});
}
if (CollUtil.isNotEmpty(failInfoMap)) {
failInfoMap.forEach((personId, checkFailInfos) -> {
BatchDeleteNodeUserCheckResp batchDeleteNodeUserCheckVO = new BatchDeleteNodeUserCheckResp();
batchDeleteNodeUserCheckVO.setPersonId(personId);
batchDeleteNodeUserCheckVO.setFailInfos(checkFailInfos);
resultList.add(batchDeleteNodeUserCheckVO);
});
//判断当前人是否有操作权限
if (NumberUtil.isPositiveNumber(req.getOperatorId())) {
}
transformFailMap(failInfoMap, resultList);
return resultList;
}
@ -161,10 +161,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService {
return personIds;
}
Set<Long> filterResult = new HashSet<>();
List<Long> topNodeIds = result.stream()
.map(OrgCooperateShipDTO::getOrganizationalNodeId)
.distinct()
.collect(Collectors.toList());
List<Long> topNodeIds = result.stream().map(OrgCooperateShipDTO::getOrganizationalNodeId).distinct().collect(Collectors.toList());
ListNodeUserReq nodeUserReq = new ListNodeUserReq();
nodeUserReq.setTopNodeIds(topNodeIds);
nodeUserReq.setPersonIds(personIds);
@ -185,6 +182,335 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService {
@Override
public List<BatchDeleteNodeUserCheckResp> checkWorkspace(BatchDeleteNodeUserCheckReq req) {
return new ArrayList<>();
Long personId = req.getOperatorId();
List<BatchDeleteNodeUserCheckResp> resultList = new ArrayList<>();
Map<Long, List<BatchDeleteNodeUserCheckResp.CheckFailInfo>> failInfoMap = new HashMap<>();
ListOrgCooperateShipReq listOrgCooperateShipReq = new ListOrgCooperateShipReq();
listOrgCooperateShipReq.setOuIds(Collections.singleton(req.getOuId()));
listOrgCooperateShipReq.setWorkspaceIds(Collections.singleton(req.getWorkspaceId()));
listOrgCooperateShipReq.setStatuses(CollUtil.newHashSet(0, 1));
List<OrgCooperateShipDTO> cooperateShipRespList = cooperateShipService.list(listOrgCooperateShipReq);
Axssert.checkNotEmpty(cooperateShipRespList, "操作失败,获取协同组织失败");
// 协同节点关联的顶级部门节点列表
List<Long> nodeIds = cooperateShipRespList.stream().map(OrgCooperateShipDTO::getOrganizationalNodeId).distinct().collect(Collectors.toList());
List<Long> nodePersonIds = Lists.newArrayList(req.getPersonIds());
nodePersonIds.add(personId);
ListNodeUserReq query = ListNodeUserReq.builder()
.topNodeIds(nodeIds)
.personIds(nodePersonIds)
.findByAncestorNodeId(true)
.build();
// 查询当前登录及待删除人员在当前项目中的参与记录仅限当前登录单位
List<NodeUserDTO> nodeUsers = nodeUserService.list(query);
// 校验当前入参
checkPermission(nodeUsers, personId);
// 过滤当前操作人员
nodeUsers = nodeUsers.stream()
.filter(e -> req.getPersonIds().contains(e.getPersonId()))
.collect(Collectors.toList());
if (CollectionUtil.isEmpty(nodeUsers)) {
req.getPersonIds().forEach(e -> {
BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo();
checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION);
addFailInfo(failInfoMap, e, checkFailInfo);
});
}
nodeUsers.stream().filter(e -> e.getIdentityType().equals(IdentityType.WORKER_LEADER.getCode())).findAny().ifPresent(e -> {
BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo();
checkFailInfo.setType(CheckInfoTypeEnum.TEAM_LEADER);
addFailInfo(failInfoMap, e.getPersonId(), checkFailInfo);
});
// 判断是否合作小组小组长合作小组小组长不允许删除
checkIndependentGroupLeader(nodeUsers, failInfoMap);
// 判断是否拥有admin角色 判断是否是分包管理员
List<Long> adminRoleIds = getSpecialRole();
PageRoleUserReq roleUserParam = PageRoleUserReq.builder().build();
PageRoleUserReq.WorkspaceOuPair workspaceOuPair = new PageRoleUserReq.WorkspaceOuPair();
workspaceOuPair.setWorkspaceId(req.getWorkspaceId());
workspaceOuPair.setOuId(req.getOuId());
roleUserParam.setWorkspaceOuPairs(Collections.singletonList(workspaceOuPair));
roleUserParam.setPersonIds(req.getPersonIds());
roleUserParam.setNeedRole(true);
List<RoleUserResp> saasRoleUserInfo = roleUserGateway.pageAll(roleUserParam);
saasRoleUserInfo.forEach(e -> {
Optional<RoleTypeEnum> roleTypeEnumOptional = RoleTypeEnum.fromValue(e.getRole().getRoleType());
RoleTypeEnum roleTypeEnum = RoleTypeEnum.AUTO_OWN;
if (roleTypeEnumOptional.isPresent()) {
roleTypeEnum = roleTypeEnumOptional.get();
}
boolean anyAdminRole = adminRoleIds.contains(e.getRoleId()) || roleTypeEnum.isAdmin();
if (anyAdminRole) {
BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo();
checkFailInfo.setType(CheckInfoTypeEnum.ANY_ADMIN);
addFailInfo(failInfoMap, e.getPersonId(), checkFailInfo);
}
});
// 检查班组节点权限
checkUserOperate(CheckUserOperateParam.builder()
.operatorId(req.getOperatorId())
.personIds(req.getPersonIds())
.workspaceId(req.getWorkspaceId())
.build(), failInfoMap);
// 三方阻断校验
thirdApiCheckPerson(req.getWorkspaceId(), req.getPersonIds(), failInfoMap);
transformFailMap(failInfoMap, resultList);
return resultList;
}
}
private static void transformFailMap(Map<Long, List<BatchDeleteNodeUserCheckResp.CheckFailInfo>> failInfoMap, List<BatchDeleteNodeUserCheckResp> resultList) {
if (CollUtil.isNotEmpty(failInfoMap)) {
failInfoMap.forEach((failPerson, checkFailInfos) -> {
// Use a LinkedHashMap to keep track of the last count for each type
Map<CheckInfoTypeEnum, Integer> lastCounts = new LinkedHashMap<>();
for (BatchDeleteNodeUserCheckResp.CheckFailInfo info : checkFailInfos) {
lastCounts.put(info.getType(), info.getCount());
}
// Create a new list of CheckFailInfo objects with unique types and their last counts
List<BatchDeleteNodeUserCheckResp.CheckFailInfo> uniqueFailInfos = new ArrayList<>();
for (Map.Entry<CheckInfoTypeEnum, Integer> entry : lastCounts.entrySet()) {
uniqueFailInfos.add(new BatchDeleteNodeUserCheckResp.CheckFailInfo(entry.getKey(), entry.getValue()));
}
BatchDeleteNodeUserCheckResp batchDeleteNodeUserCheckVO = new BatchDeleteNodeUserCheckResp();
batchDeleteNodeUserCheckVO.setPersonId(failPerson);
batchDeleteNodeUserCheckVO.setFailInfos(uniqueFailInfos);
resultList.add(batchDeleteNodeUserCheckVO);
});
}
}
private void thirdApiCheckPerson(Long workspaceId, Set<Long> personIds, Map<Long, List<BatchDeleteNodeUserCheckResp.CheckFailInfo>> failInfoMap) {
Map<Long, List<ThirdCheckFailResp>> thirdCheckFail = karmaThirdApiClient.getThirdCheckFail(workspaceId, personIds);
if (CollUtil.isEmpty(thirdCheckFail)) {
return;
}
thirdCheckFail.forEach((key, value) -> value.forEach(thirdCheckFailResp -> {
BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo();
checkFailInfo.setType(thirdCheckFailResp.getType());
checkFailInfo.setCount(thirdCheckFailResp.getCount());
addFailInfo(failInfoMap, key, checkFailInfo);
}));
}
private void checkIndependentGroupLeader(List<NodeUserDTO> nodeUsers, Map<Long, List<BatchDeleteNodeUserCheckResp.CheckFailInfo>> failInfoMap) {
Set<Long> nodeIdList = nodeUsers.stream().map(NodeUserDTO::getOrganizationalNodeId).collect(Collectors.toSet());
ListNodeReq nodeBatchQueryVO = new ListNodeReq();
nodeBatchQueryVO.setIds(nodeIdList);
List<OrgNodeDTO> nodeVOList = nodeService.list(nodeBatchQueryVO);
if (CollectionUtil.isEmpty(nodeVOList)) {
throw ResultCode.INVALID_PARAMS.toException("操作失败:获取部门节点信息失败");
}
Map<Long, OrgNodeDTO> nodeVOMap = nodeVOList.stream().collect(Collectors.toMap(OrgNodeDTO::getId, Function.identity()));
for (NodeUserDTO u : nodeUsers) {
if (projectTeamGPLeader.equals(u.getJob().getCode())) {
OrgNodeDTO nodeVO = nodeVOMap.getOrDefault(u.getOrganizationalNodeId(), null);
if (Objects.nonNull(nodeVO) && NodeTypeEnum.PROJECT_GROUP.getValue().equals(nodeVO.getNodeType())
&& Objects.nonNull(nodeVO.independentGroup()) && nodeVO.independentGroup()) {
BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo();
checkFailInfo.setType(CheckInfoTypeEnum.PROJECT_GROUP_LEADER);
addFailInfo(failInfoMap, u.getPersonId(), checkFailInfo);
}
}
}
}
private void checkPermission(List<NodeUserDTO> nodeUsers, Long personId) {
if (CollUtil.isEmpty(nodeUsers)
|| nodeUsers.stream().noneMatch(e -> Objects.equals(e.getPersonId(), personId))) {
throw ResultCode.INVALID_PARAMS.toException("你已被移除当前项目");
}
}
private List<Long> getSpecialRole() {
if (participateUnitDefaultRoleId != null && !participateUnitDefaultRoleId.isEmpty()) {
return new ArrayList<>(participateUnitDefaultRoleId.values());
} else {
return new ArrayList<>();
}
}
public void checkUserOperate(CheckUserOperateParam param, Map<Long, List<BatchDeleteNodeUserCheckResp.CheckFailInfo>> failInfoMap) {
if (NumberUtil.isNotPositiveNumber(param.getOperatorId())) {
return;
}
param.check();
List<Long> nodePersonIds = Lists.newArrayList(param.getPersonIds());
nodePersonIds.add(param.getOperatorId());
ListNodeUserReq nodeUserReq = ListNodeUserReq.builder()
.personIds(nodePersonIds)
.workspaceId(param.getWorkspaceId())
.needs(ListNodeUserReq.Needs.builder().job(true).node(true).build())
.build();
List<NodeUserDTO> nodeUsers = nodeUserService.list(nodeUserReq);
NodeUserDTO operator = nodeUsers.stream().filter(nu -> Objects.equals(nu.getPersonId(), param.getOperatorId()))
.filter(nu -> StrUtil.isNotBlank(nu.getJob().getCode()))
.min(Comparator.comparingInt(NODE_USER_PRIORITY_RESOLVER)).orElse(null);
List<NodeUserDTO> targets = param.getPersonIds().stream()
.map(personId -> nodeUsers.stream()
.filter(nu -> Objects.equals(nu.getPersonId(), personId))
.min(Comparator.comparingInt(NODE_USER_PRIORITY_RESOLVER))
.orElse(null))
.collect(Collectors.toList());
log.info("## checkUserOperate, param = {}, operator = {}, targets = {}, nodeUsers = {} "
, JSON.toJSONString(param), JSON.toJSONString(operator), JSON.toJSONString(targets), JSON.toJSONString(nodeUsers));
if (operator == null) {
throw ResultCode.INVALID_PARAMS.toException("你已经被移出该企业/项目,请及时联系管理员;你可以退出登录或切换到其他企业/项目使用");
}
if (CollUtil.isEmpty(targets)) {
throw ResultCode.INVALID_PARAMS.toException("操作对象已经被移出该企业/项目,请刷新页面重新操作");
}
// 如果只有工人身份则直接提示无权限
if (isProjectWorker(operator)) {
throw ResultCode.INVALID_PARAMS.toException("操作失败,您暂无权限!");
}
if (param.getPersonIds().size() == 1 && param.getPersonIds().contains(param.getOperatorId())) {
return;
}
// 如果 操作人是 从业人员 直接返回
if (isPractitioner(operator)) {
return;
}
// 操作人是 班组长或者带班长 则被操作人只能是 自己或者自己班组 小组的工人
if (isProjectTeamLeader(operator) || isProjectTeamManager(operator)) {
targets.forEach(target -> teamManagerCheck(target, operator, failInfoMap));
}
if (isProjectGroupManager(operator)) {
targets.forEach(target -> groupManagerCheck(target, operator, nodeUsers, failInfoMap));
}
}
private void groupManagerCheck(NodeUserDTO target, NodeUserDTO operator, List<NodeUserDTO> nodeUsers, Map<Long, List<BatchDeleteNodeUserCheckResp.CheckFailInfo>> failInfoMap) {
if (isPractitioner(target)) {
BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo();
checkFailInfo.setType(CheckInfoTypeEnum.ANY_ADMIN);
addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo);
return;
}
// 工人必须仅在自己小组
boolean isSameGroup = nodeUsers.stream()
.filter(nu -> Objects.equals(nu.getPersonId(), target.getPersonId()))
.anyMatch(nu -> Objects.equals(nu.getOrganizationalNodeId(), operator.getOrganizationalNodeId()));
if (!isSameGroup) {
BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo();
checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION);
addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo);
}
}
private void teamManagerCheck(NodeUserDTO target, NodeUserDTO operator, Map<Long, List<BatchDeleteNodeUserCheckResp.CheckFailInfo>> failInfoMap) {
if (isPractitioner(target)) {
BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo();
checkFailInfo.setType(CheckInfoTypeEnum.ANY_ADMIN);
addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo);
return;
}
boolean isSameTeam = Objects.equals(target.getOrganizationalNodeId(), operator.getOrganizationalNodeId());
if (isSameTeam) {
return;
}
// 否则自己下级小组也可以
boolean isGroup = target.getNode() != null
&& Objects.equals(target.getNode().getNodeType(), NodeTypeEnum.PROJECT_GROUP.getCode());
if (!isGroup) {
BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo();
checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION);
addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo);
return;
}
Long belongProjectTeamNodeId = resolveProjectTeamNodeId(target.getOrganizationalNodeId());
if (Objects.equals(belongProjectTeamNodeId, operator.getOrganizationalNodeId())) {
return;
}
BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo();
checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION);
addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo);
}
private boolean isPractitioner(NodeUserDTO nodeUser) {
if (nodeUser == null) {
return false;
}
return Objects.equals(nodeUser.getIdentityType(), IdentityType.PRACTITIONER.getCode());
}
private boolean isProjectWorker(NodeUserDTO nodeUser) {
if (nodeUser == null) {
return false;
}
return Objects.equals(nodeUser.getJob().getCode(), JobCodeConstants.PROJECT_TEAM_WORKER);
}
private boolean isProjectTeamLeader(NodeUserDTO nodeUser) {
if (nodeUser == null) {
return false;
}
return Objects.equals(nodeUser.getJob().getCode(), JobCodeConstants.PROJ_TEAM_LEADER);
}
private boolean isProjectTeamManager(NodeUserDTO nodeUser) {
if (nodeUser == null) {
return false;
}
return Objects.equals(nodeUser.getJob().getCode(), JobCodeConstants.PROJ_TEAM_MANAGER);
}
private boolean isProjectGroupManager(NodeUserDTO nodeUser) {
if (nodeUser == null) {
return false;
}
return Objects.equals(nodeUser.getJob().getCode(), JobCodeConstants.PROJECT_TEAM_GROUP_LEADER);
}
private static final ToIntFunction<NodeUserDTO> NODE_USER_PRIORITY_RESOLVER = nodeUser -> {
if (nodeUser == null) {
return 9999;
}
if (Objects.equals(nodeUser.getIdentityType(), IdentityType.PRACTITIONER.getCode())) {
return 20;
}
if (StrUtil.isBlank(nodeUser.getJob().getCode())) {
return 9999;
}
switch (nodeUser.getJob().getCode()) {
case JobCodeConstants.PROJECT_TEAM_WORKER:
// 工人
return 100;
case JobCodeConstants.PROJECT_TEAM_GROUP_LEADER:
// 小组长
return 90;
case JobCodeConstants.PROJ_TEAM_MANAGER:
// 带班长
return 80;
case JobCodeConstants.PROJ_TEAM_LEADER:
// 班组长
return 70;
case JobCodeConstants.ENT_TEAM_WORK:
// 平台工人
return 60;
case JobCodeConstants.ENT_TEAM_MANAGER:
// 平台班组管理员
return 50;
case JobCodeConstants.ENT_TEAM_LEADER:
// 平台班组长
return 40;
default:
return 20;
}
};
private Long resolveProjectTeamNodeId(Long nodeId) {
ListOrgCooperateShipReq saasCooperateShipQueryReq = ListOrgCooperateShipReq.builder()
.organizationNodeIds(ImmutableSet.of(nodeId))
.includeAncestors(true)
.build();
List<OrgCooperateShipDTO> nodes = cooperateShipService.list(saasCooperateShipQueryReq);
return nodes.stream().filter(n -> Objects.equals(n.getCooperateType(), CooperateShipTypeEnum.PROJ_TEAM.getCode())).findFirst()
.map(OrgCooperateShipDTO::getOrganizationalNodeId).orElse(0L);
}
}

View File

@ -0,0 +1,34 @@
package cn.axzo.orgmanax.server.util.constants;
/**
* 岗位编码常量
*
* @version V1.0
* @author: ZhanSiHu
* @date: 2024/1/25 14:03
*/
public class JobCodeConstants {
/** 企业内班组长 **/
public static final String ENT_TEAM_LEADER = "entTeamLeader";
/** 企业内班组管理员 **/
public static final String ENT_TEAM_MANAGER = "entTeamManager";
/** 企业内工人 **/
public static final String ENT_TEAM_WORK = "entWorker";
/** 项目内班组 班组长 **/
public static final String PROJ_TEAM_LEADER = "projTeamLeader";
/**
* 项目 - 带班长
*/
public static final String PROJ_TEAM_MANAGER = "projectTeamManager";
/**
* 项目 - 小组长
*/
public static final String PROJECT_TEAM_GROUP_LEADER = "projectTeamGPLeader";
public static final String PROJECT_TEAM_WORKER = "projWorker";
}