https://www.zybuluo.com/ruoli/note/479483
https://www.iteye.com/blog/huan1993-2249764
https://cloud.tencent.com/developer/article/1187876
1、会签说明
会签,是指多个人员针对同一个事务进行协商处理,共同签署决定一件事情。
在工作流中会签,是指多个人员在同一个环节进行处理,同一环节的有多个处理人并行处理,按照配置规则,固定比例的人员办理完成后即可继续扭转至下一环节。
2、Activiti会签实现
目前Activiti支持自定义配置完成比例,即 一定比例的人员 办理完成之后 即可扭转至下一步,这样就可以实现 多人处理一人审批即可通过和全部人员审批后才可通过,两种处理形式,配置方式如下:
<userTask id="sid-1D9A88B5-D0DC-4056-A5DF-179D7220B76F"
name="生产部领导会签"
activiti:assignee="${assignee}"
>
<multiInstanceLoopCharacteristics isSequential="false"
activiti:collection="${assignees}" activiti:elementVariable="assignee">
<completionCondition>
${nrOfCompletedInstances/nrOfInstances>0}
</completionCondition>
</multiInstanceLoopCharacteristics>
</userTask>
以下是我配置:
<userTask id="usertask1" name="User Task" activiti:assignee="${username}">
<multiInstanceLoopCharacteristics isSequential="false" activiti:collection="${usernamelist}" activiti:elementVariable="username">
<completionCondition>${taskChianExpress.conditionResult(a1)}</completionCondition>
</multiInstanceLoopCharacteristics>
</userTask>
说明:
1:此配置依赖外部传入流程参数 assignees,类型为 List<String>
,此为所有参与审批的人员集合。
2:activiti:elementVariable="assignee" 为内部处理参数,工作流引擎循环遍历处理这些人员时使用assignee变量来存储每一个人员信息
3:activiti:assignee="${assignee}
",执行审批人,此变量不需外部传入,对应上述第二点的内部变量。
4:${nrOfCompletedInstances/nrOfInstances>0} ,配置完成比例,此处配置为>0,代表任意一人处理后即可扭转。
5:isSequential="false" ,代表并行处理。
截图:
${nrOfCompletedInstances/nrOfInstances>0} 的含义:
nrOfInstances 实例总数
nrOfActiveInstances 当前还没有完成的实例
nrOfCompletedInstances 已经完成的实例个数
completion condition 还可以自定义函数方式。入我截图上
代码实例:
a1=12 时候,会签结束。通过函数方法控制会签结束。如果completion condition 不配置,默认是全部会签后才往下面走。
也可以指定会签人数比例 :${nrOfCompletedInstances/nrOfInstances>0} 。只要一人会签就结束
package com.zte.activi.controller;
import com.zte.activi.express.ITaskChinaExpress;
import com.zte.activi.express.impl.CondintionExpress;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author zcy
* @version 2019/9/24
* Created by zcy on 2019/9/24.
*/
@RestController
@RequestMapping("/huiqian")
@Api("huiqian")
public class HuiQianController {
@Autowired
private RepositoryService repositoryService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Autowired
private HistoryService historyService;
@Autowired
private ITaskChinaExpress iTaskChinaExpress;
private static String processDefindKey= "myFiveProcess";
@ApiOperation("启动实例")
@GetMapping("startProcess")
public void startProcess(){
System.out.println("启动实例");
Map paramMap = new HashMap<>();
//初始化会签人员s
List<String> usernamelist = new ArrayList<>();
usernamelist.add("王小宝");
usernamelist.add("王二宝");
usernamelist.add("王三宝");
//条件表达式方法 一定要序列号
CondintionExpress condintionExpress = new CondintionExpress();
paramMap.put("usernamelist", usernamelist);
paramMap.put("taskChianExpress",condintionExpress);
//条件里面变量a1
paramMap.put("a1","123");
runtimeService.startProcessInstanceByKey(processDefindKey,paramMap);
}
@ApiOperation("完成任务")
@GetMapping("submitTaskProcess")
public void submitTaskProcess(){
System.out.println("完成任务");
String taskId = "82527";
//设置变量a1
taskService.setVariable(taskId,"a1","12");
taskService.complete(taskId);
}
@ApiOperation("查询任务")
@GetMapping("queryTask")
public void queryTask(){
System.out.println("查询任务");
List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefindKey).list();
for (Task task : taskList){
System.out.println("taskId:"+task.getId()+" execId:"+task.getExecutionId()+" 流程实例id:"+task.getProcessInstanceId()+" 任务key:"+task.getTaskDefinitionKey()+" assign:"+task.getAssignee());
}
}
}
public class CondintionExpress implements Serializable{
private static final long serialVersionUID = -2817132794066235704L;
public boolean conditionResult(String a1) {
System.out.println("=======a1:"+a1);
if(a1.equals("12")){
return true;
}
return false;
}
}