当前位置:   article > 正文

Activiti7笔记_activiti7 结束任务流程

activiti7 结束任务流程

Activiti7

什么工作流引擎

框架,将业务数据和节点的流程进行分离【特定形式进行关联】,实现节点的自动流转的工作流框架.,帮助我们实现流程自动化。

使用情景:也称为工作流

请假审批:填写申请–>主管部门–>HR审批

报销审批:填写申请–>经理批准–>总经理–>财务批准

虽然不用框架也能实现该业务需求,流程变得复杂,需要改动时,就需要耗费大量的时间成本

Activiti7框架就是这样开源出来的一套框架,可以做到流程与代码分离,帮助我们实现

一、Activiti7的内部核心机制
  1. 业务流程图需要符合规范
  2. 业务流程图的本质就是xml文件,里面的数据就是一个个的节点
  3. 解析业务流程图的过程就是解析xml文件,读取数据的过程
  4. 读取节点就是把数据存到数据库中,形成一条条的记录
  5. 后续我们只要对表进行查询就能知道流程走到哪一步 ru_task
  6. 任务完成提交就是更改数据库中表的记录,再读取下一个节点的数据
  7. 流程接受后,更改表的记录
二、BPMN

制定了一套规范,也就是业务流程图

三、使用Activiti
1. 流程:
  1. 业务流程建模,画业务流程图
  2. 部署业务流程,定义业务流程,可以理解为定义一个类,关联业务流程图 …bpmn
  3. 启动业务流程,流程实例,可以理解为创建对象
  4. 查询任务
  5. 执行任务
  6. 结束流程,如果没有下一个结点,就是任务完成
2. 环境:
  1. jdk1.8或以上
  2. mysql5或以上
  3. Tomcat8.5
  4. IDEA
  5. Activiti 7.0.0.SR1
3. 安装Activiti流程设计器(画图工具)
4.处理中文乱码
5.支持的数据库
四、集成Activiti7

SE环境,基于maven项目

1. 添加依赖
<!--添加依赖-->
    <properties>
        <slf4j.version>1.6.6</slf4j.version>
        <log4j.version>1.2.12</log4j.version>
        <activiti.version>7.0.0.SR1</activiti.version>
    </properties>
    <dependencies>
        <!-- activiti引擎 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-engine</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <!-- 整合Spring -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <!-- bpmn 模型处理 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-model</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <!-- bpmn 转换 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-converter</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <!-- bpmn json数据转换 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-json-converter</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <!-- bpmn 布局 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-bpmn-layout</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.40</version>
        </dependency>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!-- 链接池 -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <!-- 单元测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!-- log start -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <!-- log end -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <!--数据库连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.4</version>
        </dependency>
    </dependencies>
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
2. 添加日志文件

在resource文件夹中创建log4j.properties文件

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=./activiti.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
3.添加核心配置文件

在resource文件夹中创建名为 activiti.cfg.xml 的文件,文件名是固定的,不按规则命名会报错

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contex
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
	<!--添加数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql:///activiti"/>
        <property name="username" value="root"/>
        <property name="password" value="admin"/>
    </bean>


    <!-- 默认id对应的值 为processEngineConfiguration -->
    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <property name="dataSource" ref="dataSource"/>
        <!--
            activiti数据库表处理策略
                false(默认值):检查数据库的版本和依赖库的版本,如果不匹配就抛出异常
                true:构建流程引擎时,执行检查,如果需要就执行更新。如果表不存在,就创建。
                create-drop:构建流程引擎时创建数据库报表,关闭流程引擎时就删除这些表。
                drop-create:先删除表再创建表。
                create:构建流程引擎时创建数据库表,关闭流程引擎时不删除这些表
        -->
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</beans>
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
五、数据库表的说明
1. 介绍

Activiti是通过操作数据库中的表单来实现工作流的。不同的环境中,表的数量也是不一样的。

此环境中有25张表。

  1. 每一种表都对应着一个Service
  2. 命名规则
    1. "act_re"开头的表,re表示 Repository,与流程定义有关
    2. "act_ru"开头的表,,ru表示RunTime,与流程实例,任务处理有关,只保存正在执行中的任务的数据
    3. "act_hi"开头的表,,hi表示History,记录流程,变量,任务等的历史信息
    4. "act_ge"开头的表,ge表示General,记录通用数据
2. 常用表
  1. 流程定义—>RepositoryService

    1. act_ge_bytearray:用于存储bpmn的数据

    2. act_ge_property:用于生产主键等,是内部表,我们一般不需要关注

    3. act_re_deployment:部署信息表

    4. act_re_procdef:流程定义表

  2. 流程实例—>RunTimeService

    1. act_ge_property:主键更新
    2. act_hi_actinst:历史节点表,记录所有开始,任务,结束节点的信息
    3. act_hi_identitylink:历史身份表,记录所有用户的信息
    4. act_hi_procinst:历史流程表:记录所有流程实例的信息
    5. act_hi_taskinst:历史任务表:记录所有任务对象的信息
    6. act_ru_execution:运行时流程执行实例表
    7. act_ru_identitylink:运行时用户信息表,
    8. act_ru_task:运行时任务信息表
  3. 执行任务—>taskService

    1. act_hi_actinst:历史节点表,记录所有开始,任务,结束节点的信息
    2. act_hi_identitylink:历史身份表,记录所有用户的信息
    3. act_hi_taskinst:历史任务表:记录所有任务对象的信息
    4. act_ru_execution:运行时流程执行实例表
    5. act_ru_identitylink:运行时用户信息表,
    6. act_ru_task:运行时任务信息表
六、流程引擎的API
接口作用
RepositoryService进行资源管理,流程定义
RunTImeService进行流程实例
TaskService进行任务管理
HistoryService进行历史管理
ManagementService进行引擎管理
七、Activiti7的入门
1. bpmn的制作
image-20220529144831975 image-20220529144851096

bpmn的id和Name是自定义的

image-20220529145102000

给任务节点设置名字,给上执行人,后续执行人可以使用UEL表达式,监听器来设置,也可以通过候选人方式设置。

2. 流程定义
@Test
public void test1() {
    //1 获取流程引擎对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    //2 获取仓库Service, RespositoryService
    processEngine.getRepositoryService()
            .createDeployment()
            .addClasspathResource("bpmn/act3.bpmn")
            .deploy();
	//一个deploye对应一个流程定义
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
3.流程实例
@Test
public void test2() {
    processEngine.getRuntimeService()
            .startProcessInstanceByKey("bpmn图中id");//自定义的流程名称
}
  • 1
  • 2
  • 3
  • 4
  • 5
4.执行任务
@Test
public void test3(){
    /*
    	参数为该任务的id,可以用TaskService提供query方法进行任务的查询
   		添加评论要在任务提交前执行
    	添加评论 taskService.addComent(taskId,processInstanceId,messag);
    	多个对象用list(),唯一用singleResult()
    */
   ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        taskService
                .createTaskQuery()
                .processDefinitionKey("leaveProcess")//查询条件
                .taskAssignee("张三")//查询条件
                .list().forEach(task -> {
            taskService.addComment(task.getId(), task.getProcessInstanceId(), "不干了");
            taskService.complete(task.getId());
        });
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
5.查看历史情况
@Test
    public void test10() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        HistoryService historyService = processEngine.getHistoryService();
        historyService.createHistoricProcessInstanceQuery()
                .processDefinitionKey("leaveProcess")
                .list()
                .forEach(historicProcessInstance -> {
                    System.out.println(historicProcessInstance.getId());
                });
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
八、Activiti7的进阶
一、流程定义相关
  1. 查询流程相关信息,包含流程定义,流程部署,流程定义版本
@Test
public void testDefinitionQuery(){
    //创建ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    //获取仓库服务
    RepositoryService repositoryService = processEngine.getRepositoryService();
    //获取流程定义集合
    List<ProcessDefinition> processDefinitionList = repositoryService
            .createProcessDefinitionQuery()
            .processDefinitionKey("leaveProcess")
            .list();
    //遍历集合
    for (ProcessDefinition definition:processDefinitionList){
        System.out.println("流程定义ID:"+definition.getId());
        System.out.println("流程定义名称:"+definition.getName());
        System.out.println("流程定义key:"+definition.getKey());
        System.out.println("流程定义版本:"+definition.getVersion());
        System.out.println("流程部署ID:"+definition.getDeploymentId());
        System.out.println("====================");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

2.现在我们的流程资源文件已经上传到数据库了,如果其他用户想要查看这些资源文件,可以从数据库中把资源文件下载到本地。

@Test
public void testDownloadResource() throws Exception {
    //创建ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    //获取仓库服务
    RepositoryService repositoryService = processEngine.getRepositoryService();
    //获取流程定义集合
    List<ProcessDefinition> list = repositoryService
            .createProcessDefinitionQuery()
            .processDefinitionKey("leaveProcess")
            .orderByProcessDefinitionVersion()//按照版本排序
            .desc()//降序
            .list();
    //获取最新那个
    ProcessDefinition definition =list.get(0);
    //获取部署ID
    String deploymentId = definition.getDeploymentId();
    //获取bpmn的输入流
    InputStream bpmnInput = repositoryService.getResourceAsStream(
                                        deploymentId,
                                        definition.getResourceName());
    //获取png的输入流
    InputStream pngInput = repositoryService.getResourceAsStream(
                                        deploymentId,
                                        definition.getDiagramResourceName());
    //设置bpmn输入
    FileOutputStream bpmnOutPut = new FileOutputStream("D:/leave.bpmn");
    //设置png输入
    FileOutputStream pngOutPut = new FileOutputStream("D:/leave.png");
    IOUtils.copy(bpmnInput,bpmnOutPut);
    IOUtils.copy(pngInput,pngOutPut);
}
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

3.根据部署Id删除对应的流程定义

如果流程定义 没有流程实例可以直接删除

如果流程定义 已近有流程实例,可以通过一个参数 true 进行级联删除

@Test
public void test3(){
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    processEngine.getRepositoryService().deleteDeployment("5001",true);
}
  • 1
  • 2
  • 3
  • 4
  • 5
二、流程实例相关

框架,将业务数据和节点的流程进行分离【特定形式进行关联】,特定形式指的就是businessKey

businessKey
搞清楚businessKey 作用?
把我们的业务数据和流程绑定起来 , 因为在审核的时候 , 审核人妖看到用户申请信息.
步骤
1 用户在申请的时候填写信息 ,最终把信息保存到业务表中
2 先画出bpmn流程 ,把流程图 部署到activiti当中
3 小陈发起申请, 在activiti 开启流程实例 , 在启动流程时候就会把businessKey 和流程实例绑定起来
4 任务走了部门经理节点 , 这里是一个任务, 我们是可以通过任务拿到流程实例id
5 通过流程实例id拿到流程实例 , 就可以通过流程实例那businessKey
6 根据businessKey 上业务表中取查询数据 , 审核人在根据查询的数据看是否通过

public class Demo {

    /**
     * 获取businessKey
     */
    //流程定义
    @Test
    public void test1() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getRepositoryService()
                .createDeployment()
                .addClasspathResource("bpmn/act3.bpmn")
                .deploy();

    }

    //流程实例+添加businessKey
    @Test
    public void test2() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getRuntimeService()
                .startProcessInstanceByKey("act3", "2887");
    }

    //在任务中获取实例id,通过实例id获取实例对象,通过实例对象获取businessKey
    @Test
    public void test3() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String processInstanceId = processEngine.getTaskService()
                .createTaskQuery()
                .singleResult()
                .getProcessInstanceId();

        String businessKey = processEngine
                .getRuntimeService()
                .createProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .singleResult()
                .getBusinessKey();

        System.out.println("businessKey = " + businessKey);
    }
}

  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

三、流程定义/实例挂起/激活

例如公司制度改变过程中的流程, 总经理更换过程中的流程,有100个人的流程, 70个人已经完成,30个人流程正好在总经理更换中,就需要挂起.

  1. 比如我们的业务流程为:

【开始节点】–>【A节点】–>【B节点】–>【C节点】–>【结束节点】

【C节点】的业务逻辑需要和外部接口交互,刚好外部接口出问题了,如果剩下的流程都走到【C节点】,执行【C节点】的业务逻辑,那都会报错,我们就可以把流程挂起,等待外部接口可用之后再重新激活流程.

  1. 业务流程发生改变,已经发起的流程实例继续按照旧的流程走,如果新发起的流程就按照新的业务流程走.这时候我们就需要挂起流程定义,但是不挂起流程实例.
  • 操作流程定义为挂起状态,该操作定义下面的所有的流程实例将全部暂停。
  • 流程定义为挂起状态,该流程定义下将不允许启动新的流程实例,同时该流程定义下的所有流程实例将全部挂起暂停执行
public class Demo {

    /**
     * 流程定义的挂起与激活
     */

    //定义流程
    @Test
    public void test1() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getRepositoryService()
                .createDeployment()
                .addClasspathResource("bpmn/act4.bpmn")
                .deploy();
    }

    //流程实例
    @Test
    public void test2() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getRuntimeService()
                .startProcessInstanceByKey("act4");
    }

    //进行流程挂起
    @Test
    public void test3() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        ProcessDefinition processDefinition = processEngine.getRepositoryService().
                createProcessDefinitionQuery()
                .singleResult();
        processEngine.getRepositoryService().suspendProcessDefinitionById(processDefinition.getId());
    }

    //查询流程挂起状态
    @Test
    public void test4() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        System.out.println(processEngine.getRepositoryService()
                .createProcessDefinitionQuery()
                .singleResult().isSuspended());//true
    }

    //可以完成未完成的任务
    @Test
    public void test5() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        Task task = processEngine.getTaskService()
                .createTaskQuery()
                .singleResult();
        processEngine.getTaskService().complete(task.getId());
    }

    //但不能再流程实例
    @Test
    public void test6() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getRuntimeService()
                .startProcessInstanceByKey("act4");
    }

    //重新激活流程定义+测试+执行新实例任务
    @Test
    public void test7() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        ProcessDefinition processDefinition = repositoryService
                .createProcessDefinitionQuery()
                .singleResult();
        if (processDefinition.isSuspended()) {
            System.out.println("to true");
            repositoryService.activateProcessDefinitionById(processDefinition.getId());

            System.out.println("流程实例");
            processEngine.getRuntimeService()
                    .startProcessInstanceByKey("act4");

            System.out.println("执行任务");
            TaskService taskService = processEngine.getTaskService();
            Task task = taskService.createTaskQuery().taskAssignee("张三").singleResult();
            taskService.complete(task.getId());
        }
    }

    //挂起后不能执行任务和进行流程定义
    @Test
    public void test8() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        ProcessDefinition processDefinition = repositoryService
                .createProcessDefinitionQuery()
                .singleResult();
        repositoryService
                .suspendProcessDefinitionById(processDefinition.getId(), true, null);
    }

    //不能进行流程定义
    @Test
    public void test9(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getRuntimeService()
                .startProcessInstanceByKey("act4");
    }
    //不能执行任务
    @Test
    public void test10(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getTaskService().complete("10005");
    }

    //挂起实例
    @Test
    public void test11(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //把原来的挂起的流程定义激活
        RepositoryService repositoryService = processEngine.getRepositoryService();
        ProcessDefinition processDefinition = repositoryService
                .createProcessDefinitionQuery()
                .singleResult();
    
        //挂起实例
        RuntimeService runtimeService = processEngine.getRuntimeService();
        runtimeService.suspendProcessInstanceById("10001");
        //检测是否挂起,若已近挂起,就重新激活,并执行任务
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery()
                .taskAssignee("张三")
                .singleResult();
        //获取实例id
        String processInstanceId = task.getProcessInstanceId();
        //判断是否已近挂起
        boolean suspended = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .singleResult()
                .isSuspended();
        if (suspended) {
            System.out.println("======================");
            System.out.println("激活");
            runtimeService.activateProcessInstanceById(processInstanceId);
            taskService.complete(task.getId());
        }
    }
}
  • 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
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
三、任务分配

指的就是指定处理任务的人,分配方法有三种

1.固定分配 直接把名字写死,在实际开发过程中,此方法不适应。但在测试时使用比其他的方法都方便。

​ 只要在任务结点中的 Assignee属性中设置值

  1. 使用EUL表达式,是一种占位符,在任务结点中的 Assignee属性中设置${value}。需要把处理人添加到流程实例,就要在流程实例时,添加参数 ,以map的方式添加。

    public class UEL {
    
        /**
         * 分配负责人
         */
    
        //流程定义
        @Test
        public void test1() {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            processEngine.getRepositoryService()
                    .createDeployment()
                    .addClasspathResource("bpmn/act5.bpmn")
                    .deploy();
        }
    
        //实例部署
        @Test
        public void test2() {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            Map<String, Object> map = new HashMap<>();
            map.put("s1", "张三");
            map.put("s2", "lisi");
            processEngine.getRuntimeService()
                    .startProcessInstanceByKey("act5", map);
        }
    
        //查询候选人
        @Test
        public void test3() {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            Task lisi = processEngine.getTaskService()
                    .createTaskQuery()
                    .taskCandidateOrAssigned("lisi").singleResult();
        }
        //领任务
        @Test
        public void test4(){
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
            processEngine.getTaskService().claim("17507","lisi");
        }
    
        //执行任务
        @Test
        public void test5(){
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            processEngine.getTaskService().complete("17507");
        }
    }
    
    • 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
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    1. 监听器

      任务监听器是发生对应的任务相关事件时执行自定义的Java逻辑或表达式。

      任务相关事件包括:

      • Event:触发事件
        • Create:任务创建后触发。
        • Assignment:任务分配后触发。
        • Delete:任务完成后触发。
        • All:所有事件发生都触发。
    2. 自定义一个任务监听器类,然后此类必须实现org.activiti.engine.delegate.TaskListener接口

      package cn.wolfcode;
      
      import org.activiti.engine.delegate.DelegateTask;
      import org.activiti.engine.delegate.TaskListener;
      
      /**
       * Created by wolfcode
       */
      public class AssigneeTaskListener implements TaskListener {
          public void notify(DelegateTask delegateTask) {
              if(delegateTask.getName().equals("部门经理审批")){
                  delegateTask.setAssignee("赵六");
              }else if(delegateTask.getName().equals("部门经理审批")){
                  delegateTask.setAssignee("孙七");
              }
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
    3. 在bpmn文件中配置监听器

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uzt3J72y-1653831176864)(E:/CodeWolf/20220215/阶段四/07 Activit/讲义/图片/image-20210603114503828.png)]

    在实际开发中,一般也不使用监听器分配方式,太麻烦了。

四、流程变量

​ 在流程中,可以通过变量来控制流程的走向,从而增强业务能力。

  1. 局部变量(少用)
  2. 全局变量(多用)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GXacHjjK-1653831176865)(C:\Users\SKY\AppData\Roaming\Typora\typora-user-images\image-20220529172114148.png)]

3. 使用方法
  	1. 在流程实例时,添加一个map为参数,Map<String,Object> ,String为变量名,Object为值
4. 特殊情况
  	1. 当两个情况都满足,在不添加其他操作时,两个任务都会被触发
  	2. 当两个情况都不满足时,会抛出异常,说找不到出口
  • 1
  • 2
  • 3
  • 4
  • 5
五、任务候选人
1. 在实际运用的过程中,任务的执行人不是固定的,而是从几个人中,拿一个人出来执行便可
2. 在Condidata中,通过添加候选人,可以添加多个,中间使用逗号隔开
3. 在流程实例后,候选人领取任务前,该任务是没有执行人的
4. 候选人执行任务
  	1. 要使用TaskServicet提供的 claim(String taskId,String userId),进行领取任务
  	2. 使用 taskSerice.commit(Strinig taskId)执行任务
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
六、网关
  1. 排他网关

    1. 当流程走到这个网关是,所有的分支都会进行判断,表达式为true的分支就是流程走向
    2. 如果分支都为true,就会选择id小的分支
    3. 当分支都为false时,会报错,说流程找不到出口
  2. 并行网关

    1. 需要两个网关,把所有分支都夹起来
    2. 只有里面的分支全都走完,流程才能到下一个结点
  3. 包含网关

    1. 可以看成是排他网关与并行网关的集合体

    2. 需要两个网关,把所有分支都夹起来

    3. 使用场景:请假规则

      1. 请假<3天的副经理批准
      2. 请假>3天的总经理批准
      3. 请假无论多少天都需要人事部门批准

候选人,需要先使用claim进行领取任务,在执行任务

g为变量名,Object为值
4. 特殊情况
1. 当两个情况都满足,在不添加其他操作时,两个任务都会被触发
2. 当两个情况都不满足时,会抛出异常,说找不到出口

五、任务候选人
1. 在实际运用的过程中,任务的执行人不是固定的,而是从几个人中,拿一个人出来执行便可
2. 在Condidata中,通过添加候选人,可以添加多个,中间使用逗号隔开
3. 在流程实例后,候选人领取任务前,该任务是没有执行人的
4. 候选人执行任务
  	1. 要使用TaskServicet提供的 claim(String taskId,String userId),进行领取任务
  	2. 使用 taskSerice.commit(Strinig taskId)执行任务
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
六、网关
  1. 排他网关

    1. 当流程走到这个网关是,所有的分支都会进行判断,表达式为true的分支就是流程走向
    2. 如果分支都为true,就会选择id小的分支
    3. 当分支都为false时,会报错,说流程找不到出口
  2. 并行网关

    1. 需要两个网关,把所有分支都夹起来
    2. 只有里面的分支全都走完,流程才能到下一个结点
  3. 包含网关

    1. 可以看成是排他网关与并行网关的集合体

    2. 需要两个网关,把所有分支都夹起来

    3. 使用场景:请假规则

      1. 请假<3天的副经理批准
      2. 请假>3天的总经理批准
      3. 请假无论多少天都需要人事部门批准
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/784603
推荐阅读
相关标签
  

闽ICP备14008679号