activiti6.0入門(四)-簡單demo示例講解

相信通過前面的學習,你已經瞭解到activiti繪製圖案的幾個概念,比如監聽器,提交表單屬性,路線分發(根據參數條件),如果你看到這幾個字眼特別陌生,那我建議你可以去百度或者google一下,案例想對還算豐富的,這不是此文介紹的關鍵,本系列旨在給讀者一個良好的學習方向,少走一些彎路。

這裏我將貼出demo示例相關代碼,內附註釋,各位私下理解一下。

流程圖

在這裏插入圖片描述

流程圖說明:

在請假流程事件內附帶form,裏面有4個屬性,由於我設置Require都是true,所以是必填項,這裏需要注意的是submitType只能爲y或者n(不分大小寫),form屬性如下圖:
在這裏插入圖片描述
你可能會問爲什麼只能輸入y或者n?因爲我在下一個節點exclusiveGateway,也就是顯示爲X號的節點設置了${submitType=="y" || submitType=="Y"}時的線指向部門主管審批,設置 ${submitType=="n" || submitType=="N"} 時指向結束節點,如下兩張圖所示:
在這裏插入圖片描述
圖2:
在這裏插入圖片描述

同樣的,後面每一個X型圖案對應的兩條走向都是有此判斷條件來作爲基礎的,具體可以複製我的圖案到你的eclipse,或者idea內查看詳情。

同時,這裏我的部門主管和經理,還可以設置指定的人選,由於我們這個demo是在main方法內簡單走流程,所以你可以看到我設置的zhangsan爲部門主管,lisi爲部門經理。

代碼介紹及代碼地址

在簡單說明了一下步驟之後,我想你可能看着你的idea已經躍躍欲試了,接下來把此示例的代碼流程簡單串一遍,先看一下項目結構,很簡單拉,就一個java類,一個bpmn文件,是我們在eclipse繪製好的:
在這裏插入圖片描述
我覺得在看代碼之前我應該先拋出一個activiti的數據持久化的概念,首先它是支持持久化到mysql數據庫的,對應的有它自己的表,這個表不用我們手動創建,通過相關配置後activiti自動幫我們實現,這個在後面的文章中會講到,並且我會吧每張表的作用貼出來供大家參考,此篇是基於h2內存來完成的,所以表是看不到的,想看錶,就跟着我一篇一篇看吧,哈哈。

貼一下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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>
    <artifactId>activiti6-leave-process</artifactId>
    <groupId>com.haohuo</groupId>
    <version>1.0-SNAPSHOT</version>
    <modelVersion>4.0.0</modelVersion>


    <dependencies>

        <!-- springboot2.x下Activiti的starter依賴 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter-basic</artifactId>
            <version>6.0.0</version>
        </dependency>

        <!-- 較受歡迎的日誌組建,類似於log4j -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.11</version>
        </dependency>

        <!-- 常用類 -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>23.0</version>
        </dependency>

        <!-- h2內存級數據庫 -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.3.176</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

在貼一下我們的DemoMain java類,我不想多寫什麼來解釋了,註釋都在代碼內,大家自行理解,需要說明的是這裏使用的scanner來完成流程的提交,大家可以拿上我的,或者你的文件去玩一下,如果想要我的,可以到文末的github地址將我完整示例下載下來跑一下:

package com.haohuo;

import com.google.common.collect.Maps;
import org.activiti.engine.*;
import org.activiti.engine.form.FormProperty;
import org.activiti.engine.form.TaskFormData;
import org.activiti.engine.impl.form.DateFormType;
import org.activiti.engine.impl.form.StringFormType;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

/**
 * @Auther: Zhang Peike
 * @Date: 2019/7/3 09:48
 */
public class DemoMain {
    private static final Logger logger = LoggerFactory.getLogger(DemoMain.class);

    public static void main(String[] args) throws ParseException {
        logger.info("開始請假流程 . . .");
        // 創建流程引擎
        ProcessEngine processEngine = getProcessEngine();

        // 部署流程定義文件
        ProcessDefinition processDefinition = getProcessDefinition(processEngine);

        // 啓動運行流程
        ProcessInstance processInstance = getProcessInstance(processEngine, processDefinition);

        // 處理流程任務
        processTask(processEngine, processInstance);
        logger.info("結束請假流程 . . ");
    }

    /**
     * 處理流程任務
     * @param processEngine
     * @param processInstance
     * @throws ParseException
     */
    private static void processTask(ProcessEngine processEngine, ProcessInstance processInstance) throws ParseException {
        Scanner scanner = new Scanner(System.in);
        while (processInstance != null && !processInstance.isEnded()) {   //判斷流程不爲空,且流程沒有結束
            TaskService taskService = processEngine.getTaskService();
            List<Task> list = taskService.createTaskQuery().list();    //列出當前需要處理的任務
            logger.info("待處理任務數量 [{}]", list.size());
            for (Task task : list) {

                logger.info("待處理任務 [{}]", task.getName());
                Map<String, Object> variables = getMap(processEngine, scanner, task);     //獲取用戶的輸入信息
                taskService.complete(task.getId(),variables);
                processInstance = processEngine.getRuntimeService().createProcessInstanceQuery()
                        .processInstanceId(processInstance.getId()).singleResult();
            }
        }
        scanner.close();
    }

    /**
     * 獲取用戶的輸入信息
     * @param processEngine
     * @param scanner
     * @param task
     * @return
     * @throws ParseException
     */
    private static Map<String, Object> getMap(ProcessEngine processEngine, Scanner scanner, Task task) throws ParseException {
        FormService formService = processEngine.getFormService();    //通過formService來獲取form表單輸入
        TaskFormData taskFormData = formService.getTaskFormData (task.getId());
        List<FormProperty> formProperties = taskFormData.getFormProperties();    //獲取taskFormData的表單內容
        Map<String,Object> variables = Maps.newHashMap();    //這個Map鍵值對來存對應表單用戶輸入的內容
        for (FormProperty property : formProperties){   //property爲表單中的內容
            String line = null;    //這裏獲取輸入的信息
            if(StringFormType.class.isInstance(property.getType())){   //如果是String類型的話
                logger.info("請輸入 [{}] ?" , property.getName());    //輸入form表單的某一項內容
                line = scanner.nextLine();
                variables.put(property.getId(),line);
            }else if(DateFormType.class.isInstance(property.getType())){   //如果是日期類型的話
                logger.info("請輸入 [{}] ? 格式爲(yyyy-MM-dd)" , property.getName());    //輸入form表單的某一項內容
                line = scanner.nextLine();
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");   //設置輸入的日期格式
                Date date = dateFormat.parse(line);
                variables.put(property.getId(),date);
            }else{
                logger.info("類型不支持 [{}]",property.getType());
            }
            logger.info("您輸入的內容是 [{}] " , line);
        }
        return variables;
    }


    /**
     * 啓動運行流程
     *
     * @param processEngine
     * @param processDefinition
     */
    private static ProcessInstance getProcessInstance(ProcessEngine processEngine, ProcessDefinition processDefinition) {
        RuntimeService runtimeService = processEngine.getRuntimeService();   //啓動流程要有一個運行時對象
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());   //這裏我們根據processDefinition的ID來啓動
        logger.info("啓動流程 [{}]", processInstance.getProcessDefinitionKey());
        return processInstance;
    }

    /**
     * 部署流程定義文件
     *
     * @param processEngine
     * @return
     */
    private static ProcessDefinition getProcessDefinition(ProcessEngine processEngine) {
        RepositoryService repositoryService = processEngine.getRepositoryService();   //創建一個對流程編譯庫操作的Service
        DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();   //獲取一個builder
        deploymentBuilder.addClasspathResource("LeaveProcess.bpmn");   //這裏寫上流程編譯路徑
        Deployment deployment = deploymentBuilder.deploy();    //部署
        String deploymentId = deployment.getId();    //獲取deployment的ID
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();     //根據deploymentId來獲取流程定義對象
        logger.info("流程定義文件 [{}] , 流程ID [{}]", processDefinition.getName(), processDefinition.getId());
        return processDefinition;
    }

    /**
     * 創建流程引擎
     *
     * @return
     */
    private static ProcessEngine getProcessEngine() {
        ProcessEngineConfiguration cfg = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();   //創建默認的基於內存數據庫的流程引擎配置對象
        ProcessEngine processEngine = cfg.buildProcessEngine();    //構造流程引擎
        String engineName = processEngine.getName();   //獲取流程引擎的name
        String version = ProcessEngine.VERSION;    //獲取流程引擎的版本信息

        logger.info("流程引擎名稱 [{}], 版本 [{}]", engineName, version);
        return processEngine;
    }

}

本文代碼地址:https://github.com/producted/activiti-learn/tree/master/activiti6-leave-process

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