flowable的多人会签和一票否决

首先直接上案例!

项目结构:

flowable的多人会签和一票否决_第1张图片

接下来代码:

Duorenhuiqian.bpmn20.xml:



  
    
    
      
        
        
        
      
      
        ${multiInstance.accessCondition(execution)}
      
    
    
    
      
        
      
    
    
    
    
      
        
      
    
    
    
    
    
    
      
    
    
      
    
  
  
    
      
        
      
      
        
      
      
        
      
      
        
      
      
        
      
      
        
      
      
        
      
      
        
        
      
      
        
        
      
      
        
        
      
      
        
        
      
      
        
        
      
      
        
        
      
    
  

application.yml:

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/foujueflowable?characterEncoding=UTF-8
    password: root
    username: root
    driver-class-name: com.mysql.jdbc.Driver
flowable:
  #关闭定时任务job
  async-executor-activate: false
scale: 0.5

assignee: person1,person2,person3,person4

yipiaofoujueren: pxy
ExpenseController:
package com.cars.ngtdms.cooperation.controller;

import org.flowable.engine.ProcessEngine;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;

@Controller

@RequestMapping(value = "expense")
@ResponseBody
public class ExpenseController {
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ProcessEngine processEngine;

    @Value("#{'${yipiaofoujueren}'.split(',')}")
    private List yipiaofoujueren;


    /**
     * 开启
     * @return
     */
    @RequestMapping(value = "add")
    public String StartTask(){
        runtimeService.startProcessInstanceByKey("countersign");
        return "OK";
    }



    /**
     * 执行
     * @return
     */
    @RequestMapping(value = "do")
    public List DoTask(String name){
       // List tasks = taskService.createTaskQuery().taskCandidateUser(name).list();
        List tasks = taskService.createTaskQuery().taskAssignee(name).list();
        List list = new ArrayList<>();
        System.out.println("[");
        for (Task task:tasks
             ) {

            System.out.println(task.getId());
            list.add("id:"+task.getId()+"   name:"+task.getName()+"    Assignee:"+task.getAssignee());

        }
        System.out.println("]");
        return list;
    }


    /**
     * 完成
     * @return
     */
    @RequestMapping(value = "done")
    @Transactional
    public String DoneTask(String name,String taskId,String flg){
        List list = taskService.createTaskQuery().taskAssignee(name).list();
        List taskList= new ArrayList<>();
        String taskId1="";
        for (Task task : list) {
            taskList.add("id:"+task.getId()+"name"+task.getName()+"审批人:"+task.getAssignee());
            taskId1 = task.getId();
            System.out.println(taskId);
        }
        System.out.println("完成前"+taskList);
       if ("n".equals(flg)){
            if (yipiaofoujueren.contains(name)){
                Map map = new HashMap<>();
                Integer reject = (int)taskService.getVariable(taskId1,"reject");
                map.put("reject",reject+1);
                taskService.complete(taskId,map);
            }else {
                Map map = new HashMap<>();
                Integer rejectPeson = (int)taskService.getVariable(taskId1,"rejectPeson");
                map.put("rejectPeson",rejectPeson+1);
                taskService.complete(taskId,map);

            }
        } else if ("y".equals(flg)){
           Map map = new HashMap<>();
           Integer agreePeson = (int)taskService.getVariable(taskId1,"agreePeson");
           map.put("agreePeson",agreePeson+1);
           taskService.complete(taskId,map);
       }

        List list1 = taskService.createTaskQuery().taskAssignee(name).list();
        List taskList1= new ArrayList<>();
        for (Task task : list1) {
            taskList1.add("id:"+task.getId()+"name"+task.getName()+"审批人:"+task.getAssignee());
        }
        System.out.println("完成后"+taskList1);
        return "通过";
    }


    /**
     * 查看当前任务名
     * @return
     */
    @RequestMapping(value = "select")
    public List SelectTask(){
        List list = taskService.createTaskQuery().list();
        List taskList=new ArrayList<>();
        for (Task task : list) {
            taskList.add(task.getId()+"-----------"+task.getName());

        }

        return taskList;
    }



}
CountersignListener:
package com.cars.ngtdms.cooperation.flowable.listener;

import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;


import java.util.HashMap;
import java.util.List;
@Component
public class CountersignListener implements ExecutionListener {
    @Value("#{'${assignee}'.split(',')}")
    private List list;
    @Override
    public void notify(DelegateExecution delegateExecution) {
        System.out.println("读取的审批人是:"+list);
            HashMap map = new HashMap<>();
            //定义的人员列表4人
            //String[] person = { "person1", "person2", "person3","pxy" };
            //map.put("assigneeList", Arrays.asList(person));
            map.put("assigneeList", list);
            map.put("reject", 0);
            map.put("rejectPeson", 0);
            map.put("agreePeson", 0);
            delegateExecution.setVariables(map);

    }
}
ApplicationPxy:
package com.cars.ngtdms.cooperation;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
//@EnableDiscoveryClient
public class ApplicationPxy {

    public static void main(String[] args) {
        SpringApplication.run(ApplicationPxy.class,args);
    }
}
MultiInstanceCompleteTask:
package com.cars.ngtdms.cooperation;

import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.Serializable;

@Component(value = "multiInstance")
public class MultiInstanceCompleteTask implements Serializable{
    /**
     * 评估结果判定条件
     * @param execution 分配执行实例
     */
    @Value("${scale}")
    private String scaleStr;


    public boolean accessCondition(DelegateExecution execution) {
        Double scale = Double.valueOf(scaleStr);
        System.out.println("比例是:"+scale);
        System.out.println("I am running!!!!!!");
        System.out.println("TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT");
        //已完成的实例数
        int completedInstance = (int) execution.getVariable("nrOfCompletedInstances");
        System.out.println("此时已完成的实例数为:"+completedInstance);
        //否决判断,一票否决
        if (execution.getVariable("reject") != null) {
            int rejectCount = (int) execution.getVariable("reject");
            System.out.println("reject:"+rejectCount);
            if (rejectCount > 0) {
                //输出方向为拒绝
                execution.setVariable("outcome", "否决");
                //一票否决其他实例没必要做,结束
                return true;
            }
        }
        //获取所有的实例数
        int AllInstance = (int)execution.getVariable("nrOfInstances");
        System.out.println("总实例数目:"+AllInstance);
        //获取不同意的次数
        int rejectPeson = (int)execution.getVariable("rejectPeson");
        System.out.println("不同意的人的个数为:"+rejectPeson);
        //获取同意人的次数
        int agreePeson = (int)execution.getVariable("agreePeson");
        System.out.println("同意的人的个数为:"+agreePeson);


        //所有实例任务未全部做完则继续其他实例任务
        if (completedInstance != AllInstance) {
            //加入不同意的人数大于设置比例*总人数
            if (rejectPeson*1.00/AllInstance>(1-scale)){
                execution.setVariable("outcome", "否决");
                return true;
            }
            if (agreePeson*1.00/AllInstance>=scale){
                execution.setVariable("outcome", "通过");
                return true;
            }

            return false;
        } else {
            //输出方向为赞同
            execution.setVariable("outcome", "通过");
            //所有都做完了没被否决,结束
            return true;
        }



    }
}

依赖:

 
        
            org.flowable
            flowable-spring-boot-starter
            6.4.1
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            mysql
            mysql-connector-java
        

好了 这样就可以直接运行了,数据库的名字要设置对

 

然后开始解释:

多人会签意思是这一个任务需要很多人来进行审批,同意总数超过或者未超过多少比例的时候会执行对应的某个任务。

还有个就是一票否决,指定某个人,它反对就直接相当于全部反对

代码解释:

首先配置文件application:

flowable的多人会签和一票否决_第2张图片

然后xml文件:

flowable的多人会签和一票否决_第3张图片

标签的具体工作原理这里不再赘述,可以自行百度

然后就是监听器CountersignListener:

flowable的多人会签和一票否决_第4张图片然后就是执行器的配置内容了MultiInstanceCompleteTask:

有点长久分开截屏写了

flowable的多人会签和一票否决_第5张图片

箭头指向的地方就是一票否决,在监听器里边对reject进行了初始化,这里通过获取reject来判断它的值如果大于零就直接否决,

我这里为了能体现否决和同意,我一共设置了三个任务,第一个任务是会签,第二个任务和第三个任务一个是同意一个是否决对应的任务,他们是通过路由进行相关联的,路由判断outcome是"否决"还是"通过"然后路由到第二个任务或者第三个任务

他这个方法呢 如果是返回的true,那么就直接结束第一个会签任务,如果返回的是false那么会继续执行第一个会签任务

接下来继续:

flowable的多人会签和一票否决_第6张图片

这里有个小BUG  如果一票否决的人还没有执行,那么但凡执行了上边的那个通过,那这个任务就直接跳过去了,他就不能一票否决了,其实这里可以进行判断,如果这里一票否决的人没有执行就让它返回false。

然后继续来看ExpenseController类:

flowable的多人会签和一票否决_第7张图片

好的 接下来第一个方法,根据审批人的ID来获取任务的ID:

flowable的多人会签和一票否决_第8张图片

第二个方法,根据审批人的名字、任务的id、flg来进行执行任务

这里要注意了!!!!这里是flg不是flag

审批人的名字就不用说了,任务id就是第一个方法获取的任务的id,flg呢就是来判断是否同意的,n代表不同意,y代表同意

这里比较简单,代码上也有注释,就解释一下逻辑处理这一点好了:

flowable的多人会签和一票否决_第9张图片

很好,然后第三个方法!:

它就是来查看当前xml就是这个flowable的当前任务,专业术语我忘记怎么说了,emmm  当前实例?不行 不行 忘记了

执行它可以到执行到哪个任务了

flowable的多人会签和一票否决_第10张图片

好了 没了 就这样了 emmmm  这里写的是审批人是相当于直接塞进去的,也可以手动的塞进去,就是add的那个方法,在进行加载xml的时候,创建一个map,然后序列化一下,放到那个方法的第二个参数的位置就行了。

你可能感兴趣的:(flowable的多人会签和一票否决)