SpringBoot 集成 Activiti在線設計器

目錄

 

前言:

源碼:

步驟:

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

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

(3)啓動項目,在瀏覽器上訪問Activiti5.22.0 在線設計器的頁面 

(4)畫流程圖的注意事項

(5)創建一個請假流程

(6)查詢正在運行的請假流程

(7)審覈這個請假流程

(8)查詢當前請假流程狀態

注意事項:

參考文章:

Activit流程實例高亮顯示


前言:

小編 做的這個項目有部分功能用到了 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  我後面將使用這個參數。

 

(7)審覈這個請假流程

代碼:

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

 

這個時候我們可以驗證一下當前這個流程是否 已經執行完,讓我們再執行一下流程執行狀態查詢。

(8)查詢當前請假流程狀態

代碼:

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張表詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章