参考地址:https://blog.youkuaiyun.com/qq_30739519/article/details/51239818
https://blog.youkuaiyun.com/u013314807/article/details/70308426
https://blog.youkuaiyun.com/chq1988/article/details/41513451
1.会签分多实例串行和并行两种
串行和并行区别:
串行会根据传入的list用户顺序,一个完成后才可以执行下一个任务。
并行直接生成list长度个数的待办任务,互不影响
1.1
如下图选择Sequential(串行)或者Parallel(并行):
1.2 下图${userList}是传入的会签人的ID集合
会根据 “元素变量(多实例)”设置的key值到"集合(多实例)"的集合中通过 "分配用户" 的表达式获取list中每个值,然后会把每个值生成一个任务,这样list中的每个用户都会收到一个待办事项
这三个需要配套使用,集合(多实例)"要和"分配用户" 保持一致
1.3下图设置循环执行基数:若为空,则根据集合的长度自动生成
1.4 可以为空,默认是所有人完成
nrOfInstances 实例总数,基于"基数(多实例)" 设置
nrOfCompletedInstances 已完成多实例数目
loopCounter 已经循环的次数
nrOfActiveInstances 已经完成的实例个数,串行一直是1,并行每一次加1
官方解释:
-
nrOfInstances: the total number of instances
-
nrOfActiveInstances: the number of currently active, i.e. not yet finished, instances. For a sequential multi-instance, this will always be 1.
-
nrOfCompletedInstances: the number of already completed instances.
1.5
集合(多实例)的设置方式:
1.5.1 直接在流程图中指定:
user1,user2,user3
1.5.2
流程变量设置方式:
${userList}
String[] candidate=new String [3];
candidate[0]=user1;
candidate[1]=user2;
candidate[2]=user3;
Arrays.asList(candidate)
ps:userList的传参格式是:[user1,user2,user3]
二。会签驳回
参考地址:https://yang-ch.iteye.com/blog/2034259
此处驳回是自动驳回到上一个节点。
业务需求:
会签人数是N个人只有所有人都审批过了才会通过,只要有一人拒绝都会驳回到上一节点。
流程图:
解决逻辑:
会签人员审批通过时正常审批,若有一人审批则通过减签的方式把其余的任务都减掉,
比如会签需要四个人审批,则第一个人审批不通过,则把其余三个人通过减签的方式都去掉。
实现方式:activity监听器
代码:事件配置要选择:complete事件
package com.pactera.workflow.interceptor;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowNode;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.delegate.TaskListener;
import org.flowable.engine.impl.bpmn.behavior.MultiInstanceActivityBehavior;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ExecutionQuery;
import org.flowable.task.service.delegate.DelegateTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
//多实例任务完成事件监听器
//触发完成事件时才会触发此监听器
@Component
public class CompleteMultiTaskListner implements TaskListener, ExecutionListener {
private static RuntimeService runtimeService;
private static RepositoryService repositoryService;
@Autowired
public void setRuntimeService(RuntimeService runtimeService){
this.runtimeService=runtimeService;
}
@Autowired
public void setRepositoryService(RepositoryService repositoryService){
this.repositoryService=repositoryService;
}
@Override
public void notify(DelegateTask delegateTask) {
//获取当前的执行实例
ExecutionQuery executionQuery =runtimeService.createExecutionQuery();
ExecutionEntity executionEntity = (ExecutionEntity)executionQuery.executionId(delegateTask.getExecutionId()).singleResult();
String activityId=executionEntity.getActivityId();
//获取当前活动节点信息
FlowNode flowNode=getFlowNode(delegateTask.getProcessDefinitionId(),activityId);
//获取当前审批人的审批意向
String circulationConditions=(String) delegateTask.getVariable("circulationConditions");
//处理并行网关的多实例
if ("N".equals(circulationConditions) && flowNode.getBehavior() instanceof MultiInstanceActivityBehavior){
// ExecutionEntity executionEntity = (ExecutionEntity)runtimeService.createExecutionQuery().executionId(delegateTask.getExecutionId()).singleResult();
String parentId=executionEntity.getParentId();
//此处获得的Execution是包括所有Execution和他们的父Execution,减签的时候要先删除子的才能删除父的
List<Execution> executions =runtimeService.createExecutionQuery().processInstanceId(delegateTask.getProcessInstanceId()).onlyChildExecutions().list();
System.out.println(parentId);
for (Execution execution:executions){
if (!execution.getId().equals(parentId) && !executionEntity.getId().equals(execution.getId())){
System.out.println(execution.getParentId());
runtimeService.deleteMultiInstanceExecution(execution.getId(),false);
}
}
}
}
//获取当前节点的节点信息
private FlowNode getFlowNode(String processDefinitionId, String activityId){
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityId);
return flowNode;
}
@Override
public void notify(DelegateExecution execution) {
execution.getCurrentFlowElement();
}
}
这样,正常驳回到上一个节点。