feat(REQ-3714): 提交单位阻断校验逻辑

This commit is contained in:
honghao.zhang 2025-03-07 00:08:10 +08:00
parent 230b2fc6b2
commit 346d99646e
9 changed files with 255 additions and 7 deletions

View File

@ -0,0 +1,17 @@
package cn.axzo.orgmanax.dto.nodeuser.enums;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum CheckInfoTypeEnum {
SUPER_ADMIN(1, "超级管理员"),
IN_PROJECT(2, "在项目中"),
TEAM_LEADER(3, "班组长");
private final Integer value;
private final String desc;
}

View File

@ -4,6 +4,7 @@ import lombok.Data;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* @author : zhanghonghao@axzo.cn * @author : zhanghonghao@axzo.cn
@ -16,7 +17,7 @@ public class BatchDeleteNodeUserCheckReq {
* personIds * personIds
*/ */
@NotNull(message = "personIds不可以为空") @NotNull(message = "personIds不可以为空")
private List<Long> personIds; private Set<Long> personIds;
private Long workspaceId; private Long workspaceId;
@ -27,4 +28,9 @@ public class BatchDeleteNodeUserCheckReq {
* 节点ID * 节点ID
*/ */
private Long nodeId; private Long nodeId;
/**
* 操作者ID
*/
private Long operatorId;
} }

View File

@ -1,5 +1,6 @@
package cn.axzo.orgmanax.dto.nodeuser.resp; package cn.axzo.orgmanax.dto.nodeuser.resp;
import cn.axzo.orgmanax.dto.nodeuser.enums.CheckInfoTypeEnum;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
@ -18,7 +19,7 @@ public class BatchDeleteNodeUserCheckResp {
@Data @Data
public static class CheckFailInfo { public static class CheckFailInfo {
private Integer type; private CheckInfoTypeEnum type;
private Integer count; private Integer count;
} }

View File

@ -1,5 +1,8 @@
package cn.axzo.orgmanax.infra.client.workspace; package cn.axzo.orgmanax.infra.client.workspace;
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.apollo.workspace.api.v2.workspace.feign.WorkspaceV2Api; import cn.axzo.apollo.workspace.api.v2.workspace.feign.WorkspaceV2Api;
import cn.axzo.apollo.workspace.api.v2.workspace.req.ListWorkspaceReq; import cn.axzo.apollo.workspace.api.v2.workspace.req.ListWorkspaceReq;
import cn.axzo.apollo.workspace.api.v2.workspace.req.WorkspaceDetailReq; import cn.axzo.apollo.workspace.api.v2.workspace.req.WorkspaceDetailReq;
@ -15,6 +18,7 @@ import org.springframework.stereotype.Component;
import java.util.List; import java.util.List;
/** /**
*
*/ */
@RequiredArgsConstructor @RequiredArgsConstructor
@Component @Component
@ -23,8 +27,11 @@ public class WorkspaceGateway {
private final WorkspaceV2Api workspaceV2Api; private final WorkspaceV2Api workspaceV2Api;
private final ParticipatingUnitV2Api participatingUnitV2Api;
/** /**
* 更新和新增 * 更新和新增
*
* @param request * @param request
* @return * @return
*/ */
@ -34,6 +41,7 @@ public class WorkspaceGateway {
/** /**
* 获取详情 * 获取详情
*
* @param request * @param request
* @return * @return
*/ */
@ -43,10 +51,15 @@ public class WorkspaceGateway {
/** /**
* 获取详情 * 获取详情
*
* @param request * @param request
* @return * @return
*/ */
public List<WorkspaceDTO> list(ListWorkspaceReq request) { public List<WorkspaceDTO> list(ListWorkspaceReq request) {
return RpcWrapper.wrapApiResult(() -> workspaceV2Api.listV2(request)); return RpcWrapper.wrapApiResult(() -> workspaceV2Api.listV2(request));
} }
public List<ParticipatingUnitResp> listParticipatingUnits(ParticipatingUnitListReq unitListReq) {
return RpcWrapper.wrapApiResult(() -> participatingUnitV2Api.list(unitListReq));
}
} }

View File

@ -4,6 +4,7 @@ import cn.axzo.foundation.result.ApiResult;
import cn.axzo.orgmanax.api.nodeuser.feign.OrgNodeUserCheckApi; import cn.axzo.orgmanax.api.nodeuser.feign.OrgNodeUserCheckApi;
import cn.axzo.orgmanax.dto.nodeuser.req.BatchDeleteNodeUserCheckReq; import cn.axzo.orgmanax.dto.nodeuser.req.BatchDeleteNodeUserCheckReq;
import cn.axzo.orgmanax.dto.nodeuser.resp.BatchDeleteNodeUserCheckResp; import cn.axzo.orgmanax.dto.nodeuser.resp.BatchDeleteNodeUserCheckResp;
import cn.axzo.orgmanax.server.nodeuser.service.NodeUserCheckService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@ -17,16 +18,17 @@ import java.util.List;
@RestController @RestController
@RequestMapping @RequestMapping
@RequiredArgsConstructor @RequiredArgsConstructor
public class OrgNodeUserCheckController implements OrgNodeUserCheckApi { public class NodeUserCheckController implements OrgNodeUserCheckApi {
private final NodeUserCheckService nodeUserCheckService;
@Override @Override
public ApiResult<List<BatchDeleteNodeUserCheckResp>> checkUnit(BatchDeleteNodeUserCheckReq req) { public ApiResult<List<BatchDeleteNodeUserCheckResp>> checkUnit(BatchDeleteNodeUserCheckReq req) {
return null; return ApiResult.success(nodeUserCheckService.checkUnit(req));
} }
@Override @Override
public ApiResult<List<BatchDeleteNodeUserCheckResp>> checkWorkspace(BatchDeleteNodeUserCheckReq req) { public ApiResult<List<BatchDeleteNodeUserCheckResp>> checkWorkspace(BatchDeleteNodeUserCheckReq req) {
return null; return ApiResult.success(nodeUserCheckService.checkWorkspace(req));
} }
} }

View File

@ -161,8 +161,9 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService
@Override @Override
public List<OrganizationalNodeUser> delete(NodeUserDelete req) { public List<OrganizationalNodeUser> delete(NodeUserDelete req) {
checkDeleteReq(req); checkDeleteReq(req);
List<NodeUserQueryRepository.NodeUserResp> list = nodeUserQueryRepository.list(NodeUserQueryRepository.ListReq.builder().organizationalUnitId(req.getOuId()) List<NodeUserQueryRepository.NodeUserResp> list = nodeUserQueryRepository.list(
.workspaceId(req.getWorkspaceId()).personIds(req.getPersonIds()).build()); NodeUserQueryRepository.ListReq.builder().organizationalUnitId(req.getOuId())
.workspaceId(req.getWorkspaceId()).personIds(req.getPersonIds()).identityType(req.getIdentityType()).build());
if (CollUtil.isEmpty(list)) { if (CollUtil.isEmpty(list)) {
return CollUtil.newArrayList(); return CollUtil.newArrayList();
} }

View File

@ -28,6 +28,11 @@ public class NodeUserDelete {
*/ */
private boolean isUnitDelete; private boolean isUnitDelete;
/**
* 身份类型 按照项目删除的时候
*/
private Integer identityType;
public OrganizationalNodeUser toEntity() { public OrganizationalNodeUser toEntity() {
return BeanUtil.toBean(this, OrganizationalNodeUser.class); return BeanUtil.toBean(this, OrganizationalNodeUser.class);
} }

View File

@ -0,0 +1,13 @@
package cn.axzo.orgmanax.server.nodeuser.service;
import cn.axzo.orgmanax.dto.nodeuser.req.BatchDeleteNodeUserCheckReq;
import cn.axzo.orgmanax.dto.nodeuser.resp.BatchDeleteNodeUserCheckResp;
import java.util.List;
public interface NodeUserCheckService {
List<BatchDeleteNodeUserCheckResp> checkUnit(BatchDeleteNodeUserCheckReq req);
List<BatchDeleteNodeUserCheckResp> checkWorkspace(BatchDeleteNodeUserCheckReq req);
}

View File

@ -0,0 +1,190 @@
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.orgmanax.dto.cooperateship.dto.OrgCooperateShipDTO;
import cn.axzo.orgmanax.dto.cooperateship.req.ListOrgCooperateShipReq;
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.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.nodeuser.service.NodeUserCheckService;
import cn.axzo.orgmanax.server.nodeuser.service.NodeUserService;
import cn.axzo.tyr.feign.enums.IdentityTypeEnum;
import cn.axzo.tyr.feign.enums.RoleTypeEnum;
import cn.axzo.tyr.feign.req.PageRoleUserReq;
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 com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor
public class NodeUserCheckServiceImpl implements NodeUserCheckService {
private final WorkspaceGateway workspaceGateway;
private final RoleUserGateway roleUserGateway;
private final PersonProfileGateway profileGateway;
private final CooperateShipService cooperateShipService;
private final NodeUserService nodeUserService;
// 企业内班组长岗位编码
@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<>();
Map<Long, List<BatchDeleteNodeUserCheckResp.CheckFailInfo>> failInfoMap = new HashMap<>();
Long ouId = req.getOuId();
Long workspaceId = req.getWorkspaceId();
Set<Long> personIds = req.getPersonIds();
ParticipatingUnitListReq participatingUnitListReq = new ParticipatingUnitListReq();
participatingUnitListReq.setLevels(ListUtil.of(Workspace.WorkspaceTypeEnum.GENERAL_ENT.value, Workspace.WorkspaceTypeEnum.GENERAL_PROJECT.value));
participatingUnitListReq.setWorkspaceId(workspaceId);
participatingUnitListReq.setOrganizationUnitId(ouId);
List<ParticipatingUnitResp> participatingUnitList = workspaceGateway.listParticipatingUnits(participatingUnitListReq);
Axssert.checkNotEmpty(participatingUnitList, "当前单位未参建任何项目,获取详细信息失败");
Long topNodeId = participatingUnitList.get(0).getOrganizationNodeId();
//1 单位联系人(超管)不能删除
PageRoleUserReq param = new PageRoleUserReq();
PageRoleUserReq.WorkspaceOuPair workspaceOuPair = new PageRoleUserReq.WorkspaceOuPair();
workspaceOuPair.setWorkspaceId(workspaceId);
workspaceOuPair.setOuId(ouId);
param.setWorkspaceOuPairs(Collections.singletonList(workspaceOuPair));
param.setRoleTypes(Collections.singleton(RoleTypeEnum.SUPER_ADMIN));
List<RoleUserResp> superAminInfoResult = roleUserGateway.pageAll(param);
superAminInfoResult.forEach(e -> {
if (personIds.contains(e.getPersonId())) {
BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo();
checkFailInfo.setType(CheckInfoTypeEnum.SUPER_ADMIN);
addFailInfo(failInfoMap, e.getPersonId(), checkFailInfo);
}
});
ListOrgCooperateShipReq listOrgCooperateShipReq = new ListOrgCooperateShipReq();
listOrgCooperateShipReq.setOuIds(Collections.singleton(ouId));
listOrgCooperateShipReq.setStatuses(CollUtil.newHashSet(0, 1));
List<OrgCooperateShipDTO> listPersonJoinedWorkspace = cooperateShipService.list(listOrgCooperateShipReq);
Set<Long> inProjectPersonIds = filterByPerson(listPersonJoinedWorkspace, personIds);
if (CollectionUtil.isNotEmpty(inProjectPersonIds)) {
inProjectPersonIds.forEach(e -> {
BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo();
checkFailInfo.setType(CheckInfoTypeEnum.IN_PROJECT);
addFailInfo(failInfoMap, e, checkFailInfo);
});
}
ListNodeUserReq nodeUserQueryVO = new ListNodeUserReq();
nodeUserQueryVO.setPersonIds(personIds);
nodeUserQueryVO.setOrganizationalUnitId(ouId);
nodeUserQueryVO.setTopNodeIds(Collections.singletonList(topNodeId));
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();
organizationalNodeUserList.forEach(organizationalNodeUserVO -> {
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 -> {
BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo();
checkFailInfo.setType(CheckInfoTypeEnum.TEAM_LEADER);
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);
});
}
return resultList;
}
private Set<Long> filterByPerson(List<OrgCooperateShipDTO> result, Set<Long> personIds) {
if (CollUtil.isEmpty(personIds)) {
return personIds;
}
Set<Long> filterResult = new HashSet<>();
List<Long> topNodeIds = result.stream()
.map(OrgCooperateShipDTO::getOrganizationalNodeId)
.distinct()
.collect(Collectors.toList());
ListNodeUserReq nodeUserReq = new ListNodeUserReq();
nodeUserReq.setTopNodeIds(topNodeIds);
nodeUserReq.setPersonIds(personIds);
List<NodeUserDTO> nodeUserDTOS = nodeUserService.list(nodeUserReq);
Map<Long, Long> personNodeMap = nodeUserDTOS.stream().collect(Collectors.toMap(NodeUserDTO::getPersonId, NodeUserDTO::getTopNodeId));
Set<Long> shipNodeIds = result.stream().map(OrgCooperateShipDTO::getOrganizationalNodeId).collect(Collectors.toSet());
for (Map.Entry<Long, Long> entry : personNodeMap.entrySet()) {
if (shipNodeIds.contains(entry.getValue())) {
filterResult.add(entry.getKey());
}
}
return filterResult;
}
private void addFailInfo(Map<Long, List<BatchDeleteNodeUserCheckResp.CheckFailInfo>> failInfoMap, Long personId, BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo) {
failInfoMap.computeIfAbsent(personId, k -> new ArrayList<>()).add(checkFailInfo);
}
@Override
public List<BatchDeleteNodeUserCheckResp> checkWorkspace(BatchDeleteNodeUserCheckReq req) {
return new ArrayList<>();
}
}