fix(bpm):解决由于退回的任务中已有自选审批人相关数据,导致退回后重新自选审批人相关数据被旧数据影响的问题。

This commit is contained in:
吴焕超 2025-05-23 16:01:51 +08:00
parent 72c8ac3817
commit 38607f0a3e
3 changed files with 73 additions and 1 deletions

View File

@ -59,7 +59,7 @@ public class BpmParallelMultiInstanceBehavior extends ParallelMultiInstanceBehav
// 第二步获取任务的所有处理人
@SuppressWarnings("unchecked")
Set<Long> assigneeUserIds = (Set<Long>) execution.getVariable(super.collectionVariable, Set.class);
Set<Long> assigneeUserIds = (Set<Long>) execution.getVariableLocal(super.collectionVariable, Set.class);
if (assigneeUserIds == null) {
assigneeUserIds = taskCandidateInvoker.calculateUsersByTask(execution);
if (CollUtil.isEmpty(assigneeUserIds)) {

View File

@ -755,6 +755,48 @@ public class BpmnModelUtils {
return userTaskList;
}
/**
* 获取当前元素后可能执行到的所有userTask
*
* @param startElement 起始元素
* @param bpmnModel 流程模型
* @return 当前元素后可能执行到的所有userTask不包含自身
*/
public static Set<UserTask> findReachableUserTasks(FlowElement startElement, BpmnModel bpmnModel) {
Set<UserTask> userTasks = new HashSet<>();
Set<String> visited = new HashSet<>();
if (startElement instanceof FlowNode) {
List<SequenceFlow> outgoing = ((FlowNode) startElement).getOutgoingFlows();
for (SequenceFlow flow : outgoing) {
FlowElement target = bpmnModel.getMainProcess().getFlowElement(flow.getTargetRef());
dfs(target, bpmnModel, userTasks, visited);
}
}
return userTasks;
}
private static void dfs(FlowElement current, BpmnModel model, Set<UserTask> userTasks, Set<String> visited) {
if (current == null || visited.contains(current.getId())) {
return;
}
visited.add(current.getId());
if (current instanceof UserTask) {
userTasks.add((UserTask) current);
}
if (current instanceof FlowNode) {
List<SequenceFlow> outgoingFlows = ((FlowNode) current).getOutgoingFlows();
for (SequenceFlow flow : outgoingFlows) {
String targetRef = flow.getTargetRef();
FlowElement targetElement = model.getMainProcess().getFlowElement(targetRef);
dfs(targetElement, model, userTasks, visited);
}
}
}
// ========== BPMN 流程预测相关的方法 ==========
/**

View File

@ -925,6 +925,36 @@ public class BpmTaskServiceImpl implements BpmTaskService {
.processInstanceId(currentTask.getProcessInstanceId())
.moveExecutionToActivityId(mainExecutionId, reqVO.getTargetTaskDefinitionKey())
.changeState();
// 5. 清除'审批人自选'策略相关数据
// 移除退回后不会自动通过的节点的审批人数据
// 根据自动去重设置执行相关操作
BpmProcessDefinitionInfoDO processDefinitionInfo = bpmProcessDefinitionService.getProcessDefinitionInfo(currentTask.getProcessDefinitionId());
BpmnModel bpmnModel = bpmProcessDefinitionService.getProcessDefinitionBpmnModel(currentTask.getProcessDefinitionId());
ProcessInstance processInstance = processInstanceService.getProcessInstance(currentTask.getProcessInstanceId());
if (BpmAutoApproveTypeEnum.NONE.getType().equals(processDefinitionInfo.getAutoApprovalType())) {
// 不自动通过清除 targetElement 后所有节点的审批人数据
Map<String, List<Long>> approveUserSelectAssignees = FlowableUtils.getApproveUserSelectAssignees(processInstance);
if (ObjectUtil.isNotEmpty(approveUserSelectAssignees)) {
Set<UserTask> reachableUserTasks = findReachableUserTasks(targetElement, bpmnModel);
for (UserTask reachableUserTask : reachableUserTasks) {
approveUserSelectAssignees.remove(reachableUserTask.getId());
}
runtimeService.setVariable(processInstance.getProcessInstanceId(),BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES,approveUserSelectAssignees);
}
} else if (BpmAutoApproveTypeEnum.APPROVE_SEQUENT.getType().equals(processDefinitionInfo.getAutoApprovalType())) {
// TODO 优化去重规则为连续审批的节点自动通过看退回到目标节点后会自动通过走到哪里将走到的位置之后的节点自选审批人数据清空
// 暂且清除 targetElement 后所有节点的审批人数据
// 自动通过时若候选人策略为'审批人自选'会因为缺失自选审批人报错需要重新选择审批人手动审批
Map<String, List<Long>> approveUserSelectAssignees = FlowableUtils.getApproveUserSelectAssignees(processInstance);
if (ObjectUtil.isNotEmpty(approveUserSelectAssignees)) {
Set<UserTask> reachableUserTasks = findReachableUserTasks(targetElement, bpmnModel);
for (UserTask reachableUserTask : reachableUserTasks) {
approveUserSelectAssignees.remove(reachableUserTask.getId());
}
runtimeService.setVariable(processInstance.getProcessInstanceId(),BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_APPROVE_USER_SELECT_ASSIGNEES,approveUserSelectAssignees);
}
}
// 若为自动通过还会走到当前节点不清除节点自选审批人数据
}
@Override