flowable的多人会签和一票否决
阅读原文时间:2023年07月09日阅读: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<String> DoTask(String name){  
   // List<Task> tasks = taskService.createTaskQuery().taskCandidateUser(name).list();  
    List<Task> tasks = taskService.createTaskQuery().taskAssignee(name).list();  
    List<String> 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<Task> list = taskService.createTaskQuery().taskAssignee(name).list();  
    List<String> 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<String,Object> map = new HashMap<>();  
            Integer reject = (int)taskService.getVariable(taskId1,"reject");  
            map.put("reject",reject+1);  
            taskService.complete(taskId,map);  
        }else {  
            Map<String,Object> 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<String,Object> map = new HashMap<>();  
       Integer agreePeson = (int)taskService.getVariable(taskId1,"agreePeson");  
       map.put("agreePeson",agreePeson+1);  
       taskService.complete(taskId,map);  
   }

    List<Task> list1 = taskService.createTaskQuery().taskAssignee(name).list();  
    List<String> 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<String> SelectTask(){  
    List<Task> list = taskService.createTaskQuery().list();  
    List<String> 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:

然后xml文件:

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

然后就是监听器CountersignListener:

然后就是执行器的配置内容了MultiInstanceCompleteTask:

有点长久分开截屏写了

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

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

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

接下来继续:

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

然后继续来看ExpenseController类:

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

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

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

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

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

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

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

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

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

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章