Activiti7 工作流

Activiti环境


    
        
            org.activiti
            activiti-dependencies
            7.0.0.Beta1
            import
            pom
        
    

1) Database

activiti运行需要有数据库的支持,支持的数据库有:h2, mysql, oracle, postgres, mssql, db2。

 流程设计器IDEA下安装

注意新版idea已经不支持,自己百度下载

搜索到actiBPM插件,它就是Activiti Designer的IDEA版本,我们点击Install安装

Activiti7 工作流_第1张图片

1.pom

首先需要在 java 工程中加入 ProcessEngine 所需要的 jar 包,包括:

1) activiti-engine-7.0.0.beta1.jar2) activiti 依赖的 jar 包: mybatis、 alf4j、 log4j 等

3) activiti 依赖的 spring 包

4) mysql数据库驱动

5) 第三方数据连接池 dbcp6) 单元测试 Junit-4.12.jar


    1.6.6
    1.2.12
    7.0.0.Beta1


    
        org.activiti
        activiti-engine
        ${activiti.version}
    
    
        org.activiti
        activiti-spring
        ${activiti.version}
    
    
    
        org.activiti
        activiti-bpmn-model
        ${activiti.version}
    
    
    
        org.activiti
        activiti-bpmn-converter
        ${activiti.version}
    
    
    
        org.activiti
        activiti-json-converter
        ${activiti.version}
    
    
    
        org.activiti
        activiti-bpmn-layout
        ${activiti.version}
    
    
    
        org.activiti.cloud
        activiti-cloud-services-api
        ${activiti.version}
    
    
    
        mysql
        mysql-connector-java
        5.1.40
    
    
    
        org.mybatis
        mybatis
        3.4.5
    
    
    
        commons-dbcp
        commons-dbcp
        1.4
    
    
        junit
        junit
        4.12
    
    
    
        log4j
        log4j
        ${log4j.version}
    
    
        org.slf4j
        slf4j-api
        ${slf4j.version}
    
    
        org.slf4j
        slf4j-log4j12
        ${slf4j.version}
    

3) 添加log4j日志配置

我们使用log4j日志包,可以对日志进行配置

在resources 下创建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=f:\act\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

4) 添加activiti配置文件

我们使用activiti提供的默认方式来创建mysql的表。

默认方式的要求是在 resources 下创建 activiti.cfg.xml 文件,

注意:默认方式目录和文件名不能修改,因为activiti的源码中已经设置,到固定的目录读取固定文件名的文件



5) 在 activiti.cfg.xml 中进行配置

默认方式要在在activiti.cfg.xml中bean的名字叫processEngineConfiguration,名字不可修改

在这里有2中配置方式:一种是单独配置数据源一种是不单独配置数据源

1、直接配置processEngineConfiguration

processEngineConfiguration 用来创建 ProcessEngine,在创建 ProcessEngine 时会执行数据库的操作

/// 表示本地localhost 



    
    
    
        
        
        
        
        
        
    

2、配置数据源后,在processEngineConfiguration 引用

首先配置数据源




    
    
        
        
        
        
        
        
    

    
        
        
        
 
        
    

6) java类编写程序生成表

创建一个测试类,调用activiti的工具类,生成acitivti需要的数据库表。

直接使用activiti提供的工具类ProcessEngines,会默认读取classpath下的activiti.cfg.xml文件,读取其中的数据库配置,创建 ProcessEngine,在创建ProcessEngine 时会自动创建表。

代码如下:

package com.itheima.activiti01.test;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.junit.Test;

public class TestDemo {
    /**
     * 生成 activiti的数据库表
     */
    @Test
    public void testCreateDbTable() {
        //使用classpath下的activiti.cfg.xml中的配置创建processEngine
		ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
		System.out.println(processEngine);
    }
}

说明:1、运行以上程序段即可完成 activiti 表创建,通过改变 activiti.cfg.xml 中databaseSchemaUpdate 参数的值执行不同的数据表处理策略。2 、 上 边 的 方法 getDefaultProcessEngine方法在执行时,从activiti.cfg.xml 中找固定的名称 processEngineConfiguration 。

在测试程序执行过程中,idea的控制台会输出日志,说明程序正在创建数据表,类似如下,注意红线内容:

Activiti7 工作流_第2张图片

执行完成后我们查看数据库, 创建了 25 张表,结果如下:

Activiti7 工作流_第3张图片

 到这,我们就完成activiti运行需要的数据库和表的创建。

3.4 表结构介绍

3.4.1 表的命名规则和作用

看到刚才创建的表,我们发现Activiti 的表都以 ACT_ 开头。

第二部分是表示表的用途的两个字母标识。 用途也和服务的 API 对应。

ACT_RE :'RE'表示 repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。

ACT_RU:'RU'表示 runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti 只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快

ACT_HI:'HI'表示 history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。

ACT_GE : GE 表示 general。 通用数据, 用于不同场景下

3.4.2 Activiti数据表介绍

表分类 表名 解释
一般数据
[ACT_GE_BYTEARRAY] 通用的流程定义和流程资源
[ACT_GE_PROPERTY] 系统相关属性
流程历史记录
[ACT_HI_ACTINST] 历史的流程实例
[ACT_HI_ATTACHMENT] 历史的流程附件
[ACT_HI_COMMENT] 历史的说明性信息
[ACT_HI_DETAIL] 历史的流程运行中的细节信息
[ACT_HI_IDENTITYLINK] 历史的流程运行过程中用户关系
[ACT_HI_PROCINST] 历史的流程实例
[ACT_HI_TASKINST] 历史的任务实例
[ACT_HI_VARINST] 历史的流程运行中的变量信息
流程定义表
[ACT_RE_DEPLOYMENT] 部署单元信息
[ACT_RE_MODEL] 模型信息
[ACT_RE_PROCDEF] 已部署的流程定义
运行实例表
[ACT_RU_EVENT_SUBSCR] 运行时事件
[ACT_RU_EXECUTION] 运行时流程执行实例
[ACT_RU_IDENTITYLINK] 运行时用户关系信息,存储任务节点与参与者的相关信息
[ACT_RU_JOB] 运行时作业
[ACT_RU_TASK] 运行时任务
[ACT_RU_VARIABLE]

流程定义部署

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

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

act_re_procdef 流程定义表,部署每个新的流程定义都会在这张表中增加一条记录

act_re_procdef 表中的 KEY 这个字段是用来唯一识别不同流程的关键字

act_ge_bytearray 流程资源表

注意:

act_re_deployment和act_re_procdef一对多关系,一次部署在流程部署表生成一条记录,但一次部署可以部署多个流程定义,每个流程定义在流程定义表生成一条记录。每一个流程定义在act_ge_bytearray会存在两个资源记录,bpmn和png。


 

启动流程实例

发起一个请假流程

 /**
     * 启动流程实例
     */
    @Test
    public void testStartProcess(){
//        1、创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        2、获取RunTimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
//        3、根据流程定义Id启动流程
        ProcessInstance processInstance = runtimeService
                .startProcessInstanceByKey("evection");
//        输出内容
        System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
        System.out.println("流程实例id:" + processInstance.getId());
        System.out.println("当前活动Id:" + processInstance.getActivityId());
    

操作数据表

act_hi_actinst 流程实例执行历史(流程节点信息,可以看到流程走到哪里)

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

act_hi_procinst 流程实例历史信息

act_hi_taskinst 流程任务历史信息

act_ru_execution 流程执行信息

act_ru_identitylink 流程运行中的参与用户信息

        字段:userid 是审批人

act_ru_task 流程运行中的任务信息
 

流程任务处理(审批)

任务负责人查询待办任务,选择任务进行处理审批,完成任务。

Activiti7 工作流_第4张图片

 完成任务

// 完成任务
    @Test
    public void completTask(){
//        获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        获取taskService
        TaskService taskService = processEngine.getTaskService();

//        根据流程key 和 任务的负责人 查询任务
//        返回一个任务对象
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("evection") //流程Key
                .taskAssignee("审核人")  //要查询的负责人
                .singleResult();

//        完成任务,参数:任务id
        taskService.complete(task.getId());
    }

流程历史信息的查看

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

    /**
     * 查看历史信息
     */
    @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("myEvection:1:4");
//        增加排序操作,orderByHistoricActivityInstanceStartTime 根据开始时间排序 asc 升序
        instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
//        查询所有内容
        List 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("<==========================>");
        }
    }

新springboot整合

配置Activiti

引入Activiti依赖



    org.activiti
    activiti-spring-boot-starter
    7.1.0.M6
    
        
            mybatis
            org.mybatis
        
    

 

添加配置

application-dev.yml中添加如下配置

spring:    
	activiti:
      #    false:默认,数据库表不变,但是如果版本不对或者缺失表会抛出异常(生产使用)
      #    true:表不存在,自动创建(开发使用)
      #    create_drop: 启动时创建,关闭时删除表(测试使用)
      #    drop_create: 启动时删除表,在创建表 (不需要手动关闭引擎)
      database-schema-update: true
      #监测历史表是否存在,activities7默认不开启历史表
      db-history-used: true
      #none:不保存任何历史数据,流程中这是最高效的
      #activity:只保存流程实例和流程行为
      #audit:除了activity,还保存全部的流程任务以及其属性,audit为history默认值
      #full:除了audit、还保存其他全部流程相关的细节数据,包括一些流程参数
      history-level: full
      #校验流程文件,默认校验resources下的process 文件夹的流程文件
      check-process-definitions: true

重启项目

会自己创建数据表

activiti 常用service服务接口

 Activiti7 工作流_第5张图片

使用activiti插件

下载activiti-explorer

官网下载:Get started | Activiti

 Activiti7 工作流_第6张图片

解压部署

把解压出来的activiti-explorer.war放在Tomcat的webapps

 Activiti7 工作流_第7张图片

 Activiti7 工作流_第8张图片

启动Tomcat服务器

访问activiti-explorer

http://localhost:8080/activiti-explorer

默认登录账号: kermit kermit

Activiti7 工作流_第9张图片

10.2、流程控制

绘制流程

请假流程审批绘制

新建

Activiti7 工作流_第10张图片

 绘制

Activiti7 工作流_第11张图片

 导出

Activiti7 工作流_第12张图片

 下载文件

qingjia.bpmn20.xml



  
    
    
    
    
    
    
    
  
  
    
      
        
      
      
        
      
      
        
      
      
        
      
      
        
        
      
      
        
        
      
      
        
        
      
    
  

下载流程定义图片

单击右键上图图片,图片另存为:qingjia.png

Activiti7 工作流_第13张图片

将资源文件放入项目

在resources下新建process资源文件夹

将qingjia.bpmn20.xml与qingjia.png放入process目录

 部署流程 相当于创建类

 单个文件部署

package com.jerry.auth.activiti;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * ClassName: ProcessTest 
* Package: com.jerry.activiti
* Description: * * @Author: jerry_jy * @Create: 2023-03-05 10:51 * @Version: 1.0 */ @SpringBootTest public class ProcessTest { @Autowired private RepositoryService repositoryService; // 单个文件的部署 @Test public void deployProcess() { Deployment deploy = repositoryService.createDeployment() .addClasspathResource("process/qingjia.bpmn20.xml") .addClasspathResource("process/qingjia.png") .name("请假申请流程") .deploy(); System.out.println("deploy.getId() = " + deploy.getId()); System.out.println("deploy.getName() = " + deploy.getName()); } }

Activiti7 工作流_第14张图片

 压缩包部署

 Activiti7 工作流_第15张图片

 Activiti7 工作流_第16张图片

 流程实例  类(部署)的对象

package com.jerry.auth.activiti;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;



@SpringBootTest
public class ProcessTest1 {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

 


    /**
     * 启动流程实例,添加businessKey  业务标识
     */
    @Test
    public void startUpProcessAddBusinessKey(){
        // 启动流程实例,指定业务标识businessKey,也就是请假申请单id
        ProcessInstance processInstance = runtimeService.
                startProcessInstanceByKey("qingjia","1001");
        // 输出
        System.out.println("业务id:"+processInstance.getBusinessKey()); //1001
        System.out.println("processInstance.getId() = " + processInstance.getId()); // 71f6803b-bb19-11ed-a845-005056c00001
    }

    /**
     * 查询流程定义
     */
    @Test
    public void findProcessDefinitionList(){
        List definitionList = repositoryService.createProcessDefinitionQuery()
                .orderByProcessDefinitionVersion()
                .desc()
                .list();
        //输出流程定义信息
        for (ProcessDefinition processDefinition : definitionList) {
            System.out.println("流程定义 id="+processDefinition.getId());
            System.out.println("流程定义 name="+processDefinition.getName());
            System.out.println("流程定义 key="+processDefinition.getKey());
            System.out.println("流程定义 Version="+processDefinition.getVersion());
            System.out.println("流程部署ID ="+processDefinition.getDeploymentId());
        }
    }

    /**
     * 删除流程定义
     */
    @Test
    public void deleteDeployment() {
        //部署id
        String deploymentId = "qingjia:1:c493c327-bb02-11ed-8360-005056c00001";
//        //删除流程定义,如果该流程定义已有流程实例启动则删除时出错
//        repositoryService.deleteDeployment(deploymentId);
        //设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式
        repositoryService.deleteDeployment(deploymentId, true);
    }

    // 查询已经处理的任务
    @Test
    public void findCompleteTaskList(){
        List list = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee("zhangsan")
                .finished().list();
        for (HistoricTaskInstance historicTaskInstance : list) {
            System.out.println("流程实例id:" + historicTaskInstance.getProcessInstanceId());
            System.out.println("任务id:" + historicTaskInstance.getId());
            System.out.println("任务负责人:" + historicTaskInstance.getAssignee());
            System.out.println("任务名称:" + historicTaskInstance.getName());
        }
    }

    // 处理当前任务
    @Test
    public void completeTask(){
        // 查询负责人需要处理的任务,返回一条
        Task task = taskService.createTaskQuery().taskAssignee("zhangsan").singleResult();
        // 完成任务
        taskService.complete(task.getId());
    }

    // 查询个人的代办任务--zhangsan
    @Test
    public void findTaskList(){
        String assign = "zhangsan";
        List list = taskService.createTaskQuery()
                .taskAssignee(assign).list();
        for (Task task : list) {
            System.out.println("task.getProcessInstanceId() = " + task.getProcessInstanceId());
            System.out.println("任务id:" + task.getId());
            System.out.println("任务负责人:" + task.getAssignee());
            System.out.println("任务名称:" + task.getName());
        }

    }

    // 启动流程实例
    @Test
    public void startProcess(){
        ProcessInstance processInstance = runtimeService.startProcessInstanceById("qingjia");
        System.out.println("processInstance.getProcessDefinitionId() = " + processInstance.getProcessDefinitionId());
        System.out.println("processInstance.getId() = " + processInstance.getId());
        System.out.println("processInstance.getActivityId() = " + processInstance.getActivityId());
    }
    
    //部署
    // 单个文件的部署
    @Test
    public void deployProcess() {
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("process/qingjia.bpmn20.xml")
                .addClasspathResource("process/qingjia.png")
                .name("请假申请流程")
                .deploy();

        System.out.println("deploy.getId() = " + deploy.getId());
        System.out.println("deploy.getName() = " + deploy.getName());
    }
}

 流程实例挂起

Activiti7 工作流_第17张图片

@SpringBootTest
public class ProcessTest1 {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    // 单个流程实例挂起
    @Test
    public void SingleSuspendProcessInstance() {
        //流程实例id
        String processInstanceId = "71f6803b-bb19-11ed-a845-005056c00001";
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        //获取到当前流程定义是否为暂停状态   suspended方法为true代表为暂停   false就是运行的
        boolean suspended = processInstance.isSuspended();
        if (suspended) {
            runtimeService.activateProcessInstanceById(processInstanceId);
            System.out.println("流程实例:" + processInstanceId + "激活");
        } else {
            runtimeService.suspendProcessInstanceById(processInstanceId);
            System.out.println("流程实例:" + processInstanceId + "挂起");
        }
    }


    // 全部流程实例挂起
    @Test
    public void suspendProcessInstance() {

        // 1、获取流程定义对象
        ProcessDefinition qingjia = repositoryService.createProcessDefinitionQuery().processDefinitionKey("qingjia").singleResult();
        // 2、调用流程定义对象的方法判断当前状态:挂起   激活
        boolean suspended = qingjia.isSuspended();
        if (suspended) {
            // 暂定,那就可以激活
            // 参数1:流程定义的id  参数2:是否激活    参数3:时间点
            repositoryService.activateProcessDefinitionById(qingjia.getId(), true, null);
            System.out.println("流程定义:" + qingjia.getId() + "激活");
        } else {
            repositoryService.suspendProcessDefinitionById(qingjia.getId(), true, null);
            System.out.println("流程定义:" + qingjia.getId() + "挂起");
        }
    }
}

任务分配

Activiti7 工作流_第18张图片

 表达式分配

uel-value

 Activiti7 工作流_第19张图片

 Activiti7 工作流_第20张图片

package com.jerry.auth.activiti;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


@SpringBootTest
public class ProcessTest2 {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

 

    // uel-value
    // 部署流程定义
    @Test
    public void deployProcess() {
        Deployment deploy = repositoryService.createDeployment().addClasspathResource("process/jiaban.bpmn20.xml").name("加班申请流程").deploy();
        System.out.println("deploy.getId() = " + deploy.getId()); // 5c5519ad-bb1d-11ed-b5c8-005056c00001
        System.out.println("deploy.getName() = " + deploy.getName()); // 加班申请流程
    }

    // 启动流程实例
    @Test
    public void startProcessInstance() {
        Map map = new HashMap<>();
        // 设置任务人
        map.put("assignee1","tom");
        map.put("assignee2","jerry");
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban", map);

        System.out.println("processInstance.getProcessDefinitionId() = " + processInstance.getProcessDefinitionId()); // jiaban:1:5c60d97f-bb1d-11ed-b5c8-005056c00001

        System.out.println("processInstance.getId() = " + processInstance.getId()); // 7f720dd9-bb1d-11ed-b6e9-005056c00001
    }

    // 查询个人的代办任务--tom
    @Test
    public void findTaskList(){
        String assign = "tom";
        List list = taskService.createTaskQuery()
                .taskAssignee(assign).list();
        for (Task task : list) {
            System.out.println("task.getProcessInstanceId() = " + task.getProcessInstanceId()); //7f720dd9-bb1d-11ed-b6e9-005056c00001
            System.out.println("任务id:" + task.getId()); // 7f759051-bb1d-11ed-b6e9-005056c00001
            System.out.println("任务负责人:" + task.getAssignee()); // tom
            System.out.println("任务名称:" + task.getName()); // 经理审批
        }
    }

}

 uel-method表达式

Activiti7 工作流_第21张图片

 Activiti7 工作流_第22张图片

 Activiti7 工作流_第23张图片

 Activiti7 工作流_第24张图片

package com.jerry.auth.activiti;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


@SpringBootTest
public class ProcessTest2 {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

  
    // uel-method
    // 部署流程定义
    @Test
    public void deployProcess01() {
        Deployment deploy = repositoryService.createDeployment().addClasspathResource("process/jiaban01.bpmn20.xml").name("加班申请流程01").deploy();
        System.out.println("deploy.getId() = " + deploy.getId()); // 8c4ac05e-bb20-11ed-8d65-005056c00001
        System.out.println("deploy.getName() = " + deploy.getName()); // 加班申请流程01
    }
    
   //创建流程实例,会自动调用userBean.getUserName()方法
    @Test
    public void startProcessInstance01(){
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban01");
        System.out.println("processInstance.getProcessDefinitionId() = " + processInstance.getProcessDefinitionId()); // jiaban01:1:8c56a740-bb20-11ed-8d65-005056c00001
        System.out.println("processInstance.getId() = " + processInstance.getId()); // abb9c7c4-bb20-11ed-b608-005056c00001
    }

    // 查询个人的代办任务--zhangsan
    @Test
    public void findTaskList01(){
        String assign = "zhangsan";
        List list = taskService.createTaskQuery()
                .taskAssignee(assign).list();
        for (Task task : list) {
            System.out.println("task.getProcessInstanceId() = " + task.getProcessInstanceId()); // abb9c7c4-bb20-11ed-b608-005056c00001
            System.out.println("任务id:" + task.getId()); // abbd4a38-bb20-11ed-b608-005056c00001
            System.out.println("任务负责人:" + task.getAssignee()); // LiLei
            System.out.println("任务名称:" + task.getName()); // 经理审批
        }
    }

   

}

 监听器分配

Activiti7 工作流_第25张图片

 Activiti7 工作流_第26张图片

 Activiti7 工作流_第27张图片

 Activiti7 工作流_第28张图片

配置监听器

package com.jerry.auth.activiti;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


@SpringBootTest
public class ProcessTest2 {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    ///
    // 监听器分配任务
    // 部署流程定义
    @Test
    public void deployProcess02() {
        Deployment deploy = repositoryService.createDeployment().addClasspathResource("process/jiaban02.bpmn20.xml").name("加班申请流程02").deploy();
        System.out.println("deploy.getId() = " + deploy.getId()); // ed080f00-bb41-11ed-a6f2-005056c00001
        System.out.println("deploy.getName() = " + deploy.getName()); // 加班申请流程02
    }

    @Test
    public void startProcessInstance02(){
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban02");
        System.out.println("processInstance.getProcessDefinitionId() = " + processInstance.getProcessDefinitionId()); // jiaban02:1:ed150752-bb41-11ed-a6f2-005056c00001
        System.out.println("processInstance.getId() = " + processInstance.getId()); // 06eca124-bb42-11ed-9bbc-005056c00001
    }


    // 查询个人的代办任务--Tim
    @Test
    public void findTaskList02(){
        String assign = "Tim";
        List list = taskService.createTaskQuery()
                .taskAssignee(assign).list();
        for (Task task : list) {
            System.out.println("task.getProcessInstanceId() = " + task.getProcessInstanceId()); // 06eca124-bb42-11ed-9bbc-005056c00001
            System.out.println("任务id:" + task.getId()); // 06f071b8-bb42-11ed-9bbc-005056c00001
            System.out.println("任务负责人:" + task.getAssignee()); // Tim
            System.out.println("任务名称:" + task.getName()); // 经理审批
        }
    }

   

}

 流程变量

Activiti7 工作流_第29张图片

 Activiti7 工作流_第30张图片

 Activiti7 工作流_第31张图片

 Activiti7 工作流_第32张图片

 Activiti7 工作流_第33张图片

任务组

Activiti7 工作流_第34张图片

 Activiti7 工作流_第35张图片

 Activiti7 工作流_第36张图片

 

package com.jerry.auth.activiti;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ClassName: ProcessTest3 
* Package: com.jerry.auth.activiti
* Description: * * @Author: jerry_jy * @Create: 2023-03-05 19:18 * @Version: 1.0 */ @SpringBootTest public class ProcessTest3 { @Autowired private RepositoryService repositoryService; @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; // 1、部署流程定义 @Test public void deployProcess() { Deployment deploy = repositoryService.createDeployment().addClasspathResource("process/jiaban04.bpmn20.xml").name("加班申请流程04").deploy(); System.out.println("deploy.getId() = " + deploy.getId()); // f204be8a-bb48-11ed-950e-005056c00001 System.out.println("deploy.getName() = " + deploy.getName()); // 加班申请流程04 } // 1.5、启动流程实例 @Test public void startProcessInstance() { // Map map = new HashMap<>(); // 设置任务人 // map.put("assignee1","tom"); // map.put("assignee2","jerry"); ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban04"); System.out.println("processInstance.getProcessDefinitionId() = " + processInstance.getProcessDefinitionId()); // jiaban04:1:f210f38c-bb48-11ed-950e-005056c00001 System.out.println("processInstance.getId() = " + processInstance.getId()); // 428d0c0f-bb49-11ed-83a5-005056c00001 } // 2、查询组任务 @Test public void findGroupTaskList(){ List list = taskService.createTaskQuery() .taskCandidateUser("tom01") .list(); for (Task task : list) { System.out.println("----------------------------"); System.out.println("流程实例id:" + task.getProcessInstanceId()); System.out.println("任务id:" + task.getId()); System.out.println("任务负责人:" + task.getAssignee()); System.out.println("任务名称:" + task.getName()); } } // 3、分配组任务,拾取任务,让某人去做这个事情 @Test public void claimTask(){ Task task = taskService.createTaskQuery() .taskCandidateUser("tom01") .singleResult(); if (task!=null){ taskService.claim(task.getId(),"tom"); System.out.println("分配任务完成/任务拾取完成"); } } // 4、查询个人的代办任务--tom01 @Test public void findTaskList(){ String assign = "tom01"; List list = taskService.createTaskQuery() .taskAssignee(assign).list(); for (Task task : list) { System.out.println("task.getProcessInstanceId() = " + task.getProcessInstanceId()); //7f720dd9-bb1d-11ed-b6e9-005056c00001 System.out.println("任务id:" + task.getId()); // 7f759051-bb1d-11ed-b6e9-005056c00001 System.out.println("任务负责人:" + task.getAssignee()); // tom System.out.println("任务名称:" + task.getName()); // 经理审批 } } // 5、办理个人任务 @Test public void completeGroupTask() { Task task = taskService.createTaskQuery() .taskAssignee("tom01") //要查询的负责人 .singleResult();//返回一条 taskService.complete(task.getId()); } }

 

 Activiti7 工作流_第37张图片

 Activiti7 工作流_第38张图片

10.3、网关

网关用来控制流程的流向,通常会和流程变量一起使用。

排他网关

  • 排他网关:只有一条路径会被选择

当你的流程出现这样的场景:请假申请,两天以内,部门经理审批流程就结束了,两天以上需要总经理直接审批,这个时候就需要排他网关

Activiti7 工作流_第39张图片

Activiti7 工作流_第40张图片

 Activiti7 工作流_第41张图片

并行网关

  • 并(平)行网关:所有路径会被同时选择

当出现这样的场景:请假申请开始,需要部门经理和总经理都审批,两者没有前后需要两个人全部审批才能进入下个节点人事审批。这个时候就需要并行网关

Activiti7 工作流_第42张图片

与排他网关的主要区别是,并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略。

包含网关


包容网关:可以同时执行多条线路,也可以在网关上设置条件,可以看做是排他网关和并行网关的结合体。
当出现这样的场景:请假申请大于等于2天需要由部门总经理审批,小于2天由部门经理审批,请假申请必须经过人事经理审批。这个时候就需要包含网关
Activiti7 工作流_第43张图片

package com.jerry.auth.activiti;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


@SpringBootTest
public class ProcessTestGateway {

    @Autowired
    private RepositoryService repositoryService;

    //注入RuntimeService
    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    //1 部署流程定义
    @Test
    public void deployProcess() {
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("process/qingjia003.bpmn20.xml")
                .name("请假申请流程003")
                .deploy();
        System.out.println(deployment.getId()); // af9242f0-bb4c-11ed-85bf-005056c00001
        System.out.println(deployment.getName()); // 请假申请流程002
    }

    //2 启动流程实例
    @Test
    public void startProcessInstance() {
        Map map = new HashMap<>();
        //设置请假天数
        map.put("day", "3");

        ProcessInstance processInstance =
//                runtimeService.startProcessInstanceByKey("qingjia002", map);
                runtimeService.startProcessInstanceByKey("qingjia003");
        System.out.println(processInstance.getProcessDefinitionId()); // qingjia002:1:afac0c82-bb4c-11ed-85bf-005056c00001
        System.out.println(processInstance.getId()); // 90d46e2c-bb4d-11ed-9b92-005056c00001
    }

    //3 查询个人的代办任务--zhao6
    @Test
    public void findTaskList() {

//        String assign = "zhao6";
//        String assign = "gousheng";
//        String assign = "xiaocui";
//        String assign = "wang5";
//        String assign = "gouwa";
        String assign = "xiaoli";
        List list = taskService.createTaskQuery()
                .taskAssignee(assign).list();
        for (Task task : list) {
            System.out.println("流程实例id:" + task.getProcessInstanceId());
            System.out.println("任务id:" + task.getId());
            System.out.println("任务负责人:" + task.getAssignee());
            System.out.println("任务名称:" + task.getName());
        }
    }

    //完成任务
    @Test
    public void completeTask() {
        Task task = taskService.createTaskQuery()
//                .taskAssignee("zhao6")  //要查询的负责人
//                .taskAssignee("xiaocui")  //要查询的负责人
//                .taskAssignee("gousheng")
//                .taskAssignee("wang5")
                .taskAssignee("gouwa")
                .singleResult();//返回一条

        //完成任务,参数:任务id
            taskService.complete(task.getId());
    }
}

Activiti7 工作流_第44张图片

 11、审批管理

Activiti7 工作流_第45张图片

 11.1、审批设置–CRUD

package com.jerry.process.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jerry.common.result.Result;
import com.jerry.model.process.ProcessType;
import com.jerry.process.service.OaProcessTypeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

/**
 * 

* 审批类型 前端控制器 *

* * @author jerry * @since 2023-03-05 */ @Api(value = "审批类型", tags = "审批类型") @RestController @RequestMapping(value = "/admin/process/processType") public class OaProcessTypeController { @Autowired private OaProcessTypeService processTypeService; @ApiOperation(value = "获取分页列表") @GetMapping("{page}/{pageSize}") public Result index(@PathVariable Long page, @PathVariable Long pageSize) { Page pageInfo = new Page<>(page, pageSize); Page pageModel = processTypeService.page(pageInfo); return Result.ok(pageModel); } @PreAuthorize("hasAuthority('bnt.processType.list')") @ApiOperation(value = "获取") @GetMapping("get/{id}") public Result get(@PathVariable Long id) { ProcessType processType = processTypeService.getById(id); return Result.ok(processType); } @PreAuthorize("hasAuthority('bnt.processType.add')") @ApiOperation(value = "新增") @PostMapping("save") public Result save(@RequestBody ProcessType processType) { processTypeService.save(processType); return Result.ok(); } @PreAuthorize("hasAuthority('bnt.processType.update')") @ApiOperation(value = "修改") @PutMapping("update") public Result updateById(@RequestBody ProcessType processType) { processTypeService.updateById(processType); return Result.ok(); } @ApiOperation(value = "删除") @DeleteMapping("remove/{id}") public Result remove(@PathVariable Long id) { processTypeService.removeById(id); return Result.ok(); } }

Activiti7 工作流_第46张图片

 11.2、模板审批–CRUD

package com.jerry.process.controller;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jerry.common.result.Result;
import com.jerry.model.process.ProcessTemplate;
import com.jerry.process.service.OaProcessTemplateService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * 

* 审批模板 前端控制器 *

* * @author jerry * @since 2023-03-05 */ @Api(value = "审批模板管理", tags = "审批模板管理") @RestController @RequestMapping(value = "/admin/process/processTemplate") public class OaProcessTemplateController { @Autowired private OaProcessTemplateService processTemplateService; // 分页查询审批模板 @ApiOperation("获取分页查询审批模板数据") @GetMapping("{page}/{pageSize}") public Result index(@PathVariable Long page, @PathVariable Long pageSize){ Page pageInfo = new Page<>(page, pageSize); //分页查询审批模板,把审批类型对应名称查询 IPage pageModel = processTemplateService.selectPageProcessTemplate(pageInfo); return Result.ok(pageModel); } //@PreAuthorize("hasAuthority('bnt.processTemplate.list')") @ApiOperation(value = "获取") @GetMapping("get/{id}") public Result get(@PathVariable Long id) { ProcessTemplate processTemplate = processTemplateService.getById(id); return Result.ok(processTemplate); } //@PreAuthorize("hasAuthority('bnt.processTemplate.templateSet')") @ApiOperation(value = "新增") @PostMapping("save") public Result save(@RequestBody ProcessTemplate processTemplate) { processTemplateService.save(processTemplate); return Result.ok(); } //@PreAuthorize("hasAuthority('bnt.processTemplate.templateSet')") @ApiOperation(value = "修改") @PutMapping("update") public Result updateById(@RequestBody ProcessTemplate processTemplate) { processTemplateService.updateById(processTemplate); return Result.ok(); } //@PreAuthorize("hasAuthority('bnt.processTemplate.remove')") @ApiOperation(value = "删除") @DeleteMapping("remove/{id}") public Result remove(@PathVariable Long id) { processTemplateService.removeById(id); return Result.ok(); } }

11.3、添加审批模板

OaProcessTypeController


    @ApiOperation(value = "获取全部审批分类")
    @GetMapping("findAll")
    public Result findAll() {
        return Result.ok(processTypeService.list());
    }

OaProcessTemplateController


    @ApiOperation(value = "上传流程定义")
    @PostMapping("/uploadProcessDefinition")
    public Result uploadProcessDefinition(MultipartFile file) throws FileNotFoundException {

        // 获取classes目录位置
        String path = new File(ResourceUtils.getURL("classpath:").getPath()).getAbsolutePath();
        // 设置上传文件夹
        File tempFile = new File(path + "/processes/");
        if (!tempFile.exists()) {
            tempFile.mkdirs();
        }
        // 创建空文件,实现文件写入
        String filename = file.getOriginalFilename();
        File zipFile = new File(path + "/processes/" + filename);

        // 保存文件
        try {
            file.transferTo(zipFile);
        } catch (IOException e) {
           return Result.fail();
        }

        Map map = new HashMap<>();
        //根据上传地址后续部署流程定义,文件名称为流程定义的默认key
        map.put("processDefinitionPath", "processes/" + filename);
        map.put("processDefinitionKey", filename.substring(0, filename.lastIndexOf(".")));
        return Result.ok(map);
    }


    public static void main(String[] args) {
        try {
            String path = new File(ResourceUtils.getURL("classpath:").getPath()).getAbsolutePath();
            System.out.println("path = " + path); //E:\CodeLife\IdeaProject\guigu-oa\guigu-oa-parent\service-oa\target\classes
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

Activiti7 工作流_第47张图片

11.4、查看审批模板

整合前端,无后台接口

Activiti7 工作流_第48张图片

 11.5、审批列表

分页查询

OaProcessController

package com.jerry.process.controller;


import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jerry.common.result.Result;
import com.jerry.model.process.Process;
import com.jerry.process.service.OaProcessService;
import com.jerry.vo.process.ProcessQueryVo;
import com.jerry.vo.process.ProcessVo;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

/**
 * 

* 审批类型 前端控制器 *

* * @author jerry * @since 2023-03-06 */ @RestController @RequestMapping(value = "/admin/process") public class OaProcessController { @Autowired private OaProcessService processService; //审批管理列表 @ApiOperation(value = "获取分页列表") @GetMapping("{page}/{limit}") public Result index(@PathVariable Long page, @PathVariable Long limit, ProcessQueryVo processQueryVo) { Page pageInfo = new Page<>(page, limit); IPage pageModel = processService.selectPage(pageInfo,processQueryVo); return Result.ok(); } }

OaProcessService

public interface OaProcessService extends IService {

    //审批管理列表
    IPage selectPage(Page pageInfo, ProcessQueryVo processQueryVo);
}

OaProcessServiceImpl

    //审批管理列表
    @Override
    public IPage selectPage(Page pageInfo, ProcessQueryVo processQueryVo) {
        IPage pageModel =  baseMapper.selectPage(pageInfo,processQueryVo);
        return pageModel;
    }

OaProcessMapper

    //审批管理列表
    IPage selectPage(Page pageInfo, @Param("vo") ProcessQueryVo processQueryVo);

涉及到4张表的多表查询,自己编写SQL语句

OaProcessMapper.xml





    

修改mapper的映射路径

Activiti7 工作流_第49张图片

 页面展示

Activiti7 工作流_第50张图片

部署流程定义

OaProcessTemplateServiceImpl

    // 修改模板的发布状态 status==1 代表已发布
    // 流程定义部署
    @Override
    public void publish(Long id) {
        // 修改模板的发布状态 status==1 代表已发布
        ProcessTemplate processTemplate = baseMapper.selectById(id);
        processTemplate.setStatus(1);
        baseMapper.updateById(processTemplate);

        // 流程定义部署
        if (StringUtils.isEmpty(processTemplate.getProcessDefinitionPath())){
            processService.deployByZip(processTemplate.getProcessDefinitionPath());
        }
    }
}

OaProcessService

    // 流程定义部署
    void deployByZip(String deployPath);

OaProcessServiceImpl

    // 流程定义部署
    @Override
    public void deployByZip(String deployPath) {
        InputStream inputStream= this.getClass().getClassLoader().getResourceAsStream(deployPath);
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        // 部署
        Deployment deployment = repositoryService.createDeployment().addZipInputStream(zipInputStream).deploy();

        System.out.println("deployment.getId() = " + deployment.getId());
        System.out.println("deployment.getName() = " + deployment.getName());
    }

12、前端审批

12.1、OA审批

Activiti7 工作流_第51张图片

 activiti-explorer整合到项目中

Springboot2.0与activiti-explorer5.23.0整合,从0开始构建自己的工作流编辑平台(附件 ***) - 灰信网(软件开发博客聚合)

解压,如图:

Activiti7 工作流_第52张图片

 

B) 将DIAGRAM-VIEWEREDITOR-APPMODELER.HTML三个文件复制到SPRINGBOOT的项目

在Springboot的项目的resource目录的static文件夹下新建一个activiti-explorer文件夹。(此处根据自己要求是否新建文件夹)

Activiti7 工作流_第53张图片

 Activiti7 工作流_第54张图片

 

复制配置文件STENCILSET.JSON到SPRINGBOO项目

stencilset.json在activiti-webapp-explorer2-5.23.0.war的文件夹下路径:

 Activiti7 工作流_第55张图片

 Activiti7 工作流_第56张图片

 Activiti7 工作流_第57张图片

 Activiti7 工作流_第58张图片

 Activiti7 工作流_第59张图片

 

 Activiti7 工作流_第60张图片

 于是手动编写一个初始化模型数据类如下:

 

 
import java.io.IOException;
import java.io.UnsupportedEncodingException;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Model;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
 
@Controller
@RequestMapping("/models")
public class TestActivitiController {
 
	private static final Logger LOGGER = LoggerFactory.getLogger(TestActivitiController.class);
 
	@Autowired
	private RepositoryService repositoryService;
	@Autowired
	private ObjectMapper objectMapper;
 
	@RequestMapping("/create")
	public void newModel(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
		try {
			// 初始化一个空模型
			Model model = repositoryService.newModel();
 
			// 设置一些默认信息
			String name = "new-process";
			String description = "";
			int revision = 1;
			String key = "process";
 
			ObjectNode modelNode = objectMapper.createObjectNode();
			modelNode.put(ModelDataJsonConstants.MODEL_NAME, name);
			modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
			modelNode.put(ModelDataJsonConstants.MODEL_REVISION, revision);
 
			model.setName(name);
			model.setKey(key);
			model.setMetaInfo(modelNode.toString());
 
			repositoryService.saveModel(model);
			String id = model.getId();
 
			// 完善ModelEditorSource
			ObjectNode editorNode = objectMapper.createObjectNode();
			editorNode.put("id", "canvas");
			editorNode.put("resourceId", "canvas");
			ObjectNode stencilSetNode = objectMapper.createObjectNode();
			stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
			editorNode.put("stencilset", stencilSetNode);
			repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));
 
			response.sendRedirect(request.getContextPath() + "/static/modeler.html?modelId=" + id);
		} catch (IOException e) {
			e.printStackTrace();
			LOGGER.info("模型创建失败!");
		}
 
	}
 
}

同时加上Bean的扫描路径注解:

@SpringBootApplication(scanBasePackages = { "org.activiti.rest", "hu.itget" }, exclude = {
		org.activiti.spring.boot.SecurityAutoConfiguration.class,
		org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class })

Activiti7 工作流_第61张图片

 Activiti7 工作流_第62张图片

 Activiti7 工作流_第63张图片

 

你可能感兴趣的:(工具,java,java,后端)