ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【Aactiviti7 从入门到放弃】(一)Activiti7工作流引擎入门

2022-01-14 18:07:09  阅读:419  来源: 互联网

标签:入门 activiti 流程 System Activiti7 Aactiviti7 println public out


目录

4.3 SpringBoot2与Activiti7整合

  • 官方文档
    • https://activiti.gitbook.io/activiti-7-developers-guide/getting-started/getting-started-activiti-core
    • https://github.com/Activiti/Activiti

4.3.1 创建项目

命名:springboot-activiti7

4.3.2 Maven依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.edcode.activiti</groupId>
    <artifactId>springboot-activiti7</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- https://github.com/Activiti/Activiti -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter</artifactId>
            <version>7.1.0.M4</version>
        </dependency>
        <dependency>
            <groupId>org.activiti.dependencies</groupId>
            <artifactId>activiti-dependencies</artifactId>
            <version>7.1.0.M4</version>
            <type>pom</type>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <configuration>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.1</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

4.3.3 application.yml

server:
  port: 8080
  servlet:
    context-path: /
spring:
  datasource:
    # 数据源
    url: jdbc:mysql://${MYSQL_HOST:127.0.0.1}:${MYSQL_PORT:3306}/${MYSQL_DATABASE:activity}?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false
    username: ${MYSQL_USERNAME:root}
    password: ${MYSQL_PASSWORD:123456}
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 连接池
    hikari:
      maximum-pool-size: 8
      minimum-idle: 4
      idle-timeout: 30000
      connection-timeout: 30000
      max-lifetime: 45000
      auto-commit: true
      pool-name: ScaCommerceHikariCP
  redis:
    database: 0
    host: ${REDIS_HOST:localhost}
    port: ${REDIS_PORT:6379}
    timeout: 5000
  # 日志的相关配置
  activiti:
    history-level: full
    db-history-used: true
    # 自动部署验证设置:true-开启(默认)、false-关闭
    check-process-definitions: false

4.3.4 启动项目

如图,自动创建数据库表
在这里插入图片描述

4.3.4 手动添加两张数据表,是M4版本缺陷

-- auto-generated definition
-- create schema `test-activity` collate utf8mb4_unicode_ci;

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- 创建用户表
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
                        `id` bigint(20) NOT NULL AUTO_INCREMENT,
                        `name` varchar(32) DEFAULT NULL COMMENT '姓名',
                        `address` varchar(64) DEFAULT NULL COMMENT '联系地址',
                        `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '账号',
                        `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密码',
                        `roles` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '角色',
                        PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

-- ----------------------------
-- 填充用户表
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'admincn', 'beijing', 'admin', '$2a$10$gw46pmsOVYO.smHYQ2jH.OoXoe.lGP8OStDkHNs/E74GqZDL5K7ki', 'ROLE_ACTIVITI_ADMIN');
INSERT INTO `user` VALUES ('2', 'bajiecn', 'shanghang', 'bajie', '$2a$10$gw46pmsOVYO.smHYQ2jH.OoXoe.lGP8OStDkHNs/E74GqZDL5K7ki', 'ROLE_ACTIVITI_USER,GROUP_activitiTeam,g_bajiewukong');
INSERT INTO `user` VALUES ('3', 'wukongcn', 'beijing', 'wukong', '$2a$10$gw46pmsOVYO.smHYQ2jH.OoXoe.lGP8OStDkHNs/E74GqZDL5K7ki', 'ROLE_ACTIVITI_USER,GROUP_activitiTeam');
INSERT INTO `user` VALUES ('4', 'salaboycn', 'beijing', 'salaboy', '$2a$10$gw46pmsOVYO.smHYQ2jH.OoXoe.lGP8OStDkHNs/E74GqZDL5K7ki', 'ROLE_ACTIVITI_USER,GROUP_activitiTeam');

-- ----------------------------
-- 修复Activiti7的M4版本缺失字段Bug
-- ----------------------------
alter table ACT_RE_DEPLOYMENT add column PROJECT_RELEASE_VERSION_ varchar(255) DEFAULT NULL;
alter table ACT_RE_DEPLOYMENT add column VERSION_ varchar(255) DEFAULT NULL;

-- ----------------------------
-- 动态表单数据存储
-- ----------------------------
DROP TABLE IF EXISTS `formdata`;
CREATE TABLE `formdata` (
                            `PROC_DEF_ID_` varchar(64) DEFAULT NULL,
                            `PROC_INST_ID_` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
                            `FORM_KEY_` varchar(255) DEFAULT NULL,
                            `Control_ID_` varchar(100) DEFAULT NULL,
                            `Control_VALUE_` varchar(2000) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

4.4 流程部署 - Deployment

4.4.1 涉及到的数据表

  • ACT_RE_DEPLOYMENT
  • ACT_RE_PROCDEF
  • ACT_GE_BYTEARRAY

4.4.2 通过bpmn部署流程

@Autowired
private RepositoryService repositoryService;

@Test
public void initDeploymentBPMN() {
    String filename = "BPMN/Part1_Deployment.bpmn20.xml";
//        String pngname="BPMN/Part1_Deployment.png";
    Deployment deployment = repositoryService.createDeployment()
            .addClasspathResource(filename)
//                .addClasspathResource(pngname)
            .name("流程部署测试BPMN_v2")
            .deploy();
    System.out.println(deployment.getName());
}

Part1_Deployment.png 生成,对着流程图右键:Save to PNG 即可

4.4.3 通过ZIP部署流程

@Autowired
private RepositoryService repositoryService;

@Test
public void initDeploymentZIP() {
    InputStream fileInputStream = this.getClass()
            .getClassLoader()
            .getResourceAsStream("BPMN/Part1_DeploymentV2.zip");
    assert fileInputStream != null;
    ZipInputStream zip = new ZipInputStream(fileInputStream);
    Deployment deployment = repositoryService.createDeployment()
            .addZipInputStream(zip)
            .name("流程部署测试zip")
            .deploy();
    System.out.println(deployment.getName());
}

对住需要压缩的文件 Part1_Deployment.bpmn20V2.xml、Part1_DeploymentV2.png 右键压缩成 zip 即可

4.4.4 查询流程部署

@Autowired
private RepositoryService repositoryService;

@Test
public void getDeployments() {
    repositoryService.createDeploymentQuery().list().forEach(deployment -> {
        System.out.println("Id:" + deployment.getId());
        System.out.println("Name:" + deployment.getName());
        System.out.println("DeploymentTime:" + deployment.getDeploymentTime());
        System.out.println("Key:" + deployment.getKey() + "\n\r");
    });
}

在这里插入图片描述

遍历 ACT_RE_DEPLOYMENT 表

4.5 流程定义 - ProcessDefinition

  • ProcessDefinition
    • 获取版本号、Key、资源名称、部署ID等

4.5.1 查询流程定义

@Autowired
private RepositoryService repositoryService;

@Test
public void getProcessDefinition() {
    repositoryService.createProcessDefinitionQuery().list().forEach(processDefinition -> {
        System.out.println("Name:" + processDefinition.getName());
        System.out.println("Key:" + processDefinition.getKey());
        System.out.println("ResourceName:" + processDefinition.getResourceName());
        System.out.println("DeploymentId:" + processDefinition.getDeploymentId());
        System.out.println("Version:" + processDefinition.getVersion() + "\n\r");
    });
}

4.5.2 删除流程定义

@Autowired
private RepositoryService repositoryService;

@Test
public void delProcessDefinition() {
    // 上面打印的 DeploymentId
    String pid = "e59fe37d-7388-11ec-92c7-5e879ca31830";
    // true 情况下,会删除所有的流程定义、历史等,如果是 false 是会保留历史,一般情况下是 false
    repositoryService.deleteDeployment(pid,true);
    System.out.println("删除流程定义成功");
}

这些表都会出现变化: ACT_RE_PROCDEF --> ACT_RE_DEPLOYMENT --> ACT_GE_BYTEARRAY

4.6 流程实例 - ProcessInstance

  • ProcessDefinition 与 ProcessInstance 是一对多的关系
  • 理解:行动计划与具体行动的关系

4.6.1 初始化流程实例

@Autowired
private RuntimeService runtimeService;

@Test
public void initProcessInstance() {
    //1、获取页面表单填报的内容,请假时间,请假事由,String fromData
    //2、fromData 写入业务表,返回业务表主键ID==businessKey
    //3、把业务数据与Activiti7流程数据关联
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess_Part1", "bKey001");
    //
    System.out.println("流程实例ID:" + processInstance.getProcessDefinitionId());
}

4.6.2 获取流程实例列表

@Autowired
private RuntimeService runtimeService;

@Test
public void getProcessInstances() {
    runtimeService.createProcessInstanceQuery().list().forEach(processInstance -> {
        System.out.println("--------流程实例------");
        System.out.println("ProcessInstanceId:" + processInstance.getProcessInstanceId());
        System.out.println("ProcessDefinitionId:" + processInstance.getProcessDefinitionId());
        System.out.println("isEnded" + processInstance.isEnded());
        System.out.println("isSuspended:" + processInstance.isSuspended());
    });
}

4.6.3 暂停与激活流程实例

@Autowired
private RuntimeService runtimeService;

@Test
public void activitieProcessInstance() {
//        runtimeService.suspendProcessInstanceById("df08e9f8-73b9-11ec-8e8a-5e879ca31830");
//        System.out.println("挂起流程实例");

    runtimeService.activateProcessInstanceById("df08e9f8-73b9-11ec-8e8a-5e879ca31830");
    System.out.println("激活流程实例");
}

先挂起,再激活

4.6.4 删除流程实例

@Autowired
private RuntimeService runtimeService;

@Test
public void delProcessInstance() {
    try {
        runtimeService.deleteProcessInstance("df08e9f8-73b9-11ec-8e8a-5e879ca31830", "删着玩");
        System.out.println("删除流程实例");
    } catch (Exception e) {
        System.out.println("因为挂起或者激活过,都会拋异常! 其实删除流程成功的!");
        getProcessInstances();
    }
}

因为挂起或者激活过,都会拋异常! 其实删除流程成功的!

4.7 任务处理 Task

4.7.1 任务类型

任务的图形化是以矩形为基础,在左侧添加具体的图标,用来描述一种特定任务类型。用户任务需要人来参与,需要人为出发。

4.7.2 用户任务属性面板(User Task)

  • Assignee:执行人/代理人
  • Due Date:任务到期时间
  • Candidate Users:候选人
  • Candidate Groups:候选组

候选相关的,在Activiti 7 之后弱化了。但是可以通过代码生成

4.7.3 画简单的报销流程图

创建 Part4_Task.bpmn20.xml,右键 “View BPMN(Activiti)Dragram”

效果图:
在这里插入图片描述----

在这里插入图片描述

4.7.4 任务处理Task

4.7.4.1 BPMN 图形

在这里插入图片描述

4.7.4.2 流程顺序

在这里插入图片描述

4.7.4.3 按上图抽取单元测试代码 - 执行任务

  • 创建 Part4_Task.bpmn20.xml

com.edcode.activiti.Part1_Deployment#initDeploymentBPMN

/**
 * 通过bpmn部署流程
 */
@Test
public void initDeploymentBPMN() {
    String filename = "BPMN/Part4_Task_claim.bpmn20.xml";
//        String pngname="BPMN/com.edcode.activiti.Part1_Deployment#initDeploymentBPMN";
    Deployment deployment = repositoryService.createDeployment()
            .addClasspathResource(filename)
//                .addClasspathResource(pngname)
            .name("流程部署测试Task")
            .deploy();
    System.out.println(deployment.getName());
}

com.edcode.activiti.Part2_ProcessDefinition#getProcessDefinition

/**
* 查询流程定义
*/
@Test
public void getProcessDefinition() {
   repositoryService.createProcessDefinitionQuery().list().forEach(processDefinition -> {
       System.out.println("Name:" + processDefinition.getName());
       System.out.println("Key:" + processDefinition.getKey());
       System.out.println("ResourceName:" + processDefinition.getResourceName());
       System.out.println("DeploymentId:" + processDefinition.getDeploymentId());
       System.out.println("Version:" + processDefinition.getVersion() + "\n\r");
   });
}

com.edcode.activiti.Part3_ProcessInstance#initProcessInstance

/**
* 获取流程实例列表
*/
@Test
public void initProcessInstance() {
    //1、获取页面表单填报的内容,请假时间,请假事由,String fromData
    //2、fromData 写入业务表,返回业务表主键ID==businessKey
    //3、把业务数据与Activiti7流程数据关联
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess_claim", "bKey003");
    //
    System.out.println("流程实例ID:" + processInstance.getProcessDefinitionId());
}

com.edcode.activiti.Part4_Task#getTasks

/**
 * 任务查询
 */
@Test
public void getTasks() {
    taskService.createTaskQuery().list().forEach(task -> {
        System.out.println("Id:" + task.getId());
        System.out.println("Name:" + task.getName());
        System.out.println("Assignee:" + task.getAssignee());
    });
}

com.edcode.activiti.Part4_Task#getTasksByAssignee

/**
* 查询我的代办任务
*/
@Test
public void getTasksByAssignee() {
   taskService.createTaskQuery()
           .taskAssignee("bajie")
           .list().forEach(task -> {
               System.out.println("Id:" + task.getId());
               System.out.println("Name:" + task.getName());
               System.out.println("Assignee:" + task.getAssignee());
           });
}

com.edcode.activiti.Part4_Task#completeTask

/**
* 执行任务
*/
@Test
public void completeTask() {
   taskService.complete("659387de-7422-11ec-9bf1-5e879ca31830");
   System.out.println("完成任务");
}

4.7.4.4 拾取任务

在这里插入图片描述

  • 拾取任务
    • 创建 Part4_Task_claim.bpmn20.xml
    • 查询流程定义(复制:Key:myProcess_claim)
    • 初始化流程实例(黏贴:Key, 然后修改 bKey003)
    • 任务查询(发现 办理人Assignee 是空的,复制taskId)
    • 拾取任务(输入 taskId: 5a628824-7438-11ec-b645-5e879ca31830 和 userid: bajie)
    • 任务查询(办理人Assignee就是bajie)
/**
 * 拾取任务
 */
@Test
public void claimTask() {
    Task task = taskService.createTaskQuery().taskId("5a628824-7438-11ec-b645-5e879ca31830").singleResult();
    taskService.claim("5a628824-7438-11ec-b645-5e879ca31830", "bajie");
}

4.7.4.5 归还与交办任务

@Test
public void setTaskAssignee() {
    Task task = taskService.createTaskQuery().taskId("5a628824-7438-11ec-b645-5e879ca31830").singleResult();
    taskService.setAssignee("5a628824-7438-11ec-b645-5e879ca31830", "null");//归还候选任务
    taskService.setAssignee("5a628824-7438-11ec-b645-5e879ca31830", "wukong");//交办
}

4.9 历史任务 - HistoryService

4.9.1 查询历史任务

  • 历史综合信息:HistoricTaskInstance
  • 历史变量:HistoricVariablelnstance

4.9.2 根据用户名查询历史记录

@Autowired
private HistoryService historyService;

@Test
public void HistoricTaskInstanceByUser() {
    historyService
            .createHistoricTaskInstanceQuery()
            .orderByHistoricTaskInstanceEndTime()
            .asc()
            .taskAssignee("bajie")
            .list().forEach(historicTaskInstance -> {
                System.out.println("Id:" + historicTaskInstance.getId());
                System.out.println("ProcessInstanceId:" + historicTaskInstance.getProcessInstanceId());
                System.out.println("Name:" + historicTaskInstance.getName());
            });
}

打印:

Id:df0d7ddc-73b9-11ec-8e8a-5e879ca31830
ProcessInstanceId:df08e9f8-73b9-11ec-8e8a-5e879ca31830
Name:null
Id:561b8715-7421-11ec-80e4-5e879ca31830
ProcessInstanceId:56174151-7421-11ec-80e4-5e879ca31830
Name:发起报销

4.9.3 根据流程实例ID查询历史

@Autowired
private HistoryService historyService;

@Test
public void HistoricTaskInstanceByPiID(){
    historyService
            .createHistoricTaskInstanceQuery()
            .orderByHistoricTaskInstanceEndTime()
            .asc()
            .processInstanceId("56174151-7421-11ec-80e4-5e879ca31830")
            .list().forEach(historicTaskInstance -> {
                System.out.println("Id:"+ historicTaskInstance.getId());
                System.out.println("ProcessInstanceId:"+ historicTaskInstance.getProcessInstanceId());
                System.out.println("Name:"+ historicTaskInstance.getName());
            });
}

打印:

Id:561b8715-7421-11ec-80e4-5e879ca31830
ProcessInstanceId:56174151-7421-11ec-80e4-5e879ca31830
Name:发起报销
Id:659387de-7422-11ec-9bf1-5e879ca31830
ProcessInstanceId:56174151-7421-11ec-80e4-5e879ca31830
Name:审核报销

4.10 UEL表达式

  • EL为表达式语言(Expression Language)
  • UEL统一表达式语言(Unified Expression Language)

4.10.1 表达式描述

- 表达式以 "${ " 开始,以 "}" 结束,例如${day > 100}
- 支持逻辑运算 ${userName == "bajie" and pwd == "123" }
- 支持变量与实体类赋值

反复赋值,会覆盖原来值

4.10.2 对应Activiti数据表

  • act_ru_variable 运行时参数表
  • act_hi_varinst 历史参数表

4.10.3 UEL 表达式的保留字和运算符

andeqgt
instanceofdivor
lefalseempty
notLtge
运算符功能示例结果
+${1+1}2
-${1-1}0
*${1*1}4
/ 或div2/1 或 { 2 div 1}2
/ 或div2/0 或 { 2 div 0}Infinity
% 或 mod求余{ 3 % 2 } 或 {3 mod 2}1
% 或 mod求余{ 3 % 0 } 或 {3 mod 0}异常:java.lang.ArithmeticException:/by zero

4.10.4 使用变量指定执行人,去执行任务

4.10.4.1 创建与部署 BPMN

留意画黄色圈圈的位置,命名:Part6_UEL_V1.bpmn20.xml
在这里插入图片描述
com.edcode.activiti.Part1_Deployment#initDeploymentBPMN

/**
* 通过bpmn部署流程
*/
@Test
public void initDeploymentBPMN() {
   String filename = "BPMN/Part6_UEL_V1.bpmn20.xml";
//        String pngname="BPMN/Part1_Deployment.png";
   Deployment deployment = repositoryService.createDeployment()
           .addClasspathResource(filename)
//                .addClasspathResource(pngname)
           .name("流程部署测试UEL_V1")
           .deploy();
   System.out.println(deployment.getName());
}

4.10.4.2 初始化流程实例

com.edcode.activiti.Part6_UEL#initProcessInstanceWithArgs

@Test
public void initProcessInstanceWithArgs() {
    //流程变量
    Map<String, Object> variables = new HashMap<String, Object>();
    variables.put("Executor", "wukong");
    //variables.put("Executor2", "aaa");
    //variables.put("Executor3", "wukbbbong");
    ProcessInstance processInstance = runtimeService
            .startProcessInstanceByKey(
                    "myProcess_UEL_V1"
                    , "bKey002"
                    , variables);
    System.out.println("流程实例ID:" + processInstance.getProcessDefinitionId());
}

启动流程实例带参数,执行执行人

在这里插入图片描述

4.10.5 根据变量条件去指定执行人

4.10.5.1 BPMN 流程图

在这里插入图片描述
需要注意地方,线条位置使用的条件表达式,如果默认的 > 会报错的,推荐使用:<![CDATA[${pay<=100}]]> 写法,类似 Mybatis

在这里插入图片描述

4.10.5.2 启动单元测试流程

  • 创建 BPMN 图
  • 通过bpmn部署流程 # com.edcode.activiti.Part1_Deployment#initDeploymentBPMN
  • 初始化流程实例 # com.edcode.activiti.Part3_ProcessInstance#initProcessInstance
  • 查询我的代办任务,查询 wukong 和 tangseng 有没有代办任务(复制 taskId) # com.edcode.activiti.Part4_Task#getTasksByAssignee
  • 完成任务带参数,指定流程变量测试 (黏贴 taskId) # com.edcode.activiti.Part6_UEL#completeTaskWithArgs

在这里插入图片描述
pay 条件是 101 所以会指向 wukong 来审核

在这里插入图片描述

4.10.6 启动流程实例带参数,使用实体类

4.10.6.1 创建与部署 BPMN

在这里插入图片描述

u e l p o j o . e x e c u t o r 与 " {uelpojo.executor} 与 " uelpojo.executor与"{candidate} 建议都是小写,不然会报错

4.10.6.2 创建一个实体类

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UEL_POJO implements Serializable {

    private static final long serialVersionUID = 3288959023641785980L;

    /**
     * 执行人
     */
    private String executor;

    /**
     * 支付
     */
    private String pay;

}

必需序列化

4.10.6.3 使用实体类入参,在流程实例化

@Test
public void initProcessInstanceWithClassArgs() {

    UEL_POJO uel_pojo = UEL_POJO.builder()
            .executor("bajie")
            .build();

    //流程变量
    Map<String, Object> variables = new HashMap<>();
    variables.put("uelpojo", uel_pojo);

    ProcessInstance processInstance = runtimeService
            .startProcessInstanceByKey(
                    "myProcess_uelv3"
                    , "bKey002"
                    , variables);
    System.out.println("流程实例ID:" + processInstance.getProcessDefinitionId());

}

4.10.6.4 查询我的代办任务

@Test
public void getTasksByAssignee() {
   taskService.createTaskQuery()
           .taskAssignee("bajie")
           .list().forEach(task -> {
               System.out.println("Id:" + task.getId());
               System.out.println("Name:" + task.getName());
               System.out.println("Assignee:" + task.getAssignee());
           });
}
Id:efc7a59c-747f-11ec-965e-5e879ca31830
Name:实体类任务
Assignee:bajie

4.10.7 任务完成环节带参数,指定多个候选人 (实际开发中使用最多一种)

4.10.7.1 指定多个候选人,逗号分隔

@Test
public void initProcessInstanceWithCandiDateArgs() {
    Map<String, Object> variables = new HashMap<>();
    variables.put("candidate", "wukong,tangseng");
    taskService.complete("efc7a59c-747f-11ec-965e-5e879ca31830", variables);
    System.out.println("完成任务");
}

candidate 是在 Part6_UEL_V3.bpmn20.xml 中定义的, 这里含义是:八戒完成任务后,指定候选人为 wukong与tangseng

4.10.7.2 任务查询

com.edcode.activiti.Part4_Task#getTasks

打印的日志

Id:9482408e-7481-11ec-8dd0-5e879ca31830
Name:候选人任务
Assignee:wukong,tangseng

如果 Assignee:null 情况下:就需要调用 【拾取任务 - com/edcode/activiti/Part4_Task.java:61】方式

4.13 流程网关-并行(模拟基础审核流程)

4.13.1 流程网关图标

在这里插入图片描述- 上面章节已经简单描述“排他网关”

4.13.2 网关简述

  并行网关:其实是就是把任务拆分成多路,并把多路任务合并成一路。比较常用,多用于重要的审批环节,需要多人审核的场景。
  排他网关:流程达到排他网关时,按照顺序以及计算条件进行处理,当计算条件返回 true 时,进行下一个环节,没有满足的条件,则抛出异常。如果存在多个条件都满足, 比如:请假 100 天,那么流程既大于3 天,又大于 10天的话,排他网关会根据 BPMN 顺序考前的条件进行执行,也就是说,排他网关只会执行一个条件。
  包容网关 可以理解为可以条件条件的并行网关,而并行网关是不能添加条件的,连几根线就需要几个审批流程,而包容网关可以在每条线路上设置条件,并且可以执行多条线路。
  事件网关:只能连接到事件,并且连接的事件必需大于等于 2 个。

4.13.3 网关比较

  • 包容网关与并行网关比较,是可以设置条件的。
  • 包容网关与排他网关比较
    • 排他网关只能有一个结束环境被启动
    • 包容网关可以有多个环节被启动

4.13.4 并行网关

设计流程图

八戒需要请假,要得到悟空同唐僧审批通过,才能请假
在这里插入图片描述

4.13.5 部署与创建实例化

  • BPMN 部署
  • 创建流程实例
  • 八戒部分
    • 查询我的代办任务 - 【相当于八戒写好请假条】
    • 通过查询 taskId 来完成当前任务 - 【相当于八戒递交请假条】
  • 唐曾部分
    • 查询我的代办任务 - 【相当于八戒的组长】
  • 悟空部分
    • 查询我的代办任务 - 【相当于八戒的主管】

4.13.6 数据库变化

数据库表对照表

ACT_RU_EXECUTION (运行时执行实例表)
在这里插入图片描述

数据3:并行分支数2、流程实例*1

ACT_HI_PROCINST(历史流程实例表)
在这里插入图片描述

数据*1 历史数据

ACT_RU_TASK(运行时任务表)
在这里插入图片描述

数据*2 并行分支数

4.14 流程网关-排他(模拟多人审批的请假流程)

4.14.1 设计流程图

八戒需要请假 101 天
在这里插入图片描述
注意:在 UI 输入条件,大于号、小于号在转换成 xml 的输入报错:

<sequenceFlow id="sid-47545a1e-7496-46c3-90c2-11aa07137fbd" sourceRef="sid-5f397871-48bc-4309-aa86-51299e2c7c2e" targetRef="sid-f7d0a470-2d1e-464e-a874-5346788056f5" name="请假小于等于3天">
  <documentation/>
  <conditionExpression xsi:type="tFormalExpression">${day&lt;=3}</conditionExpression>
</sequenceFlow>

需要修改成:

<sequenceFlow id="sid-47545a1e-7496-46c3-90c2-11aa07137fbd" sourceRef="sid-5f397871-48bc-4309-aa86-51299e2c7c2e" targetRef="sid-f7d0a470-2d1e-464e-a874-5346788056f5" name="请假小于等于3天">
  <documentation/>
  <conditionExpression xsi:type="tFormalExpression">
      <![CDATA[${day<=3}]]>
  </conditionExpression>
</sequenceFlow>

4.14.2 部署与创建实例化

  • BPMN 部署
  • 创建流程实例
  • 八戒部分
    • 查询我的代办任务 - 【相当于八戒写好请假条】
    • 通过查询 taskId 来完成当前任务 - 【相当于八戒递交请假条,需要请假 101天
  • 悟空部分
    • 直接跳过了,少于等于 3 天才找悟空
  • 唐僧部分
    • 大于 3 天,就会到唐僧这里,所以 唐僧会查询到代办任务

4.15 流程网关-包容(升级版的并行网关)

4.15.1 设计流程图

八戒要请假 1 天,按流程图,需要经过沙僧和悟空审批。

在这里插入图片描述

4.15.2 部署与创建实例化

  • BPMN 部署
  • 创建流程实例
  • 八戒部分
    • 查询我的代办任务 - 【相当于八戒写好请假条】
    • 通过查询 taskId 来完成当前任务 - 【相当于八戒递交请假条,需要请假 1 天
  • 沙僧与悟空部分
    • 因为 条件少于 5 天,所以他们都需要审批,然而审批通过了,流程结束
  • 唐僧部分
    • 直接跳过,不满足条件

标签:入门,activiti,流程,System,Activiti7,Aactiviti7,println,public,out
来源: https://blog.csdn.net/eddielee9217/article/details/122426068

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有