Activiti——基本操作

1 流程定义

  • 使用activiti流程建模工具(activity-designer)定义业务流程(.bpmn文件) 。

  • .bpmn文件就是业务流程定义文件,通过xml定义业务流程。

  • 使用idea插件设置流程图, 设置流程中需要的节点,节点负责人。具体步骤参考:

2 流程定义部署

  • activiti部署业务流程定义(.bpmn文件)。即:将流程图的内容存储到数据库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.pyr;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.junit.Test;

public class ActivitiDemo {

@Test
public void testDeployment(){
// 1. 创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 3. 使用service进行流程的部署,定义流程名字,把bpmn部署到数据库中
Deployment deploy = repositoryService.createDeployment()
.name("话费报销")
.addClasspathResource("bpmn/phoneExpense.bpmn20.xml")
.deploy();
// 4. 输出部署信息
System.out.println("流程部署id="+deploy.getId());
System.out.println("流程部署名字="+deploy.getName());
}
}

image-20230128210614102

流程定义部署后操作activiti的3张表如下:

  • act_re_deployment 流程定义部署表,每部署一次增加一条记录

  • act_re_procdef 流程定义表,部署每个新的流程定义都会在这张表中增加一条记录。比如章三的话费报销是一条记录,李四的话费报销是一条记录。

    image-20230128204451742 image-20230128204449359

  • act_ge_bytearray 流程资源表

    image-20230128204546011

3 启动流程实例

启动一个流程实例表示开始一次业务流程的运行。

在员工请假流程定义部署完成后,如果张三要请假就可以启动一个流程实例,如果李四要请假也启动一个流程实例,两个流程的执行互相不影响。

1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
public void testStartProcess(){
// 1. 创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
// 3. 根据流程ID启动流程
ProcessInstance instance = runtimeService.startProcessInstanceByKey("myProcess");
// 4. 输出
System.out.println("流程定义id="+instance.getProcessDefinitionId());
System.out.println("流程实例id="+instance.getId());
System.out.println("当前活动的id="+instance.getActivityId());
}

image-20230128210529180

操作activiti的表如下:

​ act_hi_actinst 流程实例执行历史

​ act_hi_identitylink 流程的参与用户历史信息

​ act_hi_procinst 流程实例历史信息

​ act_hi_taskinst 已经完成的任务信息

​ act_ru_execution 流程执行信息

​ act_ru_identitylink 流程的参与用户信息

​ act_ru_task 当前代办的任务信息

4 用户查询待办任务(Task)

  • 因为现在系统的业务流程已经交给activiti管理,通过activiti就可以查询当前流程执行到哪了,当前用户需要办理什么任务了,这些activiti帮我们管理了,而不需要开发人员自己编写在sql语句查询。

查询自己所能处理的任务

   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
public void testFindPersonalTasks(){
// 1. 创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取taskService
TaskService taskService = processEngine.getTaskService();
// 3. 根据流程key和任务负责人 查询任务
List<Task> tasks = taskService.createTaskQuery()
.processDefinitionKey("myProcess")
.taskAssignee("张三")
.list();
// 4. 输出
tasks.forEach(task -> {
System.out.println("流程实例id="+task.getProcessInstanceId());
System.out.println("任务id="+task.getId());
System.out.println("任务负责人="+task.getAssignee());
System.out.println("任务名称="+task.getName());
});
}

image-20230128210841640

5 用户处理任务

用户查询待办任务后,就可以办理某个任务,如果这个任务办理完成还需要其它用户办理,比如采购单创建后由部门经理审核,这个过程也是由activiti帮我们完成了。

1
2
3
4
5
6
7
8
9
@Test
public void testCompleteTask(){
// 1. 创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取taskService
TaskService taskService = processEngine.getTaskService();
// 3. 根据任务id完成任务
taskService.complete("2505");
}

操作activiti的表如下:

act_hi_taskinst: 已经完成的历史任务信息 -> 插入新数据; 更新完成任务的结束时间

image-20230128213152660

act_ru_task:当前代办的任务信息 -> 删除旧数据,插入新数据

image-20230128213015838

​ act_hi_identitylink: 流程的参与用户历史信息 -> 插入新数据

image-20230128213626199

更加灵活的完成个人任务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
public void testCompleteTask2(){
// 1. 创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 2. 获取taskService
TaskService taskService = processEngine.getTaskService();
// 3. 如果可以确定是一个任务,可以直接通过singleResult获得,依次修改taskAssignee为直线经理,部门经理,财务人员
Task task = taskService.createTaskQuery()
.processDefinitionKey("myProcess")
.taskAssignee("财务人员")
.singleResult();
// 3. 根据任务id完成任务
taskService.complete(task.getId());
System.out.println("DONE!");
}

此时查看act_ru_task表,已经没有数据了,因为任务执行完了

查看act_hi_actinst,可以看到END_TIME都已经填充上了

image-20230128231354324

6 流程结束

当任务办理完成没有下一个任务结点了,这个流程实例就完成了。

7. 流程历史信息的查看

即使流程定义已经删除了,流程执行的历史信息通过前面的分析,依然保存在activiti的act_hi_*相关的表中。所以我们还是可以查询流程执行的历史信息,可以通过HistoryService来查看相关的历史记录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    @Test
public void findHistoryInfo(){
// 获取引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取HistoryService
HistoryService historyService = processEngine.getHistoryService();
// 获取 actinst表的查询对象
HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
// 查询 actinst表,条件:根据 InstanceId 查询
// instanceQuery.processInstanceId("2501");
// 查询 actinst表,条件:根据 DefinitionId 查询
instanceQuery.processDefinitionId("process-variable:3:c8b43296-a886-11ed-90d9-9ec8af959357");
// 增加排序操作,orderByHistoricActivityInstanceStartTime 根据开始时间排序 asc 升序
instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
// 查询所有内容
List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
// 输出
for (HistoricActivityInstance hi : activityInstanceList) {
System.out.println(hi.getActivityId());
System.out.println(hi.getActivityName());
System.out.println(hi.getProcessDefinitionId());
System.out.println(hi.getProcessInstanceId());
System.out.println("<==========================>");
}
}

image-20230209233245014

8 实战使用

准备工作:

  1. 定义BPMN文件

  2. myActProcessDefinitionRegister注册entity对应的工作流信息:entityName, definitionKey,name

  3. EmActProcessStatus: entity上存储的taskDefinitionKey,可在这张表查询到对应的中文翻译

    • processRegisterId

    • taskDefinitionKey

    • name

  4. entity上冗余了工作流字段:

    • task1Assignee,taskAssignee2: 任务受理人,根据bpmn文件定义的task数量定义,每个task对应一个受理人

    • currentTaskDefinitionKey: 当前记录的流程状态,即task的标识

流程:

  1. 新增entity,afterSaveTrigger发送mq启动流程实例
    • definitionKey: 根据entityName查询emActProcessDefinitionRegister
    • businessKey: entityId
    • variables: entity复写自己的
  2. 查看认领任务:根据前端传过来的loginName, processDefinitionKeyList查看任务列表
  3. 候选人认领任务(如果有callBack,调用callback): taskService.claim(task.getId(), claimTaskForm.getUserLoginName());
  4. 查看待办任务:根据前端传过来的loginName, processDefinitionKeyList查看任务列表
  5. 完成任务:completeTask
  6. 执行完成任务回调completeFeedback, 比如:当前流程的填充审批完成时间

Activiti——基本操作
http://example.com/activiti基本操作/
作者
Panyurou
发布于
2023年1月28日
许可协议