Flowable 6.4 多实例会签 审批人设置、结果判断、会签后走向

目前最新版的Flowable6.4,与旧版或Activiti有些许区别。由于关于Flowable的文章比较稀缺,遇到不少坑,特此记录。
参考文章:http://huan1993.iteye.com/blog/2249764
第一部分是部署文件的大致说明,其他文章也有介绍,熟悉的可以跳过

  1. 首先部署文件中:

      
        
        
      
      
        ${multiInstance.accessCondition(execution)}
      

userTask标签中 ,flowable:assignee 表示取得multiInstanceLoopCharacteristics标签中flowable:elementVariable的值,而flowable:elementVariable的值表示flowable:collection这个审批人集合变量的每一个审批人变量;
extensionElements标签中,设置的是绑定的TaskListener;
multiInstanceLoopCharacteristics 标签中,设置的是多实例特点,其中:
isSequential属性表示是否串行,串行也就是说是否按顺序挨个儿执行。
flowable:collection是在上一个任务节点中放在map里的key值。

  1. ExecutionListener和TaskListener以及多实例任务结束条件类

下面说一下多实例任务的分配人环节以及结束条件部分。

分配人可以像其他文章一样使用ServiceTask读取上个节点存储的审批人。我是觉得必要性不大,直接在上个任务节点把审批人的集合存到map里完成任务即可。
map.put(“pers”, Arrays.asList(pers_arr));
taskService.complete(taskId, map);
类似于这样。注意map的key和部署文件中flowable:collection的值相同即可。

然后说一下多实例任务结束条件判定部分的坑。我当时看其他文章一直不明白为什么有了结束条件类还要绑TaskListener类,同样都可以用作监听完成任务之后的回调。
关键就在于ExecutionListener与TaskListener的可复写方法notify。这个方法的参数是DelegateExecution与DelegateTask。这两个类官方API的解释是 used in JavaDelegates and ExecutionListeners以及used in JavaDelegates and DelegateListeners。而JavaDelegates是用ServiceTask分配审批人的方式,是直接在DelegateExecution的变量调用setVariable方法设置审批人的。
这两种设置审批人的方法其实都是设置在了多实例任务所处的execution里的,所以均可。

区别在于多实例任务每次每个审批人comlete了之后。
首先说一下调用顺序,当taskService.complete(taskId, map)调用完之后,如果TaskListener的监听事件设置为comlete,那么这里会先触发TaskListener中的notify方法,之后再触发结束条件类的自定义结束函数。并且多实例任务中每次complete了之后都会顺序触发这两个类中的回调函数。
这是我的结束条件判断类:

public class MultiInstanceCompleteTask implements Serializable {
    /**
     * 评估结果判定条件
     * @param execution 分配执行实例
     */
    public boolean accessCondition(DelegateExecution execution){
    	//已完成的实例数
        int completedInstance = (int)execution.getVariable("nrOfCompletedInstances");
    	//否决判断,一票否决
    	if (execution.getVariable(“reject”) != null){
            int rejectCount = (int)execution.getVariable(“reject”);
            if(rejectCount > 0 ){
            	//输出方向为拒绝
                execution.setVariable("outcome", “reject”);
                //一票否决其他实例没必要做,结束
                return true;
            }
        }
        //所有实例任务未全部做完则继续其他实例任务
        if(completedInstance != sum){
            return false;
        }else{
        	//输出方向为赞同
        	execution.setVariable("outcome",“approved”);
        	//所有都做完了没被否决,结束
            return true;
        }
    }

我部署文件代码中multiInstance.accessCondition(execution)对应的便是此处。其中的mulitiInstance如果是和spring整合了,就是spring管理的bean的id,否则就是流程变量的key。

我遇到的坑在于无论你在多实例任务调用taskService.complete(taskId, map)之前往map里存了什么,在这个结束条件类里都是取不到的。
原因在于这里的回调参数是DelegateExecution类,是整体多实例任务的环境,在执行其中一个任务时是取不到的。
可以取到的类是DelegateTask类,所以我们每个实例的执行结果处理,应写在TaskListener类中,而结束条件类用作对TaskListener中的处理结果(包括各种结果的计数等)进行判断,然后在DelegateExecution的变量中设置输出方向是通过还是驳回等。这里判断函数的返回时是个boolean,它表示整个多实例任务节点是否结束,结束的意思是再进行下一个或其他多实例任务,还是将其他多实例任务短路掉直接结束,根据方法中setVariable中的值决定之后走向。也就是说boolean不代表接受或驳回,而是代表多实例任务节点是否提前结束。

另外计数变量的初值应在多实例任务节点钱的连线上绑定的ExecutionListener中设置,因为这才能作用于整个多实例任务。如果你在执行多实例任务中的某一个时是取不到的。代码如下:

public class IdeaExecutionListener implements ExecutionListener {

    @Override
    public void notify(DelegateExecution delegateExecution) {
        delegateExecution.setVariable("unrelated",0);
        delegateExecution.setVariable("rejected",0);
    }
}

TaskListener示例

public class IdeaTaskListener implements TaskListener {
    @Override
    public void notify(DelegateTask delegateTask) {
    	//result的值为控制类中taskService.complete(taskId, map)时,map中所设
        String result = (String) delegateTask.getVariable("result");
        //ExecutionListner类中设置的拒绝计数变量
    	int rejectedCount = (int)delegateTask.getVariable(“reject”);
    	if(“reject”.equals(result)){
            //拒绝
            delegateTask.setVariable("rejected", ++rejectedCount);
        }
    }

另附判断结果类中流程引擎自带可用变量:
1.nrOfInstances 该会签环节中总共有多少个实例

2.nrOfActiveInstances 当前活动的实例的数量,即还没有 完成的实例数量。

3.nrOfCompletedInstances 已经完成的实例的数量

新手第一次写博文,哪里写的有误或者不足的地方,请各位大佬多多指教。也欢迎大家咨询相关问题!

你可能感兴趣的:(工作流)