运行时,实现普通节点转会签节点。
注意:该方法会改变原来的流程定义,导致下个实例发起错误。个人认为用处不大,仅仅作为技术实现探讨。
/**
* 普通节点转会签节点-相当于改变了流程定义,后面如果再次发起流程,会出现错误-待解
* 认领模式不存在加签,普通节点加签时只有一个人;
*/
public MvcResult<Boolean> toCountersign(String taskId, String addSignUserId) {
// 根据任务ID获取当前任务对象.
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
// 根据流程定义ID获取流程bpmnModel.
BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
// 获取当前流程对象.
Process process = bpmnModel.getProcesses().get(0);
// 根据当前节点ID获取对应任务节点对象.
UserTask currentUserTask = (UserTask) process.getFlowElement(task.getTaskDefinitionKey());
// 获取当前节点出线信息.
SequenceFlow sequenceFlow = currentUserTask.getOutgoingFlows().get(0);
// 根据当前节点出线信息获取下一节点元素.
FlowElement flowElement = process.getFlowElement(sequenceFlow.getTargetRef());
// 判断下一节点元素是否为任务节点.
// 配置会签所需条件.
MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = new MultiInstanceLoopCharacteristics();
// 配置节点人员办理顺序 串行:true 并行:false.
multiInstanceLoopCharacteristics.setSequential(false);
// 配置会签集合变量名称.
multiInstanceLoopCharacteristics.setInputDataItem(task.getTaskDefinitionKey());
// 配置会签集合遍历名称.
multiInstanceLoopCharacteristics.setElementVariable("signAssignee");
multiInstanceLoopCharacteristics.setCompletionCondition("${nrOfInstances == nrOfCompletedInstances}");
// 将下一节点元素转换为任务节点对象.
//UserTask nextUserTask = (UserTask) flowElement;
// 设置下一节点处理人表达式 引用会签条件activiti:elementVariable="assignee".
currentUserTask.setAssignee("${signAssignee}");
// 下一任务节点设置会签循环特征.
currentUserTask.setLoopCharacteristics(multiInstanceLoopCharacteristics);
// 获取流程引擎配置实现类.
ProcessEngineConfigurationImpl processEngineConfiguration = (ProcessEngineConfigurationImpl) ProcessEngines.getDefaultProcessEngine().getProcessEngineConfiguration();
// 创建新的任务实例.
UserTaskActivityBehavior userTaskActivityBehavior = processEngineConfiguration.getActivityBehaviorFactory().createUserTaskActivityBehavior(currentUserTask);
// 创建BPMN 2.0规范中描述的多实例功能.
ParallelMultiInstanceBehavior behavior = new ParallelMultiInstanceBehavior(currentUserTask, userTaskActivityBehavior);
// 设置下一节点多实例行为.
currentUserTask.setBehavior(behavior);
// 设置多实例元素变量.
behavior.setCollectionElementVariable("signAssignee");
// 注入表达式.
ExpressionManager expressionManager = processEngineConfiguration.getExpressionManager();
// 设置多实例集合表达式.
behavior.setCollectionExpression(expressionManager.createExpression(task.getTaskDefinitionKey()));
if(addSignUserId.equals(task.getAssignee())){
return MvcResult.failed(ErrorCode.E_10.code(), messageSource.getMessage("i18n85", null, "", LangThreadLocal.get()));
}
Set<String> signAssigneeList = new HashSet<>();
signAssigneeList.add(task.getAssignee());
signAssigneeList.add(addSignUserId);
runtimeService.setVariable(task.getProcessInstanceId(), task.getTaskDefinitionKey(), signAssigneeList);
Map<String, Object> executionVariables = new HashMap<>();
executionVariables.put("signAssignee", addSignUserId);
managementService.executeCommand(new CustomCommonToCounterSignCmd(task.getTaskDefinitionKey(), task.getProcessInstanceId(), executionVariables));
//runtimeService.addMultiInstanceExecutionCmd(task.getTaskDefinitionKey(),task.getProcessInstanceId() , executionVariables);
return MvcResult.of(true);
}