Skip to content

Commit 6232b7a

Browse files
song-cc-rockfit2-zhao
authored andcommitted
feat: Approval exception handler
1 parent 6c3b872 commit 6232b7a

6 files changed

Lines changed: 244 additions & 59 deletions

File tree

backend/crm/src/main/java/cn/cordys/crm/approval/constants/ApprovalStatus.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,11 @@ public enum ApprovalStatus {
1616
/** 已驳回 */
1717
UNAPPROVED,
1818
/** 已撤销 */
19-
REVOKED
19+
REVOKED,
20+
21+
// 扩展项
22+
/** 自动通过 */
23+
AUTO_APPROVED,
24+
/** 自动拒绝 */
25+
AUTO_UNAPPROVED
2026
}

backend/crm/src/main/java/cn/cordys/crm/approval/service/ApprovalActionService.java

Lines changed: 100 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ private void approvedProcess(ApprovalTask currentTask, String currentUserId, Str
326326
appendProcessSignTask(currentTask);
327327

328328
// 多人依次审批类型的待办
329+
List<ApprovalTask> multiSeqApprovalTasks = new ArrayList<>();
329330
ApprovalNodeApprover nodeApprover = getNodeApprover(currentTask.getNodeId());
330331
if (MultiApproverModeEnum.valueOf(nodeApprover.getMultiApproverMode()) == MultiApproverModeEnum.SEQUENTIAL) {
331332
// 依次审批, 如果存在审批中任务则跳过
@@ -337,8 +338,23 @@ private void approvedProcess(ApprovalTask currentTask, String currentUserId, Str
337338
if (approvingTasks.isEmpty()) {
338339
User nextUser = getMultiSeqNextOne(currentTask.getNodeId(), currentTask.getInstanceId(), currentOrgId);
339340
if (nextUser != null) {
340-
ApprovalTask multiSeqNextTask = buildTask(currentTask.getNodeId(), currentTask.getInstanceId(), nextUser.getId(), ApprovalTaskType.NL.name(), currentUserId, currentTask.getNodeRound());
341-
approvalTaskMapper.insert(multiSeqNextTask);
341+
ApprovalTask nextTask = buildTask(currentTask.getNodeId(), currentTask.getInstanceId(), nextUser.getId(), ApprovalTaskType.NL.name(), currentUserId, currentTask.getNodeRound());
342+
// 如果配置审批人提审人相同跳过
343+
SameSubmitterActionEnum sameAction = SameSubmitterActionEnum.valueOf(nodeApprover.getSameSubmitterAction());
344+
ApprovalInstance instance = approvalInstanceMapper.selectByPrimaryKey(currentTask.getInstanceId());
345+
if (sameAction == SameSubmitterActionEnum.SKIP && Strings.CI.equals(nextUser.getId(), instance.getSubmitterId())) {
346+
nextTask.setAction(ApprovalAction.APPROVE.name());
347+
nextTask.setStatus(ApprovalStatus.AUTO_APPROVED.name());
348+
approvalFlowService.saveAutoRecord(currentTask.getInstanceId(), currentTask.getNodeId(), ApprovalStatus.AUTO_APPROVED, "审批人与提交人为同一人时, 自动同意跳过", nextTask.getId());
349+
// 依次审批下一位自动同意跳过, 发送下下一个位次的待办
350+
User nextPlusUser = getMultiSeqNextPlusOne(currentTask.getNodeId(), currentTask.getInstanceId(), currentOrgId);
351+
if (nextPlusUser != null) {
352+
ApprovalTask nextNextTask = buildTask(currentTask.getNodeId(), currentTask.getInstanceId(), nextPlusUser.getId(), ApprovalTaskType.NL.name(), currentUserId, currentTask.getNodeRound());
353+
multiSeqApprovalTasks.add(nextNextTask);
354+
}
355+
}
356+
multiSeqApprovalTasks.add(nextTask);
357+
approvalTaskMapper.batchInsert(multiSeqApprovalTasks);
342358
}
343359
}
344360
}
@@ -600,6 +616,29 @@ private User getMultiSeqNextOne(String nodeId, String instanceId, String current
600616
return null;
601617
}
602618

619+
/**
620+
* 获取多人依次审批下下一个审批人
621+
* @param nodeId 节点ID
622+
* @param instanceId 实例ID
623+
* @param currentOrgId 组织ID
624+
* @return 下一个审批人
625+
*/
626+
private User getMultiSeqNextPlusOne(String nodeId, String instanceId, String currentOrgId) {
627+
ApprovalInstance instance = approvalInstanceMapper.selectByPrimaryKey(instanceId);
628+
List<User> approvers = approvalFlowService.getCurrentNodeApproverList(nodeId, instance.getSubmitterId(), currentOrgId);
629+
LambdaQueryWrapper<ApprovalTask> queryWrapper = new LambdaQueryWrapper<>();
630+
queryWrapper.eq(ApprovalTask::getNodeId, nodeId)
631+
.eq(ApprovalTask::getInstanceId, instanceId)
632+
.eq(ApprovalTask::getType, ApprovalTaskType.NL.name())
633+
.eq(ApprovalTask::getStatus, ApprovalStatus.APPROVED.name());
634+
List<ApprovalTask> approvedTask = approvalTaskMapper.selectListByLambda(queryWrapper);
635+
if (approvedTask.size() < approvers.size()) {
636+
// 依次审批, 返回下下一个审批人
637+
return approvers.get(approvedTask.size() + 1);
638+
}
639+
return null;
640+
}
641+
603642
/**
604643
* 获取多人依次审批当前用户下一个审批人
605644
* @param nodeId 节点ID
@@ -845,7 +884,7 @@ private void handleNextApprovalNode(ApprovalNodeResponse node, ApprovalInstance
845884
resourceService.updateResourceApprovalStatus(FormKey.ofKey(instance.getType()), instance.getResourceId(), instance.getApprovalStatus());
846885
}
847886
if (ApprovalNodeTypeEnum.valueOf(node.getNodeType()) == ApprovalNodeTypeEnum.APPROVER) {
848-
List<ApprovalTask> approvalTasks = getNodeApproverTasks((ApprovalNodeApproverResponse) node, instance.getId(), currentUserId, ApprovalTaskType.NL.name());
887+
List<ApprovalTask> approvalTasks = getNodeApproverTasks((ApprovalNodeApproverResponse) node, instance.getId(), currentUserId, ApprovalTaskType.NL.name(), instance.getSubmitterId());
849888
List<ApprovalTask> ccTasks = getNodeCcTasks((ApprovalNodeApproverResponse) node, instance.getId(), currentUserId);
850889
List<ApprovalTask> allTasks = ListUtils.union(approvalTasks, ccTasks);
851890
if (CollectionUtils.isNotEmpty(allTasks)) {
@@ -888,17 +927,68 @@ public String selectBusinessName(FormKey formKey, String resourceId) {
888927
* @param taskType 任务类型
889928
* @return 待办任务集合
890929
*/
891-
public List<ApprovalTask> getNodeApproverTasks(ApprovalNodeApproverResponse approverNode, String instanceId, String userId, String taskType) {
930+
public List<ApprovalTask> getNodeApproverTasks(ApprovalNodeApproverResponse approverNode, String instanceId, String userId, String taskType, String submitter) {
892931
List<ApprovalTask> approvalTasks = new ArrayList<>();
893932
if (approverNode == null) {
894933
return approvalTasks;
895934
}
896935
Integer nextRound = extApprovalInstanceMapper.getNextNodeRound(instanceId, approverNode.getId());
897-
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(approverNode.getApproverList())) {
898-
approverNode.getApproverList().forEach(approver -> {
899-
ApprovalTask approvalTask = buildTask(approverNode.getId(), instanceId, approver, taskType, userId, nextRound);
900-
approvalTasks.add(approvalTask);
901-
});
936+
if (CollectionUtils.isNotEmpty(approverNode.getApproverList())) {
937+
MultiApproverModeEnum multiMode = MultiApproverModeEnum.valueOf(approverNode.getMultiApproverMode());
938+
SameSubmitterActionEnum sameAction = SameSubmitterActionEnum.valueOf(approverNode.getSameSubmitterAction());
939+
if (sameAction == SameSubmitterActionEnum.SKIP) {
940+
// 如果配置了审批人和提审人相同, 自动跳过 (会签, 依次审批 生成的提审人待办需直接同意, 或签和单人审批已在流程执行的时候处理过)
941+
switch (multiMode) {
942+
case SEQUENTIAL -> {
943+
// 依次审批只需要发送第一个人的待办
944+
String firstApprover = approverNode.getApproverList().get(0);
945+
ApprovalTask firstTask = buildTask(approverNode.getId(), instanceId, firstApprover, taskType, userId, nextRound);
946+
if (Strings.CI.equals(firstApprover, submitter)) {
947+
// 自动跳过该审批人
948+
firstTask.setAction(ApprovalAction.APPROVE.name());
949+
firstTask.setStatus(ApprovalStatus.AUTO_APPROVED.name());
950+
approvalFlowService.saveAutoRecord(instanceId, approverNode.getId(), ApprovalStatus.AUTO_APPROVED, "审批人与提交人为同一人时, 自动同意跳过", firstTask.getId());
951+
// 第一个需要自动同意跳过, 发送第二个人待办
952+
String secondApprover = approverNode.getApproverList().get(1);
953+
if (StringUtils.isNotBlank(secondApprover)) {
954+
ApprovalTask secondTask = buildTask(approverNode.getId(), instanceId, secondApprover, taskType, userId, nextRound);
955+
approvalTasks.add(secondTask);
956+
}
957+
}
958+
approvalTasks.add(firstTask);
959+
}
960+
case ALL -> {
961+
// 如果是会签, 需要发送所有审批人的待办
962+
approverNode.getApproverList().forEach(approver -> {
963+
ApprovalTask approvalTask = buildTask(approverNode.getId(), instanceId, approver, taskType, userId, nextRound);
964+
if (Strings.CI.equals(approver, submitter)) {
965+
// 自动跳过该审批人
966+
approvalTask.setAction(ApprovalAction.APPROVE.name());
967+
approvalTask.setStatus(ApprovalStatus.AUTO_APPROVED.name());
968+
approvalFlowService.saveAutoRecord(instanceId, approverNode.getId(), ApprovalStatus.AUTO_APPROVED, "审批人与提交人为同一人时, 自动同意跳过", approvalTask.getId());
969+
}
970+
approvalTasks.add(approvalTask);
971+
});
972+
}
973+
default -> {
974+
975+
}
976+
}
977+
} else {
978+
// 并未配置自动跳过的逻辑, 正常逻辑
979+
if (multiMode == MultiApproverModeEnum.SEQUENTIAL) {
980+
// 依次审批只需要发送第一个人的待办
981+
String firstApprover = approverNode.getApproverList().getFirst();
982+
ApprovalTask firstTask = buildTask(approverNode.getId(), instanceId, firstApprover, taskType, userId, nextRound);
983+
approvalTasks.add(firstTask);
984+
} else {
985+
// 会签, 或签需要发送所有待办
986+
approverNode.getApproverList().forEach(approver -> {
987+
ApprovalTask approvalTask = buildTask(approverNode.getId(), instanceId, approver, taskType, userId, nextRound);
988+
approvalTasks.add(approvalTask);
989+
});
990+
}
991+
}
902992
}
903993
return approvalTasks;
904994
}
@@ -909,7 +999,7 @@ public List<ApprovalTask> getNodeCcTasks(ApprovalNodeApproverResponse approverNo
909999
return approvalTasks;
9101000
}
9111001
Integer nextRound = extApprovalInstanceMapper.getNextNodeRound(instanceId, approverNode.getId());
912-
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(approverNode.getCcList())) {
1002+
if (CollectionUtils.isNotEmpty(approverNode.getCcList())) {
9131003
approverNode.getCcList().forEach(cc -> {
9141004
ApprovalTask approvalTask = buildTask(approverNode.getId(), instanceId, cc, ApprovalTaskType.CC.name(), userId, nextRound);
9151005
approvalTasks.add(approvalTask);

0 commit comments

Comments
 (0)