Flowable 处理一个流程的步骤如下:
<br/>
**1. 定义流程**
![](https://img.kancloud.cn/29/02/29024480e2c69b430a9d441e1767364b_1156x215.png)
**2. 部署流程**
```java
@Test
public void deploymentProcess() {
//获取ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//部署流程
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("bpmn/evectionProcess.bpmn") //部署资源
.name("出差申请流程") //部署名称
.deploy();
log.info("部署名:{}", deployment.getName()); //部署名:出差申请流程
log.info("部署id:{}", deployment.getId()); //部署id:1
}
```
完成上面的部署后相关数据保存到如下3张表中:
```sql
-- 流程部署表:每部署一次增加一条记录
mysql> select * from act_re_deployment;
+-----+--------------+-----------+------+------------+---------------------+---------------+--------------------+-----------------+
| ID_ | NAME_ | CATEGORY_ | KEY_ | TENANT_ID_ | DEPLOY_TIME_ | DERIVED_FROM_ | DERIVED_FROM_ROOT_ | ENGINE_VERSION_ |
+-----+--------------+-----------+------+------------+---------------------+---------------+--------------------+-----------------+
| 1 | 出差申请流程 | NULL | NULL | | 2021-10-28 17:09:50 | NULL | NULL | NULL |
+-----+--------------+-----------+------+------------+---------------------+---------------+--------------------+-----------------+
-- 流程定义表:部署每个新的流程就会在这张表中增加一条记录
-- 注意,KEY_ 这个字段是用来唯一识别不同流程的关键字
mysql> select * from act_re_procdef;
+---------------------+------+------------------------------+--------------+-----------------+----------+----------------+---------------------------+---------------------------------------...
| ID_ | REV_ | CATEGORY_ | NAME_ | KEY_ | VERSION_ | DEPLOYMENT_ID_ | RESOURCE_NAME_ | DGRM_RESOURCE_NAME_ | DESCRI...
+---------------------+------+------------------------------+--------------+-----------------+----------+----------------+---------------------------+---------------------------------------...
| evectionProcess:1:4 | 1 | http://www.activiti.org/test | 出差申请流程 | evectionProcess | 1 | 1 | bpmn/evectionProcess.bpmn | bpmn/evectionProcess.evectionProcess.png | ...
+---------------------+------+------------------------------+--------------+-----------------+----------+----------------+---------------------------+---------------------------------------...
-- 流程资源表
mysql> select id_, rev_, name_, deployment_id_, left(bytes_, 30) as bytes_, generated_ from act_ge_bytearray;
+-----+------+------------------------------------------+----------------+--------------------------------+------------+
| id_ | rev_ | name_ | deployment_id_ | bytes_ | generated_ |
+-----+------+------------------------------------------+----------------+--------------------------------+------------+
| 2 | 1 | bpmn/evectionProcess.bpmn | 1 | <?xml version="1.0" encoding=" | 0 |
| 3 | 1 | bpmn/evectionProcess.evectionProcess.png | 1 | Binary/Image | 1 |
+-----+------+------------------------------------------+----------------+--------------------------------+------------+
act_re_deployment和act_re_procdef一对多关系,一次部署在流程部署表生成一条记录,
但一次部署可以部署多个流程定义,每个流程定义在流程定义表生成一条记录。
每一个流程定义在act_ge_bytearray会存在两个资源记录,bpmn和png。
建议:一次部署一个流程,这样部署表和流程定义表是一对一有关系,方便读取流程部署及流程定义信息。
```
**3. 启动流程**
```java
@Test
public void runtimeProcess() {
//获取ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//根据流程key启动对应的流程,创建流程实例
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("evectionProcess");
//流程部署id:1
log.info("流程部署id:{}", processInstance.getDeploymentId());
//流程定义id:evectionProcess:1:4
log.info("流程定义id:{}", processInstance.getProcessDefinitionId());
//流程实例id:2501
log.info("流程实例id:{}", processInstance.getId());
}
```
完成上面的启动流程后相关数据保存到如下7张表中:
```sql
act_hi_actinst 流程实例执行历史信息
act_hi_identitylink 流程参与用户的历史信息
act_hi_procinst 流程实例的历史信息
act_hi_taskinst 流程任务的历史信息
act_ru_execution 流程执行信息
act_ru_identitylink 流程的正在参与用户信息
act_ru_task 流程当前任务信息
```
**4. 查询个人待办任务**
```java
@Test
public void queryTask() {
//获取ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取TaskService
TaskService taskService = processEngine.getTaskService();
//根据流程Key与负责人查询
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey("evectionProcess")
.taskAssignee("张三")
.list();
taskList.forEach(task -> {
log.info("任务id:{}", task.getId());
log.info("任务负责人:{}", task.getAssignee());
log.info("任务名称:{}", task.getName());
log.info("流程定义Id:{}", task.getProcessDefinitionId());
log.info("流程实例Id:{}", task.getProcessInstanceId());
log.info("任务节点Id:{}", task.getTaskDefinitionKey());
});
//任务id:2505
//任务负责人:张三
//任务名称:创建出差申请
//流程定义Id:evectionProcess:1:4
//流程实例Id:2501
//任务节点Id:_3
}
```
**5. 完成个人待办任务**
```java
@Test
public void completeTask() {
//获取ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取TaskService
TaskService taskService = processEngine.getTaskService();
//根据流程key与负责人查询待办任务
Task task = taskService.createTaskQuery()
.processDefinitionKey("evectionProcess")
.taskAssignee("张三")
.singleResult();
//根据任务id完成对应的任务
taskService.complete(task.getId());
log.info("任务负责人:{}", task.getAssignee()); //任务负责人:张三
log.info("任务Id:{}", task.getId()); //任务Id:2505
log.info("任务名称:{}", task.getName()); //任务名称:创建出差申请
log.info("流程实例Id:{}", task.getProcessInstanceId()); //流程实例Id:2501
log.info("流程定义Id:{}", task.getProcessDefinitionId()); //流程定义Id:evectionProcess:1:4
log.info("任务节点Id:{}", task.getTaskDefinitionKey()); //任务节点Id:_3
}
```
完成对应的任务后,该任务从表`act_ru_task`中删除,并在如下表中插入下一个任务的相关数据:
```sql
act_ru_task
act_hi_taskinst
act_hi_actinst
act_hi_identitylink
act_ru_identitylink
```
**6. 流程结束,后期的历史追踪与维护**
```java
@Test
public void queryHistory() {
//获取ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取HistoryService
HistoryService historyService = processEngine.getHistoryService();
List<HistoricActivityInstance> activities =
historyService.createHistoricActivityInstanceQuery()
.processInstanceId("2501") //根据流程实例id查询
.finished() //查询是已经完成的任务
.orderByHistoricActivityInstanceEndTime().asc()
.list();
activities.forEach(activity -> {
log.info("任务节点Id:{}", activity.getActivityId());
log.info("完成任务所花的时间:{}ms", activity.getDurationInMillis());
log.info("任务负责人:{}", activity.getAssignee());
log.info("流程定义Id:{}", activity.getProcessDefinitionId());
log.info("流程实例Id:{}", activity.getProcessInstanceId());
log.info("任务节点名称:{}", activity.getActivityName());
log.info("任务节点类型:{}", activity.getActivityType());
log.info("任务Id:{}\n", activity.getTaskId());
});
//任务节点Id:_2
//完成任务所花的时间:2ms
//任务负责人:null
//流程定义Id:evectionProcess:1:4
//流程实例Id:2501
//任务节点名称:StartEvent
//任务节点类型:startEvent
//任务Id:null
//任务节点Id:_3
//完成任务所花的时间:1044753ms
//任务负责人:张三
//流程定义Id:evectionProcess:1:4
//流程实例Id:2501
//任务节点名称:创建出差申请
//任务节点类型:userTask
//任务Id:2505
}
```
- Activiti流程引擎
- 工作流介绍
- Activiti是什么
- Activiti流程处理步骤
- Activiti环境搭建
- 搭建步骤
- 表结构介绍
- ActivitiAPI结构
- 认识流程符号
- 流程设计器的使用
- 流程处理步骤
- 乱码问题
- 流程实例
- 流程实例是什么
- 业务标识
- 查询流程实例
- 挂起/激活流程实例
- 个人任务
- 分配任务负责人
- 查询待办任务
- 办理权限
- 流程变量
- 流程变量类型
- 流程变量作用域
- 使用流程变量控制流程
- 组任务
- 设置任务候选人
- 组任务办理流程
- 网关
- 4种网关类型
- 排他网关
- 并行网关
- 包含网关
- 事件网关
- Spring整合Activiti
- SpringBoot整合Activiti
- Flowable流程引擎
- Flowable是什么
- Flowable与Activiti
- Flowable环境搭建
- FlowableAPI
- 流程引擎API与服务
- 流程处理步骤
- 流程部署
- 流程部署方式
- 流程定义版本
- 删除已部署的流程
- 下载资源
- 流程实例
- 什么是流程实例
- 业务标识
- 查询流程实例
- 挂起/激活流程实例
- 分配任务负责人
- 固定分配
- UEL表达式分配
- 监听器分配
- 办理权限
- 流程变量
- 流程变量类型
- 流程变量作用域
- 流程变量控制流程
- 组任务
- 设置任务候选人
- 组任务办理流程
- 网关
- 排他网关
- 并行网关
- 包含网关
- 事件网关
- 历史查询
- 查询历史
- Spring整合Flowable
- 配置文件整合
- 配置类整合
- SpringBoot整合Flowable