SpringBoot 集成 Activiti在线设计器

目录

 

前言:

源码:

步骤:

(1)新建一个SpringBoot项目,引入 Activti5.22.0 的jar 文件,生成23张工作流的表

(2) 引入Activiti 5.22.0 所需的文件

(3)启动项目,在浏览器上访问Activiti5.22.0 在线设计器的页面 

(4)画流程图的注意事项

(5)创建一个请假流程

(6)查询正在运行的请假流程

(6)审核这个请假流程

(7)查询当前请假流程状态

注意事项:

参考文章:


前言:

小编 做的这个项目有部分功能用到了 Activiti工作流,目前对工作流的掌握程度是基本会用,我之前写过一篇 Activiti 入门篇,当前这篇文章是属于Activiti 实战部分,如果你想知道Activiti 工作流是如何使用的话,那就随着小编一起看下去吧!

源码:

所有源码我会放到网盘里面,欢迎大家下载。

链接:https://pan.baidu.com/s/18TentJlrLNflNAcgJDnAtQ 
提取码:9q19

步骤:

(1)新建一个SpringBoot项目,引入 Activti5.22.0 的jar 包,生成23张工作流的表

  • 1.1 pom 文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>activiti-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>activiti-demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--Spring data JPA-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- MySQL start -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.39</version>
        </dependency>

        <!-- spring boot start -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- activiti start -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-engine</artifactId>
            <version>5.22.0</version>
        </dependency>

        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter-basic</artifactId>
            <version>5.22.0</version>
        </dependency>

        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-json-converter</artifactId>
            <version>5.22.0</version>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-explorer</artifactId>
            <version>5.22.0</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-simple-workflow</artifactId>
            <version>5.22.0</version>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring</artifactId>
            <version>5.22.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-codec</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-css</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-svg-dom</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.xmlgraphics</groupId>
            <artifactId>batik-svggen</artifactId>
            <version>1.7</version>
        </dependency>
        <!-- activiit end-->
        <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>
        </plugins>
    </build>

</project>
  • 1.2  引入生成数据库表的文件,
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!--配置流程引擎配置对象-->
    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
        <property name="jdbcDriver"  value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql://192.168.20.81:3306/activiti_demo"/>
        <property name="jdbcUsername" value="root" />
        <property name="jdbcPassword" value="root" />
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</beans>
  • 1.3 启动这个项目,就可以生成工作流的表

如下图所示,我还创建一个了activiti_demo 的数据库 

新建23张表的时候,会往 act_ge_property 中新增3条数据

(2) 引入Activiti 5.22.0 所需的文件

  • 2.1 整个项目路径如下图所示:

   static 文件夹下 是activiti5.22.0 的静态资源文件 

  • 2.2  工作流模型创建的接口
package com.example.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.io.UnsupportedEncodingException;
import java.util.List;

/**
 * 工作流前端化的controller(新建)
 *
 * @Author: tanghh
 */

@RequestMapping("/activiti")
@RestController
public class ActivitiController {

    private static Logger logger=LoggerFactory.getLogger(ActivitiController.class);
    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private ObjectMapper objectMapper;



    @ResponseBody
    public String newMode() {
        return "spring-boot";
    }



    /**
     * 根据Model部署流程
     */
    @PostMapping(value = "deploy/{modelId}")
    public void deploy(@PathVariable("modelId") String modelId) {
        try {
            Model modelData = repositoryService.getModel(modelId);
            ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
            byte[] bpmnBytes = null;

            BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
            bpmnBytes = new BpmnXMLConverter().convertToXML(model);

            String processName = modelData.getName() + ".bpmn20.xml";
            List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().processDefinitionResourceName(processName).list();
            for (ProcessDefinition definition:list){
                //删除原有流程定义,正在使用的流程定义无法删除
                repositoryService.deleteDeployment(definition.getDeploymentId());
            }
            Deployment deployment = repositoryService.createDeployment().name(modelData.getName()).addString(processName, new String(bpmnBytes)).deploy();
            System.out.println("流程部署id----"+deployment.getId());
        } catch (Exception e) {
            logger.error("根据模型部署流程失败:modelId={}", modelId, e);
        }
    }

    /**
     * 新建模型
     * @return
     * @throws UnsupportedEncodingException
     */
    @GetMapping("/create")
    public ModelAndView newModel() throws UnsupportedEncodingException {
//    	ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//    	RepositoryService repositoryService = processEngine.getRepositoryService();
//    	ObjectMapper objectMapper = new ObjectMapper();
        //初始化一个空模型
        Model model = repositoryService.newModel();

        //设置一些默认信息,可以用参数接收
        int revision = 1;
        String key = "process";
        String name = "process";
        String description = "新建流程模型";

        //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);


        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();

        repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));
        return new ModelAndView("redirect:/modeler.html?modelId=" + id);
    }
}

(3)启动项目,在浏览器上访问Activiti5.22.0 在线设计器的页面 

 在浏览器上访问这个路径: http://localhost:8005/activiti/create

  

(4)画流程图的注意事项

  • 4.1 像这种设计器一般情况都是可以拖拽的,如下图我就是鼠标放到开始事件上 ,拖到右边界面上

  • 4.2 点击 我标注的那个人头 ,就可以创建像我左边那样的 发起请假流程的框 

  • 4.3 画流程图的时候 鼠标箭头要对准 这些红点点,不要留有空隙,不然创建流程实例的时候会报错

箭头最好是可以多拖拽一点,不然会报下面这个错。 

  • 4.4  如何给一个任务一个名字 ,可以在我下图中标注的地方 填写

  • 4.5 定义一个审核人

  •  4.6 俩个跳转条件(驳回 和同意)

 

  • 4.7 最终画出来的请假流程如下图:

小编画的不咋好看, 你也可以按照你喜欢的来调

  •  4.8 点击保存这个流程

点击 图标出来的界面:

  • 4.9 需要注意的一个点: 

注意: 1 这是流程id  是唯一的 ,后面我们创建流程实例 ,要基于这个流程id 来创建。

  •  4.10 创建一个流程添加数据

创建一个模型的时候,会往 act_re_model中添加一条数据,

act_ge_ bytearray 中添加数据

 

(5)创建一个请假流程

  • 5.1 创建一个请假流程实例:

代码:

TestActivitiController 类
    @Autowired
    private ActivitiService activitiService;
    /**
     * 1.创建一个流程实例
     */
    @GetMapping(value = "/createLeaveFlow")
    public void createLeaveFlow() throws IOException {
        //1.举个例子,soup_tang 需要请假 ,我在页面上添加请假申请,任务申请人是soup_tang,
        // 我选择审核人为汤总,请汤总给我审核这个请假流程。
        String checkPeople = "汤总";
        activitiService.createLeaveWorkFlow(checkPeople);
    }
ActivitiService 类
 @Override
    public void createLeaveWorkFlow(String checkPeople) throws IOException {
            //先判断这个流程文件有没有部署(只需部署一次)
            Model modelData = repositoryService.getModel("1");
            ObjectNode modelNode = (ObjectNode) new ObjectMapper()
                    .readTree(repositoryService.getModelEditorSource(modelData.getId()));
            byte[] bpmnBytes = null;
            BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(modelNode);
            bpmnBytes = new BpmnXMLConverter().convertToXML(bpmnModel);

            String processName = modelData.getName() + ".bpmn20.xml";

            Deployment deployment = repositoryService.createDeployment()
                    .name(modelData.getName()).addString(processName, new String(bpmnBytes, "UTF-8"))
                    .deploy();
            //获取流程定义
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
            //启动流程定义,返回流程实例
            Map<String,Object> map = new HashMap<>();
            map.put("checkPeople",checkPeople);
            ProcessInstance pi = runtimeService.startProcessInstanceById(processDefinition.getId(),map);
            System.out.println("流程定义的ID:" + pi.getProcessDefinitionId());
            System.out.println("流程实例的ID:" + pi.getId());

    }

浏览器上访问 http://localhost:8005/createLeaveFlow

就会往正在运行的表中生成数据

正在运行的参数表 

 

(6)查询正在运行的请假流程

代码:

TestActivitiController

    /**
     * 3.查询正在运行的实例
     */
    @GetMapping(value = "/listLeaveFlow")
    public void listLeaveFlow()  {
        activitiService.queryExcution();
    }

ActivitiService

  /**
     * 查询正在运行的实例
     */
    @Override
    public void queryExcution() {
        //创建正在执行的流程查询对象
        List<Execution> executionList = runtimeService.createExecutionQuery()
                .list();  //查询出集合
        for(Execution execution: executionList){
            System.out.println("正在执行的流程对象的id: "+execution.getId());
            System.out.println("所属流程实例的id:"+execution.getProcessInstanceId());
            System.out.println("正在活动的节点的id: "+execution.getActivityId());
        }
    }

浏览器上访问:http://localhost:8005/listLeaveFlow

其中比较重要的就是这个流程实例id  2507  我后面将使用这个参数。

(6)审核这个请假流程

代码:

TestActivitiController类
    /**
     * 2.执行完 第一个方法的创建流程以后,就要执行下面这个审核方法
     * @throws IOException
     */
    @GetMapping(value = "/assginLeaveFlow")
    public void assginLeaveFlow()  {
        //1.当汤总 登录系统的时候,他需要审核一些 审核人为他的 请假流程,当然了,我们在创建这个请假流程的时候,
        //我这个审核人就是可以动态赋值的
        //2.这个是流程实例id ,每次创建一个工作流,都会生成,在具体的生产环境中我们需要将这个流程实例id保存起来。(2507 可能需要替换喔 切记。)
        String processInstanceId = "2507";
        //3.这个是审核人是否同意当前这个流程。(0代表同意 1代表不同意)
        int isAcceppt = 0;
        //4.这个是当前审核人
        String checkPeople = "汤总";
        activitiService.assginLeaveWorkFlow(processInstanceId,isAcceppt,checkPeople);
    }

 ActivitiService类

 @Override
    public void assginLeaveWorkFlow(String processInstanceId,int isAccept,String checkPeople) {
        Map<String,Object> map = new HashMap<>();
        //得到当前实例下的task
        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
        taskService.addComment(task.getId(), processInstanceId, "审核人是否同意该请假流程");
        if(isAccept == 0){
            System.out.println("审核人同意了该请求");
            map.put("accept","同意");
            task.setAssignee(checkPeople);
            map.put("checkPeople", checkPeople);
        }else{
            System.out.println("审核人驳回了该请求");
            map.put("accept","驳回");
            //审核驳回后
            task.setAssignee("soup_tang");
            map.put("auditor","soup_tang");
        }
        task.setDescription("请假的描述信息");
        //执行当前这个工作流任务
        taskService.saveTask(task);
        taskService.complete(task.getId(), map);
    }

浏览上访问:http://localhost:8005/assginLeaveFlow

 

这个时候我们可以验证一下当前这个流程是否 已经执行完,让我们再执行一下流程执行状态查询。

(7)查询当前请假流程状态

代码:

TestActiviController

   /**
     * 3.查询正在运行的实例
     */
    @GetMapping(value = "/getLeaveFlowByProccessInstanceId")
    public void getLeaveFlowByProccessInstanceId()  {
        String proccessInstanceId = "2507";
        activitiService.queryProccessInstanceState(proccessInstanceId);
    }

ActivitiService

  @Override
    public void  queryProccessInstanceState(String proccessInstanceId) {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(proccessInstanceId).singleResult();
        if (processInstance == null) {
            System.out.println("当前流程已经完成");
        } else {
            System.out.println("当前流程实例ID:" + processInstance.getId());
            System.out.println("当前流程所处的位置:" + processInstance.getActivityId());
        }
    }

浏览器上访问:http://localhost:8005/getLeaveFlowByProccessInstanceId

注意事项:

1.我在测试的时候,发现当一个流程执行完以后,对应的 act_ru_task当中的数据也会被清空掉,数据会保存到 hi开头的表中。

2.其中比较重要的就是这个流程实例id  2507  我后面将使用这个参数。

3.我目前使用的是Activiti5.22.0 版本。

4.这篇文章写不下了,下篇文章 我会介绍如何高亮显示一个工作流实例,以及查询历史任务,以及 如何挂起,激活,删除一个流程,敬请期待。

参考文章:

Activiti工作流之任务的运行/查询/完成

SpringBoot集成Activiti之在线设计器 狂飙的蜗牛_013dpringBoot 集成Activi之在线设计器

Activiti23张表详解

发布了68 篇原创文章 · 获赞 55 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/tangthh123/article/details/105120702