Activiti7的基础使用
1. 一些操作
1.1 查询流程定义
processDefinitionKey(Key)
/**
* 查询流程定义
*/
@Test
public void queryProcessDefinition() {
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//获取 ProcessDefinitionQuery 对象
ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
//查询当前所有的流程定义(根据 Key 来查询),返回流程定义信息的集合
List<ProcessDefinition> definitionList = definitionQuery.processDefinitionKey("Test2").orderByProcessDefinitionVersion() //根据表 act_re_procdef 的 VERSION 字段进行排序
.desc() //倒序
.list();
//输出信息
for (ProcessDefinition processDefinition : definitionList) {
System.out.println("流程定义ID=" + processDefinition.getId());
System.out.println("流程定义名称=" + processDefinition.getName());
System.out.println("流程定义Key=" + processDefinition.getKey());
System.out.println("流程定义版本=" + processDefinition.getVersion());
System.out.println("流程部署ID=" + processDefinition.getDeploymentId());
}
}
/*
流程定义ID=Test2:1:2506
流程定义名称=Test2
流程定义Key=Test2
流程定义版本=1
流程部署ID=2501
*/
1.2 删除流程部署信息
deleteDeployment(deploymentId)
/**
* 删除流程部署信息
*/
@Test
public void deleteDeployMent() {
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//通过部署id来删除流程部署信息,表 act_re_procdef
String deploymentId = "1";
//不加第二个参数默认false,说明此流程如果有实例则不删除。如果为true,则无视已经创建出来的实例直接删除。
repositoryService.deleteDeployment(deploymentId, true);
}
1.3 下载资源文件
getResourceAsStream(deploymentId,Name)
/**
* 下载资源文件
*
* @方案1:使用Activiti提供的api来下载资源文件
* @方案2:自己写代码从数据库中下载文件,使用jdbc对blob类型,clob类型读取出来,保存到文件目录解决io操作解决io操作commons-io.jar
* @一般使用方案1
*/
@Test
public void getDeployment() throws IOException {
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取api,RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//获取查询对象 ProcessDefinitionQuery,查询流程定义信息
ProcessDefinition test2 = repositoryService.createProcessDefinitionQuery().processDefinitionKey("Test2") //流程定义的Key,来自表 act_re_procdef
.singleResult(); //返回单一结果
String deploymentId = test2.getDeploymentId(); //通过流程定义信息,获取部署ID
String pngName = test2.getDiagramResourceName(); //获取png图片名称
String bpmnName = test2.getResourceName(); //获取bpmn名称
//通过 RepositoryService ,传递部署ID参数,读取资源信息(png 和 bpmn)
InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, pngName);
InputStream bpmnNameInput = repositoryService.getResourceAsStream(deploymentId, bpmnName);
//将资源文件写到文件目录
FileOutputStream pngFileStream = null;
FileOutputStream bpmnFileStream = null;
try {
pngFileStream = new FileOutputStream("D:\\Test\\java\\Test1\\activiti7\\src\\main\\resources\\临时\\Test2.png");
bpmnFileStream = new FileOutputStream("D:\\Test\\java\\Test1\\activiti7\\src\\main\\resources\\临时\\Test2.bpmn20.xml");
} finally {
IOUtils.copy(pngInput, pngFileStream);
IOUtils.copy(bpmnNameInput, bpmnFileStream);
}
}
1.4 查询历史信息
getHistoryService()
获取历史服务
createHistoricActivityInstanceQuery()
创建历史活动实例查询
processInstanceId()
需要查询的实例id
processDefinitionId()
需要查询的流程模板id
/**
* 查询历史信息
*/
@Test
public void findHistoryInfo() {
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取 HistoryService
HistoryService historyService = processEngine.getHistoryService();
//获取表 act_hi_actinst 查询对象
HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
//两种查询字段,二选一也可都选
//查询表 act_hi_actinst,参数为 PROC_INST_ID 字段
instanceQuery.processInstanceId("5001");
//查询表 act_hi_actinst,参数为 PROC_DEF_ID_ 字段
// instanceQuery.processDefinitionId("Test2:1:2506");
//添加排序 根据StartTime的升序来排(可以选择根据其他字段来排序)
instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
//查询所有内容
List<HistoricActivityInstance> historyList = instanceQuery.list();
//输出
for (HistoricActivityInstance historicInfo : historyList) {
System.out.println("ID=" + historicInfo.getActivityId());
System.out.println("Name=" + historicInfo.getActivityName());
System.out.println("DefinitionId=" + historicInfo.getProcessDefinitionId());
System.out.println("InstanceId=" + historicInfo.getProcessInstanceId());
System.out.println("***********************************************");
}
}
/*
ID=sid-0b703557-b739-4789-a805-0b60f5a5b0cf
Name=这个是Test2启动节点
DefinitionId=Test2:1:2506
InstanceId=5001
***********************************************
ID=sid-099df3f1-57a9-4c0b-9bfa-8bc2f06e62dc
Name=这个是Test2的第一个节点
DefinitionId=Test2:1:2506
InstanceId=5001
***********************************************
ID=sid-59e49190-9d28-4d25-8791-ad8af332645b
Name=这个是Test2的第二个节点
DefinitionId=Test2:1:2506
InstanceId=5001
***********************************************
*/
1.5 挂起与激活
ps:
获取流程模板的操作是 getRepositoryService() 获取存储库服务
获取流程实例的操作是 getRuntimeService() 获取运行时服务
1.5.1 全部流程实例的 挂起 和 激活
getRepositoryService
获取存储库服务
createProcessDefinitionQuery()
创建流程定义查询
isSuspended()
获取当前流程定义的实例是否都是挂起状态
activateProcessDefinitionById()
按 ID 激活流程定义。参数1: 流程定义id 参数2:是否激活 参数3:激活时间
suspendProcessDefinitionById()
按 ID 挂起进程定义。 参数1:流程定义id 参数2:是否暂停 参数3:暂停时间
/**
* 全部流程实例的 挂起 和 激活
* suspend 暂停
*/
@Test
public void suspendAllProcessInstance() {
//1.获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.查询流程定义,获取流程定义查询对象
ProcessDefinition evenction = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("evenction") //流程模板的Key值
.singleResult();
//4.获取当前流程定义的实例是否都是挂起状态
boolean suspended = evenction.isSuspended();
//5.获取流程定义id
String id = evenction.getId();
//6.如果是挂起则激活 影响表 act_ru_task,act_re_procdef,act_ru_execution 的 SUSPENSION_STATE 字段 -> 1-激活 2-挂起
// (参数1:流程定义id 参数2:是否激活 参数3:激活时间)
if (suspended) {
repositoryService.activateProcessDefinitionById(id, true, null);
System.out.println("流程定义id:" + id + ",已激活");
} else {
//7.如果是激活则挂起 (参数1:流程定义id 参数2:是否暂停 参数3:暂停时间)
repositoryService.suspendProcessDefinitionById(id, true, null);
System.out.println("流程定义id:" + id + ",已暂停");
}
}
如果挂起成功,act_re_procdef表的SUSPENSION_STATE_ 字段就会为2.现在为1说明是激活状态
1.5.2 单个流程实例的 挂起 和 激活
getRuntimeService()
获取运行时服务
createProcessDefinitionQuery()
创建流程定义查询
isSuspended()
获取当前流程实例是否都是挂起状态
activateProcessInstanceById()
按 ID 激活流程实例
suspendProcessInstanceById()
按 ID 挂起进程实例
/**
* 挂起 - 激活 单个流程实例
*/
@Test
public void suspendSingleProcessInstance() {
//1.获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.通过 RuntimeService 获取流程实例id
ProcessInstance instance = runtimeService.createProcessInstanceQuery()
.processInstanceId("10001")
.singleResult();
String id = instance.getId();
//4.得到实例的暂停状态
boolean suspended = instance.isSuspended();
//5.如果是挂起则激活 1-激活 2-挂起
if (suspended) {
runtimeService.activateProcessInstanceById(id);
System.out.println("流程实例id:" + id + ",已激活");
} else {
//7.如果是激活则挂起 (参数1:流程定义id)
runtimeService.suspendProcessInstanceById(id);
System.out.println("流程实例id:" + id + ",已暂停");
}
}
如果挂起成功,act_ru_task表的SUSPENSION_STATE_ 字段就会为2.现在为2说明是挂起状态,挂起状态不能执行下一步,测试如下
/**
* 完成个人任务
*/
@Test
public void completTask() {
//获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取操作任务的服务 TaskService
TaskService taskService = processEngine.getTaskService();
//使用 taskService 获取任务
Task task = taskService.createTaskQuery()
.processInstanceId("10001") //参数为流程实例ID,表act_ru_task 的 PROC_INST_ID 字段可获取
.taskAssignee("zhangsan")
.singleResult();
System.out.println("流程实例id:" + task.getProcessInstanceId());
System.out.println("流程任务id:" + task.getId());
System.out.println("流程负责人名字:" + task.getAssignee());
System.out.println("任务名称:" + task.getName());
//根据任务id完成任务
taskService.complete(task.getId());
}
报错:org.activiti.engine.ActivitiException: Cannot complete a suspended task。
无法完成暂停任务
2. 动态设置
2.1 动态设置负责人 Assignee
2.1.1 使用uel表达式读取参数
1. bpmn流程图中 Assignee 原本是写死的,现在使用uel表达式 改为 ${assignee}
其他几项同理
2. 使用uel表达式动态的部署设置属性
/**
* 使用uel表达式动态的部署设置属性
*/
@Test
public void testDeploymentUEL() {
//1.获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.使用 service 进行流程部署,定义一个流程名字,把bpmn和png部署到数据中
Deployment deploy = repositoryService.createDeployment()
.name("出差申请-UEL")
.addClasspathResource("bpmn/evection.bpmn20.xml")
.deploy();
System.out.println("流程部署id" + deploy.getId());
System.out.println("流程部署名称" + deploy.getName());
}
3. 使用uel表达式设置属性并启动流程实例
/**
* 使用uel表达式设置属性并启动流程实例
*/
@Test
public void testStartUEL() {
//1.获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取 RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.启动流程实例 startProcessInstanceByKey 根据key值(key,map)
//3.1 设置map,里面是uel表达式的值 表--act-hi-varinst
HashMap<String, Object> map = new HashMap<>();
map.put("assignee0","张三");
map.put("assignee1","李四");
map.put("assignee2","王五");
map.put("assignee3","钱六");
ProcessInstance instance = runtimeService.startProcessInstanceByKey("evenction",map);
}
效果如下 表 act-hi-varinst
2.1.2 使用监听器设置
注: Activiti BPMN visualizer 这个插件不支持设置监听器,所以需要手动改下xml文件
1. 创建出来的与之前一样,文件名:listener.bpmn20.xml
2.listener.bpmn20.xml
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
<process id="listener" name="监听测试" isExecutable="true">
<startEvent id="testListener" name="监听测试"/>
<userTask id="_1" name="创建出差申请">
<!--重点-->
<extensionElements>
<activiti:taskListener class="com.uuz.demo.listener.MyTaskListener" event="all"/>
</extensionElements>
</userTask>
<userTask id="_2" name="经理审批"/>
<userTask id="_3" name="总经理审批"/>
<userTask id="_4" name="财务审批"/>
<endEvent id="end" name="EndEvent"/>
<sequenceFlow id="sid-de4ef1ba-6d8e-4d2f-a6b7-a01c0ccc4da6" sourceRef="testListener" targetRef="_1"/>
<sequenceFlow id="sid-bac901bb-8972-4fe0-872a-a4a0dc6f77e7" sourceRef="_1" targetRef="_2"/>
<sequenceFlow id="sid-ba2657da-d2d4-42b9-a59c-466af06a5134" sourceRef="_2" targetRef="_3"/>
<sequenceFlow id="sid-4c8abe35-997d-4949-9afa-2f67a9ffb1fc" sourceRef="_3" targetRef="_4"/>
<sequenceFlow id="sid-e95a6a72-f61e-4717-8ebe-adec24cf3017" sourceRef="_4" targetRef="end"/>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_evenction">
<bpmndi:BPMNPlane bpmnElement="listener" id="BPMNPlane_evenction">
<bpmndi:BPMNShape id="shape-c6c977d4-e101-439d-8da9-bfcd391c9b9f" bpmnElement="testListener">
<omgdc:Bounds x="-2005.0" y="-1555.0" width="30.0" height="30.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-4e729324-2457-491a-b162-b85e01069462" bpmnElement="_1">
<omgdc:Bounds x="-2040.0" y="-1510.0" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-843d0f2e-3568-4248-8220-b88fe6dad1db" bpmnElement="_2">
<omgdc:Bounds x="-2040.0001" y="-1395.0" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-57b666ba-9d46-40d7-ba93-94596a3c263b" bpmnElement="_3">
<omgdc:Bounds x="-2040.0001" y="-1285.0" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-2b900cc4-00d8-4151-aee5-6b475095dc03" bpmnElement="_4">
<omgdc:Bounds x="-2040.0" y="-1175.0" width="100.0" height="80.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="shape-5c08b723-fd52-4b05-8cc4-a81e12801eef" bpmnElement="end">
<omgdc:Bounds x="-2005.0" y="-1060.0" width="30.0" height="30.0"/>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="edge-fdaa9e79-e739-4ac4-bdea-5d830915b8a5" bpmnElement="sid-de4ef1ba-6d8e-4d2f-a6b7-a01c0ccc4da6">
<omgdi:waypoint x="-1990.0" y="-1525.0"/>
<omgdi:waypoint x="-1990.0" y="-1510.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge-8d829762-92b6-4d1d-b5ee-d371f9a4510e" bpmnElement="sid-bac901bb-8972-4fe0-872a-a4a0dc6f77e7">
<omgdi:waypoint x="-1990.0" y="-1430.0"/>
<omgdi:waypoint x="-1990.0001" y="-1395.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge-f5916ac5-38a1-4d0d-8cbf-9e16255d2620" bpmnElement="sid-ba2657da-d2d4-42b9-a59c-466af06a5134">
<omgdi:waypoint x="-1990.0001" y="-1315.0"/>
<omgdi:waypoint x="-1990.0001" y="-1285.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge-2282edfd-1500-494d-9ded-844329633cb1" bpmnElement="sid-4c8abe35-997d-4949-9afa-2f67a9ffb1fc">
<omgdi:waypoint x="-1990.0001" y="-1205.0"/>
<omgdi:waypoint x="-1990.0" y="-1175.0"/>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="edge-238c8248-f347-4ec0-a8d1-3036b45a637c" bpmnElement="sid-e95a6a72-f61e-4717-8ebe-adec24cf3017">
<omgdi:waypoint x="-1990.0" y="-1095.0"/>
<omgdi:waypoint x="-1990.0" y="-1060.0"/>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
手动新增的在前10行的,class是监听的类,event是监听的事件
event属性:
- Create:任务创建后触发
- Assignment:任务分配后触发
- Delete:任务完成后触发
- All:所有事件发生都触发
<extensionElements>
<activiti:taskListener class="com.uuz.demo.listener.MyTaskListener" event="all"/>
</extensionElements>
3. class监听类,实现 TaskListener 接口重写 notify方法
public class MyTaskListener implements TaskListener {
/**
* 指定负责人
* @param delegateTask 委托任务
*/
@Override
public void notify(DelegateTask delegateTask) {
//判断当前任务是 创建申请 且 事件是 create 事件
if (delegateTask.getName().equals("创建出差申请") && delegateTask.getEventName().equals("create")) {
delegateTask.setAssignee("addd");
}
}
}
3. 启动流程实例
@Test
public void startDemoListener() {
//1.获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取RepositoryService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.启动流程实例
ProcessInstance evenction = runtimeService.startProcessInstanceByKey("listener");
}
4. 结果如下 表 act_ru_task
3. 分支流程路径
1. 创建如图所示的bpmn图 evection-global.bpmn20.xml
使用网关更加合适
assignee1 -< 创建出差申请
assignee2 -< 部门经理
assignee3 -< 总经理
assignee4 -< 财务
2. 设置分支选择条件
双击选中需要判断的线,设置Condition expression 属性 同样是uel表达式。(evection是下面所创建的一个类)
3. 创建一个实体类 evection ,类中的属性通过启动流程实例的时候可以传入
//Serializable 实现序列化接口
public class Evection implements Serializable {
//省略getset方法
//主键ID
private Long id;
//出差实例的名字
private String evectionName;
//出差天数
private Double num;
//开始时间
private Date beginDate;
//结束时间
private Date endDate;
//目的地
private String destination;
//出差原因
private String reson;
4.
- 4.1 部署略
- 4.2 启动流程实例
/**
* 启动流程实例
*/
@Test
public void testStartProcess() {
//1.创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取runTimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.定义流程变量 上文提到的实体类
Evection evection = new Evection();
HashMap<String, Object> variables = new HashMap<>();
//3.1 设置出差天数 5天
evection.setNum(5d);
//3.2 设定任务负责人
variables.put("evection", evection);
variables.put("assignee1", "普通员工");
variables.put("assignee2", "经理");
variables.put("assignee3", "总经理");
variables.put("assignee4", "财务");
//4.根据流程定义key和参数启动实例 表 act_ru_variable 可以看到一个类型为serializable
ProcessInstance instance = runtimeService.startProcessInstanceByKey("evection-global", variables);
//4.输出内容
System.out.println("流程定义ID=" + instance.getProcessDefinitionId());
System.out.println("流程实列ID=" + instance.getId());
System.out.println("当前活动的ID=" + instance.getActivityId());
}
- 4.3 完成个人任务
注意:
.processInstanceId(ID) 这个ID是任务实例从出生到死亡不会变的ID
task.getId() 这个ID虽然也能查询到,但只是限于当前任务,当前任务执行下一步后每次都会改变此ID值
/**
* 完成个人任务
*/
@Test
public void completTask() {
//1.创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取TaskService
TaskService taskService = processEngine.getTaskService();
//3. 查询任务,表 act_ru_task
Task task = taskService.createTaskQuery()
.processDefinitionKey("evection-global") //流程定义key
.taskAssignee("财务") //Assignee
.processInstanceId("17502") //实例id,如果是多个实例满足前两个条件则需要此处判断
.singleResult();
if (task != null) {
//4.根据任务 ID 来完成任务 查看表 act_ru_task 的Assignee字段
taskService.complete(task.getId());
}
}
- 4.4 结果
多次执行完成个人任务后到达了总经理审批
4. 设置变量
4.1 创建流程时设置变量
如前文中启动流程时设置天数
//3.定义流程变量
Evection evection = new Evection();
HashMap<String, Object> variables = new HashMap<>();
//3.1 设置出差天数
evection.setNum(5d);
//3.2 设定任务负责人
variables.put("evection", evection);
variables.put("assignee1", "普通员工");
variables.put("assignee2", "经理");
variables.put("assignee3", "总经理");
variables.put("assignee4", "财务");
//4.根据流程定义key和参数启动实例 表 act_ru_variable 可以看到一个类型为serializable
ProcessInstance instance = runtimeService.startProcessInstanceByKey("evection-global", variables);
4.2 任务处理中设置变量
还是拿上面那一部分,只不过这次taskService.complete() 多传了一个参数。
如这里,本来启动流程时是5天,在这里修改为了两天,后续就不会在走总经理审批路线
taskService.complete
@Test
public void completTask() {
//1.创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取TaskService
TaskService taskService = processEngine.getTaskService();
//3. 查询任务
Task task = taskService.createTaskQuery()
.processDefinitionKey("evection-global") //流程定义key
.processInstanceId("17502") //实例id,如果是多个实例满足前两个条件则需要此处判断
.singleResult();
Evection evection = new Evection();
evection.setNum(2d);
// taskService.setVariableLocal("35002","evection",evection);
HashMap<String, Object> map = new HashMap<>();
map.put("evection",evection);
System.out.println(task);
if (task != null) {
//4.根据任务 ID 来完成任务 查看表 act_ru_task 的Assignee字段
taskService.complete(task.getId(),map);
}
}
4.2.1 任务处理中设置变量的多种方式
1. 全局变量
runtimeService.setVariable()
runtimeService.setVariables()
本地变量
runtimeService.setVariableLocal()
runtimeService.setVariablesLocal()
//1.创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取runTimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.创建 Evection 对象
Evection evection = new Evection();
evection.setNum(2d);
//4.通过实例id来设置属性值
runtimeService.setVariable(ID, "evection", evection)
//runtimeService.setVariables(ID, map)通过传入map可以一次修改多个变量
2. 当前任务设置
taskService.setVariable()
taskService.setVariables()
本地变量
taskService.setVariableLocal()
taskService.setVariablesLocal()
//1.创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取TaskService
TaskService taskService = processEngine.getTaskService();
//3.创建 Evection 对象
Evection evection = new Evection();
evection.setNum(2d);
//通过任务设置流程变量
taskService.setVariable(taskId, "evection", evection)
//taskService.setVariables(ID, map)通过传入map可以一次修改多个变量
3. complete
taskService.complete(task.getId(),map);
5. 组任务
- 创建如图流程图,注意 Assignee 为空,CandidateUsers用逗号隔开多个
实质是 activiti:candidateUsers=“a,b”
<userTask id="sid-e81d100e-8c42-43bd-acce-aaf72c6c75ac" name="222" activiti:candidateUsers="a,b"/>
略部署
略创建实列
略111
2. 查询组任务 与 拾取,归还任务
核心:
1. 查询.taskCandidateUser(候选人字段)
2. 拾取taskService.claim(TaskId, 候选人字段);
3. 归还taskService.setAssignee(TaskId, null);
null 也可以直接将其赋值为其他候选人字段
当前taskId是17502,可以看到 Assignee 字段为 null,说明没有人处理(没有人处理是指此处没有绑定负责人字段,并不是不可执行,直接调用 complete() 方法依然可以进入到结束流程)
/**
* 查询组任务
*/
@Test
public void findGroupTaskList() {
//1.创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取TaskService
TaskService taskService = processEngine.getTaskService();
//3.查询组任务
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey("candidate-users") //流程定义key
.taskCandidateUser("a") //根据候选人查询任务(指此处CandidateUsers绑定了a这个字段,也能传list集合)
// .taskId("5012")
.list();
System.out.println(taskList);
}
/**
* 候选人拾取任务
*/
@Test
public void claimTask() {
//1.创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取TaskService
TaskService taskService = processEngine.getTaskService();
//3.查询任务
Task task = taskService.createTaskQuery()
.taskId("17502") //task本段id
.taskCandidateUser("a") //可以选择的候选人
.singleResult();
if (task != null) {
//4.拾取任务
taskService.claim("17502", "b");
System.out.println("拾取任务完成");
}
}
/**
* 候选人归还任务
*/
@Test
public void AssigneeToGroupTask() {
//1.创建 processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取TaskService
TaskService taskService = processEngine.getTaskService();
//3.查询任务
Task task = taskService.createTaskQuery()
.taskId("17502") //task本段id
.taskAssignee("b") //根据现在的负责人查询
.singleResult();
if (task != null) {
//4.归还任务(将任务负责人设置为null就清除了候选人,当然也可以直接设置其他候选人)
taskService.setAssignee("17502", null);
System.out.println("拾取任务完成");
}
}
6. 网关Gateway
6.1 网关的四种类型
当事件需要多选一的时候可以使用排他网关(如果都符合则选择xml中id小的那条,都不符合抛出异常)类似前文的单独在线路上设置的判断,只不过这里加了网关,好处是都不符合会抛出异常,而没有网关则会直接终止事件
设置的方法
传参(此处判断num值,这里传的是2,说明走下面一条路)
HashMap<String, Object> variables = new HashMap<>();
variables.put("num", "2");
runtimeService.startProcessInstanceByKey("ExclusiveGateway", variables);
当事件需要满足多个条件时使用并行网关,并行网关的特点是会无视连线上设置的条件,他会将流程分发给下一步所有的处理,并且末尾会有一个集束的并行网关来收集。
当执行到网关后,表 act_ru_task 会创建多个相同的 PROC_INTS_ID(实例) 字段,这个时候就不能在单独用 processInstanceId(ID) 来查询了因为会返回多个,而是使用.taskId(id) 来具体查询流程步骤。
在满足一个条件后,会删除此步骤等待并行的另一个步骤完成后,到达总经理阶段
等待两条并行线步骤
类似于排他+并行网关,可以有判断条件,也需要汇集,等待并行的其他条件
num>3 由项目经理处理,<3由技术经理处理,但无论怎么样都要有人事经理处理(若等于3则只通过人事经理)不设置会报错