1. <nobr id="easjo"><address id="easjo"></address></nobr>

      <track id="easjo"><source id="easjo"></source></track>
      1. 
        

      2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
      3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>
          貴州做網站公司
          貴州做網站公司~專業!靠譜!
          10年網站模板開發經驗,熟悉國內外開源網站程序,包括DEDECMS,WordPress,ZBlog,Discuz! 等網站程序,可為您提供網站建設,網站克隆,仿站,網頁設計,網站制作,網站推廣優化等服務。我們專注高端營銷型網站,企業官網,集團官網,自適應網站,手機網站,網絡營銷,網站優化,網站服務器環境搭建以及托管運維等。為客戶提供一站式網站解決方案?。?!

          最新Flowable工作流教程

          來源:互聯網轉載 時間:2024-01-29 08:03:02

          最新Flowable工作流教程

          一、Flowable介紹

          ??Flowable是BPMN的一個基于java的軟件實現,不過Flowable不僅僅包括BPMN,還有DMN決策表和CMMN Case管理引擎,并且有自己的用戶管理、微服務API等一系列功能,是一個服務平臺。

          二、Flowable基礎

          官方手冊:https://tkjohn.github.io/flowable-userguide/#_introduction

          1.創建ProcessEngine

          ??創建一個基本的maven工程,可以是Eclipse也可以是其他IDEA。然后添加兩個依賴

          • Flowable流程引擎。使我們可以創建一個ProcessEngine流程引擎對象,并訪問Flowable API。
          • 一個是MySQL的數據庫驅動

          pom.xml文件中添加下列行:

          <dependency>    <groupId>org.flowable</groupId>    <artifactId>flowable-engine</artifactId>    <version>6.3.0</version></dependency><dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId>    <version>8.0.21</version></dependency>

          ??然后創建一個普通的Java類,添加對應的main方法,首先要做的是初始化ProcessEngine流程引擎實例。這是一個線程安全的對象,因此通常只需要在一個應用中初始化一次。 ProcessEngineProcessEngineConfiguration實例創建。該實例可以配置與調整流程引擎的設置。 通常使用一個配置XML文件創建ProcessEngineConfiguration,但是(像在這里做的一樣)也可以編程方式創建它。 ProcessEngineConfiguration所需的最小配置,是數據庫JDBC連接:

          public static void main(String[] args) {    ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()        .setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn?serverTimezone=UTC")        .setJdbcUsername("root")        .setJdbcPassword("123456")        .setJdbcDriver("com.mysql.cj.jdbc.Driver")        .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);    ProcessEngine processEngine = cfg.buildProcessEngine();}

          ??注意在mysql8.0中執行可能出現如下的錯誤

          ??出現這種情況只需要在mysql的連接字符串中添加上nullCatalogMeansCurrent=true,設置為只查當前連接的schema庫即可。

              public static void main(String[] args) {        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()                .setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn1?serverTimezone=UTC&nullCatalogMeansCurrent=true")                .setJdbcUsername("root")                .setJdbcPassword("123456")                .setJdbcDriver("com.mysql.cj.jdbc.Driver")                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);        ProcessEngine processEngine = cfg.buildProcessEngine();    }

          ??然后應用運行沒有問題,但也沒有在控制臺提供有用的信息,只有一條消息提示日志沒有正確配置。Flowable使用SLF4J作為內部日志框架。在這個例子中,我們使用log4j作為SLF4J的實現。因此在pom.xml文件中添加下列依賴:

          <dependency>    <groupId>org.slf4j</groupId>    <artifactId>slf4j-api</artifactId>    <version>1.7.21</version></dependency><dependency>    <groupId>org.slf4j</groupId>    <artifactId>slf4j-log4j12</artifactId>    <version>1.7.21</version></dependency>

          ??Log4j需要一個配置文件。在src/main/resources文件夾下添加log4j.properties文件,并寫入下列內容:

          log4j.rootLogger=DEBUG, CAlog4j.appender.CA=org.apache.log4j.ConsoleAppenderlog4j.appender.CA.layout=org.apache.log4j.PatternLayoutlog4j.appender.CA.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n

          ??重新運行應用。應該可以看到關于引擎啟動與創建數據庫表結構的提示日志:

          ??同時可以看到創建了相關的表結構在數據庫中

          ??這樣就得到了一個啟動可用的流程引擎。接下來為它提供一個流程!

          2.部署流程定義

          ??接下來我們構建一個非常簡單的請假流程,Flowable引擎需要流程定義為BPMN 2.0格式,這是一個業界廣泛接受的XML標準。 在Flowable術語中,我們將其稱為一個流程定義(process definition)。一個流程定義可以啟動多個流程實例(process instance)。流程定義可以看做是重復執行流程的藍圖。 在這個例子中,流程定義定義了請假的各個步驟,而一個流程實例對應某個雇員提出的一個請假申請。

          ??BPMN 2.0存儲為XML,并包含可視化的部分:使用標準方式定義了每個步驟類型(人工任務,自動服務調用,等等)如何呈現,以及如何互相連接。這樣BPMN 2.0標準使技術人員與業務人員能用雙方都能理解的方式交流業務流程。

          ??我們要使用的流程定義為:

          ??流程定義說明:

          • 我們假定啟動流程需要提供一些信息,例如雇員名字、請假時長以及說明。當然,這些可以單獨建模為流程中的第一步。 但是如果將它們作為流程的“輸入信息”,就能保證只有在實際請求時才會建立一個流程實例。否則(將提交作為流程的第一步),用戶可能在提交之前改變主意并取消,但流程實例已經創建了。 在某些場景中,就可能影響重要的指標(例如啟動了多少申請,但還未完成),取決于業務目標。
          • 左側的圓圈叫做啟動事件(start event)。這是一個流程實例的起點。
          • 第一個矩形是一個用戶任務(user task)。這是流程中用戶操作的步驟。在這個例子中,經理需要批準或駁回申請
          • 取決于經理的決定,排他網關(exclusive gateway) (帶叉的菱形)會將流程實例路由至批準或駁回路徑
          • 如果批準,則需要將申請注冊至某個外部系統,并跟著另一個用戶任務,將經理的決定通知給申請人。當然也可以改為發送郵件。
          • 如果駁回,則為雇員發送一封郵件通知他。

          ??一般來說,這樣的流程定義使用可視化建模工具建立,如Flowable Designer(Eclipse)或Flowable Web Modeler(Web應用)。但在這里我們直接撰寫XML,以熟悉BPMN 2.0及其概念。

          ??與上面展示的流程圖對應的BPMN 2.0 XML在下面顯示。請注意這只包含了“流程部分”。如果使用圖形化建模工具,實際的XML文件還將包含“可視化部分”,用于描述圖形信息,如流程定義中各個元素的坐標(所有的圖形化信息包含在XML的BPMNDiagram標簽中,作為definitions標簽的子元素)。

          ??將下面的XML保存在src/main/resources文件夾下名為holiday-request.bpmn20.xml的文件中。

          <?xml version="1.0" encoding="UTF-8"?><definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"             xmlns:xsd="http://www.w3.org/2001/XMLSchema"             xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"             xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"             xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"             xmlns:flowable="http://flowable.org/bpmn"             typeLanguage="http://www.w3.org/2001/XMLSchema"             expressionLanguage="http://www.w3.org/1999/XPath"             targetNamespace="http://www.flowable.org/processdef">    <process  name="Holiday Request" isExecutable="true">        <startEvent />        <sequenceFlow sourceRef="startEvent" targetRef="approveTask"/>        <userTask  name="Approve or reject request"/>        <sequenceFlow sourceRef="approveTask" targetRef="decision"/>        <exclusiveGateway />        <sequenceFlow sourceRef="decision" targetRef="externalSystemCall">            <conditionExpression xsi:type="tFormalExpression">                <![CDATA[          ${approved}        ]]>            </conditionExpression>        </sequenceFlow>        <sequenceFlow  sourceRef="decision" targetRef="sendRejectionMail">            <conditionExpression xsi:type="tFormalExpression">                <![CDATA[          ${!approved}        ]]>            </conditionExpression>        </sequenceFlow>        <serviceTask  name="Enter holidays in external system"                     flowable:/>        <sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/>        <userTask  name="Holiday approved"/>        <sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/>        <serviceTask  name="Send out rejection email"                     flowable:/>        <sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/>        <endEvent />        <endEvent />    </process></definitions>

          ??現在我們已經有了流程BPMN 2.0 XML文件,下來需要將它部署(deploy)*到引擎中。部署*一個流程定義意味著:

          • 流程引擎會將XML文件存儲在數據庫中,這樣可以在需要的時候獲取它
          • 流程定義轉換為內部的、可執行的對象模型,這樣使用它就可以啟動流程實例。

          ??將流程定義部署至Flowable引擎,需要使用RepositoryService,其可以從ProcessEngine對象獲取。使用RepositoryService,可以通過XML文件的路徑創建一個新的部署(Deployment),并調用deploy()方法實際執行:

              /**     * 部署流程     */    @Test    public void testDeploy(){        // 配置數據庫相關信息 獲取 ProcessEngineConfiguration        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()                .setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true")                .setJdbcUsername("root")                .setJdbcPassword("123456")                .setJdbcDriver("com.mysql.cj.jdbc.Driver")                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);        // 獲取流程引擎對象        ProcessEngine processEngine = cfg.buildProcessEngine();        // 部署流程 獲取RepositoryService對象        RepositoryService repositoryService = processEngine.getRepositoryService();        Deployment deployment = repositoryService.createDeployment()// 創建Deployment對象                .addClasspathResource("holiday-request.bpmn20.xml") // 添加流程部署文件                .name("請求流程") // 設置部署流程的名稱                .deploy(); // 執行部署操作        System.out.println("deployment.getId() = " + deployment.getId());        System.out.println("deployment.getName() = " + deployment.getName());    }

          ??然后執行該方法日志操作成功:

          ??在后臺表結構也可以看到相關的信息

          act_re_deployment: 流程定義部署表,每部署一次就增加一條記錄

          act_re_procdef :流程定義表,部署每個新的流程定義都會在這張表中增加一條記錄

          act_ge_bytearray :流程資源表,流程部署的 bpmn文件和png圖片會保存在該表中

          ??我們現在可以通過API查詢驗證流程定義已經部署在引擎中(并學習一些API)。通過RepositoryService創建的ProcessDefinitionQuery對象實現。

          /**     * 查看流程定義     */    @Test    public void testDeployQuery(){        // 配置數據庫相關信息 獲取 ProcessEngineConfiguration        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()                .setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true")                .setJdbcUsername("root")                .setJdbcPassword("123456")                .setJdbcDriver("com.mysql.cj.jdbc.Driver")                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);        // 獲取流程引擎對象        ProcessEngine processEngine = cfg.buildProcessEngine();        // 部署流程 獲取RepositoryService對象        RepositoryService repositoryService = processEngine.getRepositoryService();        // 獲取流程定義對象        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()                .deploymentId("2501")                .singleResult();        System.out.println("processDefinition.getId() = " + processDefinition.getId());        System.out.println("processDefinition.getName() = " + processDefinition.getName());        System.out.println("processDefinition.getDeploymentId() = " + processDefinition.getDeploymentId());        System.out.println("processDefinition.getDescription() = " + processDefinition.getDescription());    }

          輸出結果為:

          processDefinition.getId() = holidayRequest:2:2503processDefinition.getName() = Holiday RequestprocessDefinition.getDeploymentId() = 2501processDefinition.getDescription() = null

          3.啟動流程實例

          ??現在已經在流程引擎中部署了流程定義,因此可以使用這個流程定義作為“模板”啟動流程實例。

          ??要啟動流程實例,需要提供一些初始化流程變量。一般來說,可以通過呈現給用戶的表單,或者在流程由其他系統自動觸發時通過REST API,來獲取這些變量。在這個例子里,我們簡化直接在代碼中定義了,我們使用RuntimeService啟動一個流程實例。

              /**     * 啟動流程實例     */    @Test    public void testRunProcess(){        // 配置數據庫相關信息 獲取 ProcessEngineConfiguration        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()                .setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true")                .setJdbcUsername("root")                .setJdbcPassword("123456")                .setJdbcDriver("com.mysql.cj.jdbc.Driver")                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);        // 獲取流程引擎對象        ProcessEngine processEngine = cfg.buildProcessEngine();        // 啟動流程實例通過 RuntimeService 對象        RuntimeService runtimeService = processEngine.getRuntimeService();        // 構建流程變量        Map<String,Object> variables = new HashMap<>();        variables.put("employee","張三") ;// 誰申請請假        variables.put("nrOfHolidays",3); // 請幾天假        variables.put("description","工作累了,想出去玩玩"); // 請假的原因        // 啟動流程實例,第一個參數是流程定義的id        ProcessInstance processInstance = runtimeService                .startProcessInstanceByKey("holidayRequest", variables);// 啟動流程實例        // 輸出相關的流程實例信息        System.out.println("流程定義的ID:" + processInstance.getProcessDefinitionId());        System.out.println("流程實例的ID:" + processInstance.getId());        System.out.println("當前活動的ID:" + processInstance.getActivityId());    }

          啟動成功,輸出結果如下:

          流程定義的ID:holidayRequest:2:2503流程實例的ID:5001當前活動的ID:null

          對應的流程實例ID為:5001

          啟動流程實例涉及到的表結構:

          • act_hi_actinst 流程實例執行歷史
          • act_hi_identitylink 流程的參與用戶的歷史信息
          • act_hi_procinst 流程實例歷史信息
          • act_hi_taskinst 流程任務歷史信息
          • act_ru_execution 流程執行信息
          • act_ru_identitylink 流程的參與用戶信息
          • act_ru_task 任務信息

          4.查看任務

          ??上面員工發起了一個請假流程,接下來就會流轉到總經理這兒來處理,之前我們沒有指定經理這的處理人,我們可以加一個

          ??然后我們來查看下lisi的任務

              /**     * 查看任務     */    @Test    public void testQueryTask(){        // 配置數據庫相關信息 獲取 ProcessEngineConfiguration        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()                .setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true")                .setJdbcUsername("root")                .setJdbcPassword("123456")                .setJdbcDriver("com.mysql.cj.jdbc.Driver")                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);        // 獲取流程引擎對象        ProcessEngine processEngine = cfg.buildProcessEngine();        TaskService taskService = processEngine.getTaskService();        List<Task> list = taskService.createTaskQuery()                .processDefinitionKey("holidayRequestNew")                .taskAssignee("lisi")                .list();        for (Task task : list) {            System.out.println("task.getProcessDefinitionId() = " + task.getProcessDefinitionId());            System.out.println("task.getId() = " + task.getId());            System.out.println("task.getAssignee() = " + task.getAssignee());            System.out.println("task.getName() = " + task.getName());        }    }

          輸出結果為:

          task.getProcessDefinitionId() = holidayRequestNew:1:10003task.getId() = 12508task.getAssignee() = lisitask.getName() = Approve or reject request

          5.完成任務

          ??現在李四這個角色可以來完成當前的任務了

          ??在此處我們直接解決掉這個請假,然后會走發送拒絕郵件的流程,這塊我們需要用到JavaDelegate來觸發。

          我們定義這樣一個Java類

          public class SendRejectionMail implements JavaDelegate {    /**     * 觸發發送郵件的操作     * @param delegateExecution     */    @Override    public void execute(DelegateExecution delegateExecution) {        System.out.println("請假被拒絕,,,安心工作吧");    }}

          然后來完成任務

              /**     * 完成任務     */    @Test    public void testCompleteTask(){        // 配置數據庫相關信息 獲取 ProcessEngineConfiguration        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()                .setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true")                .setJdbcUsername("root")                .setJdbcPassword("123456")                .setJdbcDriver("com.mysql.cj.jdbc.Driver")                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);        // 獲取流程引擎對象        ProcessEngine processEngine = cfg.buildProcessEngine();        TaskService taskService = processEngine.getTaskService();        Task task = taskService.createTaskQuery()                .processDefinitionKey("holidayRequestNew")                .taskAssignee("lisi")                .singleResult();        // 添加流程變量        Map<String,Object> variables = new HashMap<>();        variables.put("approved",false); // 拒絕請假        // 完成任務        taskService.complete(task.getId(),variables);    }

          然后可以看到JavaDelegate觸發了

          6.流程的刪除

          ??有些流程已經沒有用了,我們需要刪除掉,其實也非常簡單

              /**     * 刪除流程     */    @Test    public void testDeleteProcess(){        // 配置數據庫相關信息 獲取 ProcessEngineConfiguration        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()                .setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true")                .setJdbcUsername("root")                .setJdbcPassword("123456")                .setJdbcDriver("com.mysql.cj.jdbc.Driver")                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);        // 獲取流程引擎對象        ProcessEngine processEngine = cfg.buildProcessEngine();        RepositoryService repositoryService = processEngine.getRepositoryService();        // 刪除流程定義,如果該流程定義已經有了流程實例啟動則刪除時報錯        // repositoryService.deleteDeployment("1");        // 設置為TRUE 級聯刪除流程定義,及時流程有實例啟動,也可以刪除,設置為false 非級聯刪除操作。        repositoryService.deleteDeployment("2501",true);    }

          7.查看歷史信息

          ??選擇使用Flowable這樣的流程引擎的原因之一,是它可以自動存儲所有流程實例的審計數據歷史數據。這些數據可以用于創建報告,深入展現組織運行的情況,瓶頸在哪里,等等。

          ??例如,如果希望顯示流程實例已經執行的時間,就可以從ProcessEngine獲取HistoryService,并創建歷史活動(historical activities)的查詢。在下面的代碼片段中,可以看到我們添加了一些額外的過濾條件:

          • 只選擇一個特定流程實例的活動
          • 只選擇已完成的活動

          ??結果按照結束時間排序,代表其執行順序。

          /**     * 查看歷史     */    @Test    public void testQueryHistory(){        // 配置數據庫相關信息 獲取 ProcessEngineConfiguration        ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()                .setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true")                .setJdbcUsername("root")                .setJdbcPassword("123456")                .setJdbcDriver("com.mysql.cj.jdbc.Driver")                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);        // 獲取流程引擎對象        ProcessEngine processEngine = cfg.buildProcessEngine();        HistoryService historyService = processEngine.getHistoryService();        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()                .processDefinitionId("holidayRequestNew:1:10003")                .finished()                .orderByHistoricActivityInstanceEndTime().asc()                .list();        for (HistoricActivityInstance historicActivityInstance : list) {            System.out.println(historicActivityInstance.getActivityId() + " took "                    + historicActivityInstance.getDurationInMillis() + " milliseconds");        }    }

          輸出結果

          startEvent took 1 millisecondsapproveTask took 837735 millisecondsdecision took 13 millisecondssendRejectionMail took 2 millisecondsrejectEnd took 1 milliseconds

          好了~flowable的基本應用我們就先介紹到這里了。

          三、Flowable流程設計器

          1.Eclipse Designer

          ??Flowable提供了名為Flowable Eclipse Designer的Eclipse插件,可以用于圖形化地建模、測試與部署BPMN 2.0流程。

          1.1 下載安裝Eclipse

          ??去Eclipse官網下載即可:https://www.eclipse.org/downloads/packages/release 注意2020-09后的版本不再支持jdk8

          ?解壓縮就可以了,然后進入解壓縮的目錄

          ??直接啟動即可

          1.2 安裝Flowable插件

          ??然后我們再安裝下Flowable的插件,選擇Help → Install New Software。在下圖面板中,點擊Add按鈕,并填寫下列字段

          • Name: Flowable BPMN 2.0 designer
          • Location: http://www.flowable.org/designer/update/

          ??這種在線更新的方式已經被官網移除了,操作不了

          ??這時我們就只能通過離線安裝的方式來實現了,下載對應的離線文件

          ??安裝步驟來操作,

          然后繼續:選擇Help → Install New Software

          下一步

          再下一步

          然后finish。彈出如下窗口

          重啟即可

          1.3 創建項目

          ??然后我們就可以創建一個Flowable Project了

          ??然后我們可以在src/mian/resources/ 的目錄下創建對應的流程圖了

          ??看到如下的界面說明插件安裝成功了

          1.4 創建流程圖

          使用滑板來繪制流程,通過從右側把圖標拖拽到左側的面板,最終的效果

          指定流程的主鍵

          指定任務的負責人

          在Properties視圖中指定每個任務節點的負責人

          創建請假單:zhangsan

          審批請假單:lisi

          當我們設置完成后保存文件,會同時生成png圖片

          注意:生成圖片需要如下配置

          1.5 部署流程

          ??首先在Eclipse中生成bar文件,選中項目然后鼠標右擊

          然后會發現在項目的根目錄下多了一個deployment文件夾,里面多了一個MyProcess.bar文件

          然后我們就可以把這個bar文件拷貝到IDEA中,繼續部署的流程

          而部署的代碼和前面沒啥區別

              @Test    public void testDeploy(){        // 1.獲取 ProcessEngine 對象        ProcessEngine processEngine = configuration.buildProcessEngine();        // 2.獲取RepositoryService        RepositoryService repositoryService = processEngine.getRepositoryService();        InputStream in = this.getClass().getClassLoader().getResourceAsStream("MyHoliday.bar");        ZipInputStream zipInputStream = new ZipInputStream(in);        // 3.完成流程的部署操作 ZIP 或者 Bar文件        Deployment deploy = repositoryService.createDeployment()               // .addClasspathResource("MyHoliday.bar")// 關聯要部署的流程文件                .addZipInputStream(zipInputStream)                .name("XXX公司請求流程")                .deploy() ;// 部署流程        System.out.println("deploy.getId() = " + deploy.getId());        System.out.println("deploy.getName() = " + deploy.getName());    }

          執行后查看表結構,相關的信息就進去了

          完整的案例代碼:

          package com.bobo.flowable.test;import org.flowable.engine.*;import org.flowable.engine.history.HistoricActivityInstance;import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;import org.flowable.engine.repository.Deployment;import org.flowable.engine.runtime.ProcessInstance;import org.flowable.task.api.Task;import org.junit.Before;import org.junit.Test;import java.io.InputStream;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.zip.ZipInputStream;public class Test02 {    ProcessEngineConfiguration configuration = null;    @Before    public void before(){        // 獲取  ProcessEngineConfiguration 對象        configuration = new StandaloneProcessEngineConfiguration();        // 配置 相關的數據庫的連接信息        configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver");        configuration.setJdbcUsername("root");        configuration.setJdbcPassword("123456");        configuration.setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn?serverTimezone=UTC&nullCatalogMeansCurrent=true");        // 如果數據庫中的表結構不存在就新建        configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);    }    /**     * 部署流程     *     */    @Test    public void testDeploy(){        // 1.獲取 ProcessEngine 對象        ProcessEngine processEngine = configuration.buildProcessEngine();        // 2.獲取RepositoryService        RepositoryService repositoryService = processEngine.getRepositoryService();        InputStream in = this.getClass().getClassLoader().getResourceAsStream("MyHoliday.bar");        ZipInputStream zipInputStream = new ZipInputStream(in);        // 3.完成流程的部署操作 ZIP 或者 Bar文件        Deployment deploy = repositoryService.createDeployment()               // .addClasspathResource("MyHoliday.bar")// 關聯要部署的流程文件                .addZipInputStream(zipInputStream)                .name("XXX公司請求流程")                .deploy() ;// 部署流程        System.out.println("deploy.getId() = " + deploy.getId());        System.out.println("deploy.getName() = " + deploy.getName());    }    /**     * 啟動流程實例     */    @Test    public void testRunProcess(){        ProcessEngine processEngine = configuration.buildProcessEngine();        // 我們需要通過RuntimeService來啟動流程實例        RuntimeService runtimeService = processEngine.getRuntimeService();        // 啟動流程實例        ProcessInstance holidayRequest = runtimeService.startProcessInstanceById("myProcess:1:25004");        System.out.println("holidayRequest.getProcessDefinitionId() = " + holidayRequest.getProcessDefinitionId());        System.out.println("holidayRequest.getActivityId() = " + holidayRequest.getActivityId());        System.out.println("holidayRequest.getId() = " + holidayRequest.getId());    }    /**     * 測試任務查詢     */    @Test    public void testQueryTask(){        ProcessEngine processEngine = configuration.buildProcessEngine();        TaskService taskService = processEngine.getTaskService();        List<Task> list = taskService.createTaskQuery()                .processDefinitionKey("myProcess") // 指定查詢的流程編程                .taskAssignee("zhangsan") // 查詢這個任務的處理人                .list();        for (Task task : list) {            System.out.println("task.getProcessDefinitionId() = " + task.getProcessDefinitionId());            System.out.println("task.getName() = " + task.getName());            System.out.println("task.getAssignee() = " + task.getAssignee());            System.out.println("task.getDescription() = " + task.getDescription());            System.out.println("task.getId() = " + task.getId());        }    }    /**     * 完成當前任務     */    @Test    public void testCompleteTask(){        ProcessEngine processEngine = configuration.buildProcessEngine();        TaskService taskService = processEngine.getTaskService();        Task task = taskService.createTaskQuery()                .processDefinitionKey("myProcess")                .taskAssignee("lisi")                .singleResult();        // 創建流程變量        if(task != null){            // 完成任務            taskService.complete(task.getId());        }    }    /**     * 獲取流程任務的歷史數據     */    @Test    public void testHistory(){        ProcessEngine processEngine = configuration.buildProcessEngine();        HistoryService historyService = processEngine.getHistoryService();        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()                .processDefinitionId("myProcess:1:25004")                .finished() // 查詢的歷史記錄的狀態是已經完成                .orderByHistoricActivityInstanceEndTime().asc() // 指定排序的字段和順序                .list();        for (HistoricActivityInstance history : list) {            System.out.println(history.getActivityName()+":"+history.getAssignee()+"--"                    +history.getActivityId()+":" + history.getDurationInMillis()+"毫秒");        }    }}

          2.Flowable UI應用

          ??Flowable提供了幾個web應用,用于演示及介紹Flowable項目提供的功能:

          • Flowable IDM: 身份管理應用。為所有Flowable UI應用提供單點登錄認證功能,并且為擁有IDM管理員權限的用戶提供了管理用戶、組與權限的功能。
          • Flowable Modeler: 讓具有建模權限的用戶可以創建流程模型、表單、選擇表與應用定義。
          • Flowable Task: 運行時任務應用。提供了啟動流程實例、編輯任務表單、完成任務,以及查詢流程實例與任務的功能。
          • Flowable Admin: 管理應用。讓具有管理員權限的用戶可以查詢BPMN、DMN、Form及Content引擎,并提供了許多選項用于修改流程實例、任務、作業等。管理應用通過REST API連接至引擎,并與Flowable Task應用及Flowable REST應用一同部署。

          ??所有其他的應用都需要Flowable IDM提供認證。每個應用的WAR文件可以部署在相同的servlet容器(如Apache Tomcat)中,也可以部署在不同的容器中。由于每個應用使用相同的cookie進行認證,因此應用需要運行在相同的域名下。

          2.1 安裝部署

          下載Tomcat:https://tomcat.apache.org/download-80.cgi 官網下載后解壓縮到非中文目錄即可,然后是下載FlowableUI的文件,在Flowable6.6之后把FlowableUI中提供的四個功能合并到了一起。

          然后把解壓縮后的兩個war包拷貝到Tomcat的解壓縮的webapps目錄下

          Tomcat目錄:

          2.2 啟動服務

          ??啟動Tomcat服務,執行startup.bat文件

          如果啟動中出現亂碼修改Tomcat的conf目錄下的 logging.properties 文件中的編碼

          如果一閃而過則檢查jdk的環境變量配置。啟動成功后,在瀏覽器中訪問 http://localhost:8080/flowable-ui, 默認的賬號密碼是 admin/test

          2.3 用戶管理

          ??我們先在 身份管理應用程序 中創建用戶并授權

          創建用戶

          填寫詳細信息

          授權管理

          2.4 繪制流程

          創建新的流程

          流程圖界面

          創建流程,分配處理人

          繼續完成流程圖的創建

          2.5 部署流程

          ??繪制好的流程圖,我們只需要一鍵導出即可

          下載下來后拷貝到項目的resource目錄下即可

          然后就是正常的操作流程了

          2.6 FlowableUI 演示

          2.6.1 部署流程

          ??在FlowableUI中提供了演示程序

          創建一個新的應用程序,并指定相關的信息

          創建應用后需要指定對應的流程圖

          發布應用程序

          2.6.2 啟動流程

          ??發布了應用程序后我們就可以來啟動流程了

          點擊顯示圖:

          也就是可以看到當前是user1來處理,user1登錄后可以看到要處理的流程,user2登錄是看不到的。

          點擊完成后流程就向下一步流轉了

          這時再通過user2登錄,就可以看到對應的代辦的信息

          然后點擊完成,那么整個流程就介紹了

          四、Flowable基礎表結構

          1.表結構講解

          ??工作流程的相關操作都是操作存儲在對應的表結構中,為了能更好的弄清楚Flowable的實現原理和細節,我們有必要先弄清楚Flowable的相關表結構及其作用。在Flowable中的表結構在初始化的時候會創建五類表結構,具體如下:

          • ACT_RE :'RE'表示 repository。 這個前綴的表包含了流程定義和流程靜態資源 (圖片,規則,等等)。
          • ACT_RU:'RU'表示 runtime。 這些運行時的表,包含流程實例,任務,變量,異步任務,等運行中的數據。 Flowable只在流程實例執行過程中保存這些數據, 在流程結束時就會刪除這些記錄。 這樣運行時表可以一直很小速度很快。
          • ACT_HI:'HI'表示 history。 這些表包含歷史數據,比如歷史流程實例, 變量,任務等等。
          • ACT_GE: GE 表示 general。 通用數據, 用于不同場景下
          • ACT_ID: ’ID’表示identity(組織機構)。這些表包含標識的信息,如用戶,用戶組,等等。

          具體的表結構的含義:

          表分類表名解釋
          一般數據
          [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]運行時變量表
          用戶用戶組表
          [ACT_ID_BYTEARRAY]二進制數據表
          [ACT_ID_GROUP]用戶組信息表
          [ACT_ID_INFO]用戶信息詳情表
          [ACT_ID_MEMBERSHIP]人與組關系表
          [ACT_ID_PRIV]權限表
          [ACT_ID_PRIV_MAPPING]用戶或組權限關系表
          [ACT_ID_PROPERTY]屬性表
          [ACT_ID_TOKEN]記錄用戶的token信息
          [ACT_ID_USER]用戶表

          2.ProcessEngine講解

          2.1 硬編碼的方式

          ??我們前面講解案例的時候是通過ProcessEngineConfiguration這個配置類來加載的。

          // 配置數據庫相關信息 獲取 ProcessEngineConfigurationProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()    .setJdbcUrl("jdbc:mysql://localhost:3306/flowable-learn2?serverTimezone=UTC&nullCatalogMeansCurrent=true")    .setJdbcUsername("root")    .setJdbcPassword("123456")    .setJdbcDriver("com.mysql.cj.jdbc.Driver")    .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);// 獲取流程引擎對象ProcessEngine processEngine = cfg.buildProcessEngine();

          ??這種方式會調用buildProcessEngine()方法,里面的核心代碼為:

          2.2 配置文件

          ??除了上面的硬編碼的方式外,我們還可以在resources目錄下創建一個flowable.cfg.xml文件,注意這個名稱是固定的哦。內容如下:

          <beans xmlns="http://www.springframework.org/schema/beans"       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">    <bean           >        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/flow1?allowMultiQueries=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;useSSL=false&amp;serverTimezone=UTC&amp;nullCatalogMeansCurrent=true" /><property name="jdbcDriver" value="com.mysql.cj.jdbc.Driver" />        <property name="jdbcUsername" value="root" />        <property name="jdbcPassword" value="123456" />        <property name="databaseSchemaUpdate" value="true" />        <property name="asyncExecutorActivate" value="false" />    </bean></beans>

          ??在上面的配置文件中配置相關的信息。我們在Java代碼中就可以簡化為:

              @Test    public void test01(){        // 獲取流程引擎對象        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        System.out.println("processEngine = " + processEngine);    }

          ??可以看下getDefaultProcessEngine的源碼,在里面最終還是執行了和硬編碼一樣的代碼

              public static ProcessEngine getProcessEngine(String processEngineName) {        if (!isInitialized()) {            init(); // 完成初始化操作        }        return processEngines.get(processEngineName);    }

          ??進入init方法

              public static synchronized void init() {        if (!isInitialized()) {            if (processEngines == null) {                // Create new map to store process-engines if current map is null                processEngines = new HashMap<>();            }            ClassLoader classLoader = ReflectUtil.getClassLoader();            Enumeration<URL> resources = null;            try {                resources = classLoader.getResources("flowable.cfg.xml"); // 加載flowable.cfg.xml配置文件            } catch (IOException e) {                throw new FlowableIllegalArgumentException("problem retrieving flowable.cfg.xml resources on the classpath: " + System.getProperty("java.class.path"), e);            }            // Remove duplicated configuration URL's using set. Some            // classloaders may return identical URL's twice, causing duplicate            // startups            Set<URL> configUrls = new HashSet<>();            while (resources.hasMoreElements()) {                configUrls.add(resources.nextElement());            }            for (Iterator<URL> iterator = configUrls.iterator(); iterator.hasNext();) {                URL resource = iterator.next();                LOGGER.info("Initializing process engine using configuration '{}'", resource.toString());                initProcessEngineFromResource(resource); // 初始化ProcessEngine            }            try {                resources = classLoader.getResources("flowable-context.xml"); // 在整合Spring的情況下加載該文件            } catch (IOException e) {                throw new FlowableIllegalArgumentException("problem retrieving flowable-context.xml resources on the classpath: " + System.getProperty("java.class.path"), e);            }            while (resources.hasMoreElements()) {                URL resource = resources.nextElement();                LOGGER.info("Initializing process engine using Spring configuration '{}'", resource.toString());                initProcessEngineFromSpringResource(resource); // 從Spring的資源文件中完成ProcessEngine的初始化            }            setInitialized(true);        } else {            LOGGER.info("Process engines already initialized");        }    }

          ??在源碼中提供了單獨使用好整合Spring的配置加載方式。再進入到initProcessEngineFromResource(resource)方法中:

          而且我們也可以看到ProcessEngine最終的實現是 ProcessEngineImpl對象。

          2.3 自定義配置文件

          ??最后我們如果要加載自定義名稱的配置文件可以通過ProcessEngineConfiguration中的對應構造方法來實現

              @Test    public void test2() throws Exception{        ProcessEngineConfiguration configuration = ProcessEngineConfiguration                .createProcessEngineConfigurationFromResource("flowable.cfg.xml");        ProcessEngine processEngine = configuration.buildProcessEngine();        System.out.println("processEngine = " + processEngine);    }

          3. Servcie服務接口

          Service是工作流引擎提供用于進行工作流部署、執行、管理的服務接口,我們使用這些接口可以就是操作服務對應的數據表

          3.1 Service創建方式

          通過ProcessEngine創建Service

          方式如下:

          RuntimeService runtimeService = processEngine.getRuntimeService();RepositoryService repositoryService = processEngine.getRepositoryService();TaskService taskService = processEngine.getTaskService();// ...

          3.2 Service總覽

          service名稱service作用
          RepositoryServiceFlowable的資源管理類
          RuntimeServiceFlowable的流程運行管理類
          TaskServiceFlowable的任務管理類
          HistoryServiceFlowable的歷史管理類
          ManagerServiceFlowable的引擎管理類

          簡單介紹:

          RepositoryService

          是activiti的資源管理類,提供了管理和控制流程發布包和流程定義的操作。使用工作流建模工具設計的業務流程圖需要使用此service將流程定義文件的內容部署到計算機。

          除了部署流程定義以外還可以:查詢引擎中的發布包和流程定義。

          暫?;蚣せ畎l布包,對應全部和特定流程定義。 暫停意味著它們不能再執行任何操作了,激活是對應的反向操作。獲得多種資源,像是包含在發布包里的文件, 或引擎自動生成的流程圖。

          獲得流程定義的pojo版本, 可以用來通過java解析流程,而不必通過xml。

          RuntimeService

          Activiti的流程運行管理類??梢詮倪@個服務類中獲取很多關于流程執行相關的信息

          TaskService

          Activiti的任務管理類??梢詮倪@個類中獲取任務的信息。

          HistoryService

          Flowable的歷史管理類,可以查詢歷史信息,執行流程時,引擎會保存很多數據(根據配置),比如流程實例啟動時間,任務的參與者, 完成任務的時間,每個流程實例的執行路徑,等等。 這個服務主要通過查詢功能來獲得這些數據。

          ManagementService

          Activiti的引擎管理類,提供了對Flowable 流程引擎的管理和維護功能,這些功能不在工作流驅動的應用程序中使用,主要用于 Flowable 系統的日常維護。

          4.圖標介紹

          ??BPMN 2.0是業務流程建模符號2.0的縮寫。它由Business Process Management Initiative這個非營利協會創建并不斷發展。作為一種標識,BPMN 2.0是使用一些符號來明確業務流程設計流程圖的一整套符號規范,它能增進業務建模時的溝通效率。目前BPMN2.0是最新的版本,它用于在BPM上下文中進行布局和可視化的溝通。接下來我們先來了解在流程設計中常見的 符號。

          BPMN2.0的基本符合主要包含:

          4.1 事件圖標

          ??在Flowable中的事件圖標啟動事件,邊界事件,中間事件和結束事件.

          4.2 活動(任務)圖標

          ??活動是工作或任務的一個通用術語。一個活動可以是一個任務,還可以是一個當前流程的子處理流程; 其次,你還可以為活動指定不同的類型。常見活動如下:

          4.3 結構圖標

          ??結構圖標可以看做是整個流程活動的結構,一個流程中可以包括子流程。常見的結構有:

          4.4 網關圖標

          ??網關用來處理決策,有幾種常用網關需要了解:

          5.流程部署詳解

          5.1 部署實現

          ??我們先來看下流程部署的具體過程。代碼實現

          /**     * 部署流程     */    @Test    public void test3(){        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        RepositoryService repositoryService = processEngine.getRepositoryService();        Deployment deploy = repositoryService.createDeployment()                .addClasspathResource("holiday-request-new.bpmn20.xml")                .name("請假流程...")                .category("請假") // 分類                .tenantId("dpb") // 租戶id                .deploy();        System.out.println("deploy.getId() = " + deploy.getId());        System.out.println("deploy.getName() = " + deploy.getName());        System.out.println("deploy.getCategory() = " + deploy.getCategory());    }

          5.2 部署涉及表結構

          涉及到的三張表:

          部署資源表:act_ge_bytearray

          字段名稱備注
          ID_主鍵
          REV_版本號
          NAME_名稱部署的文件名稱,如:holiday-request-new.bpmn20.xml、holiday-request-new.bpmn20.png
          DEPLOYMENT_ID_部署ID
          BYTES_字節(二進制數據)
          GENERATED_是否系統生成0為用戶上傳,
          1為系統自動生成, 比如系統會 自動根據xml生 成png

          部署ID表:act_re_deployment

          字段名稱備注
          ID_主鍵
          NAME_名稱
          CATEGORY_分類
          TENANT_ID_租戶ID
          DEPLOY_TIME_部署時間
          DERIVED_FROM_來源于
          DERIVED_FROM_ROOT_來源于
          ENGINE_VERSION_流程引擎的版本

          流程表:act_re_procdef

          字段名稱備注
          ID_主鍵
          REV_版本號
          CATEGORY_分類流程定義的Namespace就是類別
          NAME_名稱
          KEY_標識
          VERSION_版本
          DEPLOYMENT_ID_部署ID
          RESOURCE_NAME_資源名稱流程bpmn文件名稱
          DGRM_RESOURCE_NAME_圖片資源名稱
          DESCRIPTION_描述
          HAS_START_FORM_KEY_擁有開始表單標識start節點是否存在formKey 0否 1是
          HAS_GRAPHICAL_NOTATION_擁有圖形信息
          SUSPENSION_STATE_掛起狀態暫停狀態 1激活 2暫停
          TENANT_ID_租戶ID

          注意:

          業務流程定義數據表。此表和ACT_RE_DEPLOYMENT是多對一的關系,即,一個部署的bar包里可能包含多個流程定義文件,每個流程定義文件都會有一條記錄在ACT_REPROCDEF表內,每個流程定義的數據,都會對于ACT_GE_BYTEARRAY表內的一個資源文件和PNG圖片文件。和ACT_GE_BYTEARRAY的關聯是通過程序用ACT_GE_BYTEARRAY.NAME與ACT_RE_PROCDEF.NAME_完成的

          5.3 掛起和激活

          ??部署的流程默認的狀態為激活,如果我們暫時不想使用該定義的流程,那么可以掛起該流程。當然該流程定義下邊所有的流程實例全部暫停。

          流程定義為掛起狀態,該流程定義將不允許啟動新的流程實例,同時該流程定義下的所有的流程實例都將全部掛起暫停執行。

          /**     * 掛起流程     */    @Test    public void test05(){        // 獲取流程引擎對象        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        RepositoryService repositoryService = processEngine.getRepositoryService();        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()                .processDefinitionId("holiday:1:4")                .singleResult();        // 獲取流程定義的狀態        boolean suspended = processDefinition.isSuspended();        System.out.println("suspended = " + suspended);        if(suspended){            // 表示被掛起            System.out.println("激活流程定義");            repositoryService.activateProcessDefinitionById("holiday:1:4",true,null);        }else{            // 表示激活狀態            System.out.println("掛起流程");            repositoryService.suspendProcessDefinitionById("holiday:1:4",true,null);        }    }

          具體的實現其實就是更新了流程定義表中的字段

          而且通過REV_字段來控制數據安全,也是一種樂觀鎖的體現了,如果要啟動一個已經掛起的流程就會出現如下的錯誤

          6.啟動流程實例

          ??然后我們來看看啟動流程實例的過程。實現代碼如下:

          /**     * 啟動流程實例     */    @Test    public void testRunProcess(){        // 獲取流程引擎對象        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        // 啟動流程實例通過 RuntimeService 對象        RuntimeService runtimeService = processEngine.getRuntimeService();        // 構建流程變量        Map<String,Object> variables = new HashMap<>();        variables.put("employee","張三") ;// 誰申請請假        variables.put("nrOfHolidays",3); // 請幾天假        variables.put("description","工作累了,想出去玩玩"); // 請假的原因        // 啟動流程實例,第一個參數是流程定義的id        ProcessInstance processInstance = runtimeService                .startProcessInstanceById("holiday:1:4", variables);// 啟動流程實例        // 輸出相關的流程實例信息        System.out.println("流程定義的ID:" + processInstance.getProcessDefinitionId());        System.out.println("流程實例的ID:" + processInstance.getId());        System.out.println("當前活動的ID:" + processInstance.getActivityId());    }

          ??當我們啟動了一個流程實例后,會在ACT_RU_*對應的表結構中操作,運行時實例涉及的表結構共10張:

          • ACT_RU_DEADLETTER_JOB 正在運行的任務表
          • ACT_RU_EVENT_SUBSCR 運行時事件
          • ACT_RU_EXECUTION 運行時流程執行實例
          • ACT_RU_HISTORY_JOB 歷史作業表
          • ACT_RU_IDENTITYLINK 運行時用戶關系信息
          • ACT_RU_JOB 運行時作業表
          • ACT_RU_SUSPENDED_JOB 暫停作業表
          • ACT_RU_TASK 運行時任務表
          • ACT_RU_TIMER_JOB 定時作業表
          • ACT_RU_VARIABLE 運行時變量表

          ??啟動一個流程實例的時候涉及到的表有

          • ACT_RU_EXECUTION 運行時流程執行實例
          • ACT_RU_IDENTITYLINK 運行時用戶關系信息
          • ACT_RU_TASK 運行時任務表
          • ACT_RU_VARIABLE 運行時變量表

          ACT_RU_EXECUTION表結構

          字段名稱備注
          ID_主鍵
          REV_版本號
          PROC_INST_ID_流程實例ID
          BUSINESS_KEY_業務主鍵ID
          PARENT_ID_父執行流的ID
          PROC_DEF_ID_流程定義的數據ID
          SUPER_EXEC_
          ROOT_PROC_INST_ID_流程實例的root流程id
          ACT_ID_節點實例ID
          IS_ACTIVE_是否存活
          IS_CONCURRENT_執行流是否正在并行
          IS_SCOPE_
          IS_EVENT_SCOPE_
          IS_MI_ROOT_
          SUSPENSION_STATE_流程終端狀態
          CACHED_ENT_STATE_
          TENANT_ID_租戶編號
          NAME_
          START_TIME_開始時間
          START_USER_ID_開始的用戶編號
          LOCK_TIME_鎖定時間
          IS_COUNT_ENABLED_
          EVT_SUBSCR_COUNT_
          TASK_COUNT_
          JOB_COUNT_
          TIMER_JOB_COUNT_
          SUSP_JOB_COUNT_
          DEADLETTER_JOB_COUNT_
          VAR_COUNT_
          ID_LINK_COUNT_

          創建流程實例后對應的表結構的數據

          ACT_RU_TASK 運行時任務表

          字段名稱備注
          ID_主鍵
          REV_版本號
          EXECUTION_ID_任務所在的執行流ID
          PROC_INST_ID_流程實例ID
          PROC_DEF_ID_流程定義數據ID
          NAME_任務名稱
          PARENT_TASK_ID_父任務ID
          DESCRIPTION_說明
          TASK_DEF_KEY_任務定義的ID值
          OWNER_任務擁有人
          ASSIGNEE_被指派執行該任務的人
          DELEGATION_委托人
          PRIORITY_優先級
          CREATE_TIME_創建時間
          DUE_DATE_耗時
          CATEGORY_類別
          SUSPENSION_STATE_是否掛起1代表激活 2代表掛起
          TENANT_ID_租戶編號
          FORM_KEY_
          CLAIM_TIME_拾取時間

          創建流程實例后對應的表結構的數據

          ACT_RU_VARIABLE 運行時變量表

          字段名稱備注
          ID_主鍵
          REV_版本號
          TYPE_參數類型可以是基本的類型,也可以用戶自行擴展
          NAME_參數名稱
          EXECUTION_ID_參數執行ID
          PROC_INST_ID_流程實例ID
          TASK_ID_任務ID
          BYTEARRAY_ID_資源ID
          DOUBLE_參數為double,則保存在該字段中
          LONG_參數為long,則保存在該字段中
          TEXT_用戶保存文本類型的參數值
          TEXT2_用戶保存文本類型的參數值

          創建流程實例后對應的表結構的數據

          ACT_RU_IDENTITYLINK 運行時用戶關系信息

          字段名稱備注
          ID_主鍵
          REV_版本號
          GROUP_ID_用戶組ID
          TYPE_關系數據類型assignee支配人(組)、candidate候選人(組)、owner擁有人,participant參與者
          USER_ID_用戶ID
          TASK_ID_任務ID
          PROC_INST_ID_流程定義ID
          PROC_DEF_ID_屬性ID

          創建流程實例后對應的表結構的數據:

          7.處理流程

          ??上面的流程已經流轉到了zhangsan這個用戶這里,然后可以開始審批了

          // 獲取流程引擎對象        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();        TaskService taskService = processEngine.getTaskService();        Task task = taskService.createTaskQuery()                .processDefinitionId("holiday:1:4")                .taskAssignee("zhangsan")                .singleResult();        // 添加流程變量        Map<String,Object> variables = new HashMap<>();        variables.put("approved",false); // 拒絕請假        // 完成任務        taskService.complete(task.getId(),variables);

          ??在正常處理流程中涉及到的表結構

          • ACT_RU_EXECUTION 運行時流程執行實例
          • ACT_RU_IDENTITYLINK 運行時用戶關系信息
          • ACT_RU_TASK 運行時任務表
          • ACT_RU_VARIABLE 運行時變量表

          ACT_RU_TASK 運行時任務表 :會新生成一條記錄

          ACT_RU_VARIABLE 運行時變量表:會記錄新的流程變量

          當然流程實例也可以掛起

          // 1.獲取ProcessEngine對象ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();// 2.獲取RuntimeServiceRuntimeService runtimeService = engine.getRuntimeService();// 3.獲取流程實例對象ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()    .processInstanceId("25001")    .singleResult();// 4.獲取相關的狀態操作boolean suspended = processInstance.isSuspended();String id = processInstance.getId();if(suspended){    // 掛起--》激活    runtimeService.activateProcessInstanceById(id);    System.out.println("流程定義:" + id + ",已激活");}else{    // 激活--》掛起    runtimeService.suspendProcessInstanceById(id);    System.out.println("流程定義:" + id + ",已掛起");}

          啟動第二個流程實例后再查看相關的表結構時,對他們的關系理解會更加的清楚一些

          啟動一個新的流程實例對應的就會產生兩條記錄

          IDENTITYLINK中會記錄每次流程操作的信息

          流程變量數據,及時key 相同,但是屬于不同的流程實例相互間也是隔離的

          8.完成一個流程

          ??然后我們把第一個流程處理完成

          ProcessEngine processEngine = cfg.buildProcessEngine();TaskService taskService = processEngine.getTaskService();Task task = taskService.createTaskQuery()    .processDefinitionId("holiday:1:4")    .taskAssignee("lisi")    .singleResult();// 添加流程變量Map<String,Object> variables = new HashMap<>();variables.put("approved",false); // 拒絕請假// 完成任務taskService.complete(task.getId(),variables);

          處理完了一個工作流程后,我們來看看相關的表結構信息

          首先我們會發現

          • ACT_RU_EXECUTION 運行時流程執行實例
          • ACT_RU_IDENTITYLINK 運行時用戶關系信息
          • ACT_RU_TASK 運行時任務表
          • ACT_RU_VARIABLE 運行時變量表

          這四張表中對應的數據都沒有了,也就是這個流程已經不是運行中的流程了。然后在對應的歷史表中我們可以看到相關的信息

          • 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_HI_ACTINST 歷史的流程實例

          字段名稱備注
          ID_主鍵
          PROC_DEF_ID_流程定義ID
          PROC_INST_ID_流程實例ID
          EXECUTION_ID_執行ID
          ACT_ID_節點實例ID
          TASK_ID_任務ID
          CALL_PROC_INST_ID_調用外部的流程實例ID
          ACT_NAME_節點名稱
          ACT_TYPE_節點類型
          ASSIGNEE_處理人
          START_TIME_開始時間
          END_TIME_結束時間
          DURATION_耗時
          DELETE_REASON_刪除原因
          TENANT_ID_租戶編號

          ACT_HI_IDENTITYLINK 歷史的流程運行過程中用戶關系

          字段名稱備注
          ID_主鍵
          GROUP_ID_組編號
          TYPE_類型
          USER_ID_用戶編號
          TASK_ID_任務編號
          CREATE_TIME_創建時間
          PROC_INST_ID_流程實例編號
          SCOPE_ID_
          SCOPE_TYPE_
          SCOPE_DEFINITION_ID_

          ACT_HI_PROCINST 歷史的流程實例

          字段名稱備注
          ID_主鍵
          PROC_INST_ID_流程實例ID
          BUSINESS_KEY_業務主鍵
          PROC_DEF_ID_屬性ID
          START_TIME_開始時間
          END_TIME_結束時間
          DURATION_耗時
          START_USER_ID_起始人
          START_ACT_ID_起始節點
          END_ACT_ID_結束節點
          SUPER_PROCESS_INSTANCE_ID_父流程實例ID
          DELETE_REASON_刪除原因
          TENANT_ID_租戶編號
          NAME_名稱

          ACT_HI_TASKINST 歷史的任務實例

          字段名稱備注
          ID_主鍵
          PROC_DEF_ID_流程定義ID
          TASK_DEF_KEY_任務定義的ID值
          PROC_INST_ID_流程實例ID
          EXECUTION_ID_執行ID
          PARENT_TASK_ID_父任務ID
          NAME_名稱
          DESCRIPTION_說明
          OWNER_實際簽收人 任務的擁有者簽收人(默認為空,只有在委托時才有值)
          ASSIGNEE_被指派執行該任務的人
          START_TIME_開始時間
          CLAIM_TIME_任務拾取時間
          END_TIME_結束時間
          DURATION_耗時
          DELETE_REASON_刪除原因
          PRIORITY_優先級別
          DUE_DATE_過期時間
          FORM_KEY_節點定義的formkey
          CATEGORY_類別
          TENANT_ID_租戶

          ACT_HI_VARINST 歷史的流程運行中的變量信息:流程變量雖然在任務完成后在流程實例表中會刪除,但是在歷史表中還是會記錄的

          字段名稱備注
          ID_主鍵
          PROC_INST_ID_流程實例ID
          EXECUTION_ID_指定ID
          TASK_ID_任務ID
          NAME_名稱
          VAR_TYPE_參數類型
          REV_數據版本
          BYTEARRAY_ID_字節表ID
          DOUBLE_存儲double類型數據
          LONG_存儲long類型數據
          .....

          好了一個相對簡單的流程處理涉及到的相關表結構內容就介紹完了

          標簽:flowable-

          網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...

          在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...

          在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...

          石家莊有幾家北國超市?北國超市(天河店)地址:橋東區勝利北街243號北國超市(新百店)地址:橋西區中山西路139號(近中華街)北國超市(長江店)地址:長安區中山東路與翟穎北街交叉口向北100米(公交醫院附近)。北國超市(育才街店)地址:長安區育才街265號(近淮安東路)北國超市(北國店)地址:長安區中山東路188號北國超市(新市店)地址:橋東區中華南街585號(交管局對面)北國超市(長江店)地址:...

          安徽毫州屬于哪個市 亳州屬于安徽東部嗎?亳州為什么叫亳州? 亳州市位于安徽省北部和安徽省北部。位于安徽省馬鞍山市北部。亳州市是安徽省的地級市,未來宜人宜居。它是中國古代著名醫生華佗的家鄉,也是中國最大的中草藥配送基地。中草藥的年營業額非常大。亳州也是安徽北部重要的交通樞紐,年勞務輸出人口相對較大。 安徽省亳州市屬于哪個市? 安微省毫州市是一個成立于1990年的縣級市,隸屬于蒙城縣、渦陽縣、...

          成都限行單雙號應該怎么開?成都限行單雙號是按機動車號牌最后一位阿拉伯數字實行單號單日、雙號雙日行駛(單號為1、3、5、7、9,雙號為2、4、6、8、0)。限行時間是重污染天氣紅色預警期間,工作日的3:00至24:00(公休日因法定節假日調休為工作日的,不限行)。特殊車輛是不限行的,也可以買新能源車不限行。成都單雙號限號區域范圍?限行區域、范圍:成都市繞城高速(G4202)(不含)以內所有道路。限行...

          TOP
          国产初高中生视频在线观看|亚洲一区中文|久久亚洲欧美国产精品|黄色网站入口免费进人
          1. <nobr id="easjo"><address id="easjo"></address></nobr>

              <track id="easjo"><source id="easjo"></source></track>
              1. 
                

              2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
              3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>