Activity5详解

一、画流程图

我们以请假流程为例,画一个简单的流程图

新建文件

右键新建BPMN文件,命名为Myprocess,打开文件出现如下界面:

imageba4904a90108bde5.png

点击空白处,然后在右边可看到ID选项,为流程图设置一个唯一的ID,如果ID重复,部署的时候就会认为是一个流程的新版本。

加入元素

需要用到如下几个组件:

image44a855f4fee3d0fc.png

完成后的结果:

image84bbedbe28172a78.png

二、流程部署

把我们画好的流程信息保存到数据库中

:::tip 提示

bpmn文件存放到processes文件夹下,会自动部署.

:::

部署指定的文件

Deployment deploy = 
repositoryService.createDeployment().addClasspathResource("MyProcess.bpmn").deploy();  

部署后表数据分析

1.act_ge_bytearray表

二进制数据表,存储了流程定义图形的XML文件和图片信息

保存流程定义的xml信息

保存流程定义的图片

2.act_re_deployment

部署信息表,存储了部署的相关信息(部署时间)

3.act_re_procdef

流程定义数据表,存储了当前流程图形的相关信息(id,name,版本号)

解决乱码问题

import org.activiti.spring.SpringProcessEngineConfiguration;
import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class ActivitiConfig implements ProcessEngineConfigurationConfigurer{
@Override
    public void configure(SpringProcessEngineConfiguration processEngineConfiguration) {
        processEngineConfiguration.setActivityFontName("宋体");
        processEngineConfiguration.setLabelFontName("宋体");
    } 
}

三、查询流程定义数据

对应表:act_re_procdef

ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
//查询流程
List<ProcessDefinition> list = query.list();
for (ProcessDefinition pd : list) {
    System.out.println("name:"+pd.getName()+"\nid:"+pd.getId());
}

//查询流程定义数量
System.out.println("流程定义数量:"+query.count());

//最后一次部署的流程定义对象
ProcessDefinition singleResult = query.latestVersion().singleResult();
System.out.println("最后一次部署的流程定义对象"+singleResult);

//根据版本号进行倒序排序
ProcessDefinitionQuery processDefinitionQuery = query.orderByProcessDefinitionVersion().desc();
List<ProcessDefinition> list2 = processDefinitionQuery.list();
for (ProcessDefinition pd : list2) {
    System.out.println("name:"+pd.getName()+"\nid:"+pd.getId());
}

四、运行流程实例

//查询流程实例
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey("myProcess_1")
        .latestVersion()
        .singleResult();
//System.out.println(myProcess);

//运行流程实例
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());
System.out.println(processInstance);

发生变化的表

act_hi_procinst : 历史流程实例表 保存了流程实例的信息
act_hi_taskinst: 历史任务实例表 保存了流程任务的相关信息
act_hi_actinst:历史节点表 保存了流程执行的节点顺序
act_ru_execution : 运行时流程执行实例表 保存了当前流程执行的节点数据,流程开始会自动完成,直接执行第一个任务

act_ru_task : 运行时任务节点表 保存当前流程执行的任务数据

完成请假流程

画流程图 并添加委托人,委托人的作用就是来完成这个任务。

image.png

部署新的工作流程,启动流程实例,观察表数据

查看act_ru_identitylink表:增加了委托人的信息

image369a4b694fd28d61.png

查询任务:

TaskQuery taskQuery = taskService.createTaskQuery();
//获取zhangsan的任务列表
List<Task> taskList = taskQuery.taskAssignee("zhangsan").list();
for (Task task : taskList) {
    System.out.println(task.getId()+":"+task.getName());
}

完成任务:

TaskQuery taskQuery = taskService.createTaskQuery();
//获取zhangsan的任务列表
List<Task> taskList = taskQuery.taskAssignee("zhangsan").list();
for (Task task : taskList) {
    System.out.println(task.getId()+":"+task.getName());
    taskService.complete(task.getId());
}
TaskQuery taskQuery = taskService.createTaskQuery();
//获取zhangsan的任务列表
List<Task> taskList = taskQuery.taskAssignee("lisi").list();
for (Task task : taskList) {
    System.out.println(task.getId()+":"+task.getName());
    taskService.complete(task.getId());
}

查看act_hi_actinst可查看历史结点:

image27a0c8806e8ad368.png

五、查询历史流程

找到act_hi_procinst,历史流程实例表,可以看到里面有完成的也有为完成的任流程。

image6f94236f71b1cc50.png

先查询流程定义,找到我们要查询的那个流程,然后在查询历史流程实例:

ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey("myProcess_1")
        .latestVersion()
        .singleResult();

HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery();
HistoricProcessInstance historicProcessInstance = query.processInstanceId("15001").finished().singleResult();

System.out.println("historicProcessInstance:"+historicProcessInstance);

输出:historicProcessInstance:HistoricProcessInstanceEntity[superProcessInstanceId=null]

输出结果不为空,表示流程已经完成。

六、领取任务

重新画一个流程图,并指定委派人为一个组

image.png

运行流程实例

//查找对应的流程定义
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey("myProcess_2")
        .latestVersion()
        .singleResult();

//运行
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());

运行后可以查询根据委托人分组查询到对应的流程实例:

Task cpes = taskService.createTaskQuery().taskCandidateGroup("cpes").singleResult();
System.out.println(cpes);

输出如下:Task[id=25004, name=组长审批]

任务领取

Task task1 = taskService.createTaskQuery().taskCandidateGroup("cpes").singleResult();
taskService.claim(task1.getId(),"zhangsan");

List<Task> tasks = taskService.createTaskQuery().taskAssignee("zhangsan").list();
for (Task task : tasks) {
    System.out.println(task);
}

完成任务:

 taskService.complete(task.getId());

七、流程变量

重新定义流程,委托人采用流程变量获取委托人

imageaa4c37ad79d0c1d8.png

imagea8ba4a9e97407bb0.png

部署运行流程

因为指定了流程变量,需要给流程变量赋值,所以直接运行流程实例会报错。

//从act_re_procdef找到流程定义key
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey("myProcess_4")
        .latestVersion().singleResult();

ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());

startProcessInstanceById方法还有一个map参数,就是用来给流程变量赋值的。

//从act_re_procdef找到流程定义key
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey("myProcess_4")
        .latestVersion().singleResult();

Map<String,Object> var = new HashMap<>();
var.put("tl","zhangsan");

ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(),var);

这时候就可以查找zhangsan的流程列表,完成任务了。看我们的流程图,下一步是经理审批,因为经理审批处的流程变量还没有赋值,所以也要在这里给我们设置的${pm}设置值。

TaskQuery taskQuery = taskService.createTaskQuery();
//获取zhangsan的任务列表
List<Task> taskList = taskQuery.taskAssignee("zhangsan").list();
for (Task task : taskList) {
    Map<String,Object> var = new HashMap<>();
    var.put("pm","lisi");
    System.out.println(task.getId()+":"+task.getName());
    taskService.complete(task.getId(),var);
}

这时候运行经理审批这个节点了,我们设置了这个节点的委托人为lisi,我们就查找lisi的任务列表,然后完成。

TaskQuery taskQuery = taskService.createTaskQuery();
//获取zhangsan的任务列表
List<Task> taskList = taskQuery.taskAssignee("lisi").list();
for (Task task : taskList) {
    System.out.println(task.getId()+":"+task.getName());
    taskService.complete(task.getId());
}

到这里任务就完成了。

可以查看下act_hi_actinst表如下:

image9300dd82f0c73592.png

八、网关

排他网关:有多个分支的情况下,只走其中一个分支。(决策网关)。

并行网关:多个分支同时走。(会签网关)。

包含网关:以上两种网关结合在一起使用。(至少满足一个分支或者同时满足两个分支才会走这个流程)

排他网关

同样以请假流程为例,请假天数大于三天需要经理审批,小于等于三天不需要经理审批,设置组长委托人为zhangsan,设置经理委托人为lisi,并设置排他网关的条件。

imageb57d10c4c9558e42.png

同样设置另一条线条件为${days>3}

//查询流程定义
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey("myProcess_6")
        .latestVersion()
        .singleResult();
//准备流程变量
Map<String,Object> var = new HashMap<>();
var.put("days",3);

//启动流程,传递流程变量
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(), var);

//完成任务
List<Task> taskList = taskService.createTaskQuery().taskAssignee("zhangsan").list();
for (Task task : taskList) {
    System.out.println(task);
    taskService.complete(task.getId());
}

//查看流程是否完成  完成则!= null
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
        .processInstanceId(processInstance.getId())
        .finished()
        .singleResult();
System.out.println(historicProcessInstance);

输出结果如下,则流程完成

Task[id=125005, name=组长审核]
HistoricProcessInstanceEntity[superProcessInstanceId=null]

::: tip 注意

特殊情况,条件判断分支中不包含3,但恰恰给了3的值,导致两个分支都没有执行。

:::

并行网关

出差,出差天数项目经理要审批,申请出差费用财务部门要需要审批

项目经理审批:zhangsan

财务经理审批:lisi

image3508b136b2bbd7cb.png

//部署流程
System.out.println(processEngine);
//查询流程定义
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey("myProcess_6")
        .latestVersion()
        .singleResult();
System.out.println(processDefinition);

//部署流程
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());
System.out.println(processInstance);

//查看zhangsan,lisi的任务
Task task = taskService.createTaskQuery()
        .processDefinitionKey("myProcess_6")
        .taskAssignee("lisi")
        .singleResult();
System.out.println(task);
//完成任务
taskService.complete(task.getId());

包含网关

项目经理审批:zhangsan

条件:${days>3}

财务经理审批:lisi

条件:${cost>5000}

image76d89b2f5c442260.png

System.out.println(processEngine);
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey("myProcess_9")
        .latestVersion()
        .singleResult();

Map<String,Object> var = new HashMap<>();
var.put("days",2);
var.put("cost",10000);
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(),var);

Task task = taskService.createTaskQuery().processDefinitionKey("myProcess_9").taskAssignee("lisi").singleResult();

System.out.println(task);

taskService.complete(task.getId());

九、流程监听器

审核通过:${flag==true}

审核拒绝:${flag==false}

imagea334bcca7d95d963.png

创建监听类,实现ExcutorListener接口

package cn.ishangit.helloactivity5.act.listener;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;

/**
 * @description:
 * @author: Chen
 * @create: 2019-06-29 21:23
 **/
public class NoListener implements ExecutionListener {
    @Override
    public void notify(DelegateExecution delegateExecution) throws Exception {
        System.out.println("流程拒绝-------------------");
    }
}
package cn.ishangit.helloactivity5.act.listener;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;

/**
 * @description:
 * @author: Chen
 * @create: 2019-06-29 21:23
 **/
public class YesListener implements ExecutionListener {

    @Override
    public void notify(DelegateExecution delegateExecution) throws Exception {
        System.out.println("流程同意-------------------");
    }
}

绑定监听器

image867d156902b84474.png

测试:

System.out.println(processEngine);
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .processDefinitionKey("myProcess_10")
        .latestVersion()
        .singleResult();

ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());

Task task = taskService.createTaskQuery().processDefinitionKey("myProcess_10").taskAssignee("zhangsan").singleResult();

System.out.println(task);

Map<String,Object> var = new HashMap<>();
var.put("flag",true);
taskService.complete(task.getId(),var);

结果:

image80c8968fcc3e2769.png

猜你喜欢

转载自www.cnblogs.com/chen88/p/11538432.html