!1303 子流程优化

Merge pull request !1303 from Lesan/feature/bpm-子流程
This commit is contained in:
芋道源码 2025-03-25 04:44:01 +00:00 committed by Gitee
commit 2cf5e17f4b
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 34 additions and 7 deletions

View File

@ -42,6 +42,7 @@ public interface ErrorCodeConstants {
ErrorCode PROCESS_INSTANCE_CANCEL_FAIL_NOT_ALLOW = new ErrorCode(1_009_004_005, "流程取消失败,该流程不允许取消");
ErrorCode PROCESS_INSTANCE_HTTP_TRIGGER_CALL_ERROR = new ErrorCode(1_009_004_006, "流程 Http 触发器请求调用失败");
ErrorCode PROCESS_INSTANCE_APPROVE_USER_SELECT_ASSIGNEES_NOT_CONFIG = new ErrorCode(1_009_004_007, "下一个任务({})的审批人未配置");
ErrorCode CHILD_PROCESS_INSTANCE_CANCEL_FAIL_NOT_ALLOW = new ErrorCode(1_009_004_008, "子流程取消失败,子流程不允许取消");
// ========== 流程任务 1-009-005-000 ==========
ErrorCode TASK_OPERATE_FAIL_ASSIGN_NOT_SELF = new ErrorCode(1_009_005_001, "操作失败,原因:该任务的审批人不是你");

View File

@ -18,6 +18,7 @@ public enum BpmReasonEnum {
REJECT_TASK("审批不通过任务,原因:{}"), // 场景用户审批不通过任务修改文案时需要注意 isRejectReason 方法
CANCEL_PROCESS_INSTANCE_BY_START_USER("用户主动取消流程,原因:{}"), // 场景用户主动取消流程
CANCEL_PROCESS_INSTANCE_BY_ADMIN("管理员【{}】取消流程,原因:{}"), // 场景管理员取消流程
CANCEL_CHILD_PROCESS_INSTANCE_BY_MAIN_PROCESS("子流程自动取消,原因:主流程已取消"),
// ========== 流程任务的独有原因 ==========

View File

@ -148,7 +148,6 @@ public class BpmProcessInstanceController {
processDefinition, processDefinitionInfo, startUser, dept));
}
// TODO @lesan子流程子流程如果取消主流程应该是通过还是不通过哈还是禁用掉子流程的取消
@DeleteMapping("/cancel-by-start-user")
@Operation(summary = "用户取消流程实例", description = "取消发起的流程")
@PreAuthorize("@ss.hasPermission('bpm:process-instance:cancel')")

View File

@ -72,6 +72,9 @@ public class BpmApprovalDetailRespVO {
@Schema(description = "候选人用户列表")
private List<UserSimpleBaseVO> candidateUsers; // 只包含未生成 ApprovalTaskInfo 的用户列表
@Schema(description = "流程编号", example = "8761d8e0-0922-11f0-bd37-00ff1db677bf")
private String processInstanceId;
}
@Schema(description = "活动节点的任务信息")

View File

@ -813,7 +813,6 @@ public class SimpleModelUtils {
callActivity.setCalledElementType("key");
// 1. 是否异步
if (node.getChildProcessSetting().getAsync()) {
// TODO @lesan: 这里目前测试没有跳过执行call activity 后面的节点
callActivity.setAsynchronous(true);
}

View File

@ -387,8 +387,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
List<HistoricActivityInstance> activities, List<HistoricTaskInstance> tasks) {
// 遍历 tasks 列表只处理已结束的 UserTask
// 为什么不通过 activities 因为加签场景下它只存在于 tasks没有 activities导致如果遍历 activities 的话它无法成为一个节点
// TODO @芋艿子流程只有activity这里获取不到已结束的子流程
// TODO @lesan子流程基于 activities 查询出 usertaskcallactivity然后拼接如果是子流程就是可以点击过去
List<HistoricTaskInstance> endTasks = filterList(tasks, task -> task.getEndTime() != null);
List<ActivityNode> approvalNodes = convertList(endTasks, task -> {
FlowElement flowNode = BpmnModelUtils.getFlowElementById(bpmnModel, task.getTaskDefinitionKey());
@ -410,7 +408,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
// 遍历 activities只处理已结束的 StartEventEndEvent
List<HistoricActivityInstance> endActivities = filterList(activities, activity -> activity.getEndTime() != null
&& (StrUtil.equalsAny(activity.getActivityType(), ELEMENT_EVENT_START, ELEMENT_EVENT_END)));
&& (StrUtil.equalsAny(activity.getActivityType(), ELEMENT_EVENT_START, ELEMENT_CALL_ACTIVITY, ELEMENT_EVENT_END)));
endActivities.forEach(activity -> {
// StartEvent只处理 BPMN 的场景因为SIMPLE 情况下已经有 START_USER_NODE 节点
if (ELEMENT_EVENT_START.equals(activity.getActivityType())
@ -444,7 +442,18 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
}
approvalNodes.add(endNode);
}
// CallActivity
if (ELEMENT_CALL_ACTIVITY.equals(activity.getActivityType())) {
ActivityNode callActivity = new ActivityNode().setId(activity.getId())
.setName(BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getName())
.setNodeType(BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType()).setStatus(processInstanceStatus)
.setStartTime(DateUtils.of(activity.getStartTime()))
.setEndTime(DateUtils.of(activity.getEndTime()))
.setProcessInstanceId(activity.getProcessInstanceId());
approvalNodes.add(callActivity);
}
});
approvalNodes.sort(Comparator.comparing(ActivityNode::getStartTime));
return approvalNodes;
}
@ -464,7 +473,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
HistoricActivityInstance::getActivityId);
// 按照 activityId 分组构建 ApprovalNodeInfo 节点
// TODO @lesan子流程在子流程进行审批的时候HistoricActivityInstance 里面可以拿到 runActivities.get(0).getCalledProcessInstanceId()要不要支持跳转
Map<String, HistoricTaskInstance> taskMap = convertMap(tasks, HistoricTaskInstance::getId);
return convertList(runningTaskMap.entrySet(), entry -> {
String activityId = entry.getKey();
@ -510,6 +518,9 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
approvalTaskInfo.getAssignee())); // 委派或者向前加签情况需要先比较 owner
activityNode.setCandidateUserIds(CollUtil.sub(candidateUserIds, index + 1, candidateUserIds.size()));
}
if (BpmSimpleModelNodeTypeEnum.CHILD_PROCESS.getType().equals(activityNode.getNodeType())) {
activityNode.setProcessInstanceId(firstActivity.getProcessInstanceId());
}
return activityNode;
});
}
@ -823,6 +834,10 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
&& Boolean.FALSE.equals(processDefinitionInfo.getAllowCancelRunningProcess())) {
throw exception(PROCESS_INSTANCE_CANCEL_FAIL_NOT_ALLOW);
}
// 1.4 子流程不允许取消
if (StrUtil.isNotBlank(instance.getSuperExecutionId())) {
throw exception(CHILD_PROCESS_INSTANCE_CANCEL_FAIL_NOT_ALLOW);
}
// 2. 取消流程
updateProcessInstanceCancel(cancelReqVO.getId(),
@ -849,7 +864,16 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
BpmProcessInstanceStatusEnum.CANCEL.getStatus());
runtimeService.setVariable(id, BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_REASON, reason);
// 2. 结束流程
// 2. 取消所有子流程
List<ProcessInstance> subProcessInstances = runtimeService.createProcessInstanceQuery()
.superProcessInstanceId(id)
.list();
subProcessInstances.forEach(processInstance -> {
updateProcessInstanceCancel(processInstance.getProcessInstanceId(),
BpmReasonEnum.CANCEL_CHILD_PROCESS_INSTANCE_BY_MAIN_PROCESS.getReason());
});
// 3. 结束流程
taskService.moveTaskToEnd(id, reason);
}