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;
}
}