.NET 開源工作流: Slickflow流程引擎高級開發(十) — BpmnJS流程設計器集成

前言: 在Slickflow產品開發過程中,前端流程設計器經歷了幾個不同的版本(jsPlumb, mxGraph等),目的是為了在設計流程時的用戶體驗更加良好,得到客戶的好評和認可。BpmnJS流程設計器的集成,更加讓客戶體驗到了優秀的前端流程設計器帶來的改變。通過這篇文章的介紹,讓我們來認識一下Slickflow產品對BpmnJS設計器的集成和使用。

BPMN(Business Process Modeling Notation)是一種流程建模的通用和標準語言,用來繪製業務流程圖,其好處是便於業務人員和技術人員共同參與對流程的分析和維護,其容易理解,更大程度地能夠消除節點標識的歧義。目前BPMN的版本是2.0版本,關於BPMN標準的詳細介紹,可以通過以下文章進行了解:

//baike.baidu.com/item/BPMN/9818373?fr=aladdin

BpmnJS是一款Web流程設計器,可以繪製出符合BPMN2標準的流程圖,這使得業務分析人員和程式開發人員更加方便流程的管理和維護。BpmnJS由 Camunda 團隊研發,是一個 BPMN 2.0渲染工具包和web建模器。使得可以在瀏覽器中創建、嵌入和擴展 BPMN 流程圖。它採用JavaScript編寫,包含一個基礎的查看器,與「增強」後的建模器,可以嵌入到任何web應用程式中,Bpmn.js 內部依賴 diagram.jsbpmn-moddle 。其項目GitHub地址如下://github.com/bpmn-io/bpmn-js

如下圖,是一張BPMN標準的流程圖,在處理複雜流程邏輯時候,需要業務人員和技術人員都容易理解,並且互相交流通暢,作為業界公認的流程語義標準,這是BPMN2的優勢所在。

 

零:開發環境

Slickflow.Designer是集成BpmnJS的設計器項目,區別於傳統的Asp.NETCore項目,它搭建於node環境基礎之上,從項目文件package.json裡面可以看到項目依賴的文件類庫,初次配置時,需要在ClientApp目錄下執行npm install 命令來安裝所需的文件包。此外,編譯調試發布時候,使用webpack.config來管理文件部署。作為技術開發人員,需要熟悉nodejs開發環境和項目部署等知識,這是跟Asp.NETCore項目開發方式的很大差別。

一:BpmnJS Modeler介紹
Modeler 用於讀寫Bpmn的Xml文檔維護,等於元數據模型定義器。它將xml文件解析為對象樹,該樹在建模期間編輯和驗證,並在保存建模的時候導出為XML。其中有兩個核心庫:
moddle:對象樹的定義和處理
moddle-xml :基於moddle庫讀寫XML文檔。
此外也提供了簡單的操作介面,比如:fromXML和toXML

Modeler的初始化配置構造如程式碼示例:

var bpmnModeler = new BpmnModeler({
  container: '#js-canvas',
  propertiesPanel: {
    parent: '#js-properties-panel'
    },
    moddleExtensions: {
        sf: sfModdleDescriptor,
        magic: magicModdleDescriptor
    },
  additionalModules: [
    BpmnPropertiesPanelModule,
      SfCommandInterceptor,
      SfCommandExtension,
      identityPropertiesProviderModule,
      actionPropertiesProviderModule,
      transitionPropertiesProviderModule,
      sectionPropertiesProviderModule,
      boundaryPropertiesProviderModule,
      gatewayPropertiesProviderModule,
      multisignPropertiesProviderModule,
      triggerPropertiesProviderModule,
      servicetaskPropertiesProviderModule,
      scripttaskPropertiesProviderModule,
      performersPropertiesProviderModule
  ]
});

在初始化構建時候,提供了moddler的擴展和附加模組,這是訂製化開發部分的個性集成,客戶也可以根據自身的業務需要來繼續擴充所需要的流程流轉控制參數。  

二:BpmnJS Viewer介紹
Viewer方便流程圖形的只讀展示,而不是像Modeler那樣可以編輯。當用戶需要查看流程進度的時候,需要根據不同進度狀態來渲染各個流程節點和路徑,這個時候使用BpmnJS Viewer就能完成。其示例程式碼如下:
 
const bpmnViewer = new Viewer({
  container: $('#js-canvas'),
  height: 600,
  additionalModules: [
    MoveModule,
    ModelingModule, 
    MoveCanvasModule
  ]
})

其渲染的圖形效果如下圖所示:

 

 其中綠色節點表示流程當前所運行的節點位置,紅色連線表示已經運行過的路徑。

三:BpmnJS 屬性擴展面板開發
雖然BpmnJS提供了標準BPMN2的XML定義,但是作為流程引擎的高級特性實現,還是需要各個廠商來訂製開發的,這樣就增加了extensionElements節點的配置,其中的xml片段示例如下:
    <bpmn2:task id="Activity_1kcsr5d" sf:guid="cf13dd79-df24-4503-92fe-88556238bf7e" name="Dept Manager Approval">
      <bpmn2:extensionElements>
        <sf:performers>
          <sf:performer name="部門經理" outerId="2" outerCode="depmanager" outerType="Role" />
        </sf:performers>
      </bpmn2:extensionElements>
      <bpmn2:incoming>Flow_149y4hy</bpmn2:incoming>
      <bpmn2:outgoing>Flow_0oks1po</bpmn2:outgoing>
    </bpmn2:task>

示例程式碼中,增加了執行角色的定義,而執行角色一般又和業務系統的組織機構數據關聯,所以需要靈活定義,要實現跟業務系統的對接便利性。屬性面板的數據配置如下:

 

 四:Slickflow流程定義描述器

在實現BPMN2標準時候,流程引擎核心需要負責對流程的解析和執行,一套穩定的,規範良好的軟體產品,更容易被客戶接受和認可,畢竟客戶也是需要在此基礎上做二次開發。Slickflow產品組在考慮自定義特性實現時候,更加關注產品是否精簡易讀,所以其定義方式也容易被程式開發人員掌握和接受。考慮到流程設計的複雜性,尤其是不同節點類型的詳細屬性,幾乎沒個客戶的考量都是不同的,所以採用了整體-分離模式,將各個離散的細節特性,通過不同的組裝模式組合到一起。

1) BpmnJS屬性面板默認模組

import {
  BpmnPropertiesPanelModule,
  BpmnPropertiesProviderModule
} from 'bpmn-js-properties-panel';

2) 擴展屬性的描述器

Slickflow引擎核心需要對自定義的流程節點特性進行處理,通過描述器可以固定特性名稱和限制條件等,載入描述的程式程式碼如下:

import sfModdleDescriptor from './slickflow/descriptors/sf';
import magicModdleDescriptor from './slickflow/descriptors/magic';
import identityModdleDescriptor from './slickflow/descriptors/identity';
import actionModdleDescriptor from './slickflow/descriptors/action';
import sectionModdleDescriptor from './slickflow/descriptors/section';
import boundaryModdleDescriptor from './slickflow/descriptors/boundary';
import transitionModdleDescriptor from './slickflow/descriptors/transition';
import performersModdleDescriptor from './slickflow/descriptors/performers';
import gatewayModdleDescriptor from './slickflow/descriptors/gateway';
import multisignModdleDescriptor from './slickflow/descriptors/multisign';
import servicetaskModdleDescriptor from './slickflow/descriptors/servicetask';
import scripttaskModdleDescriptor from './slickflow/descriptors/scripttask';

sfModdleDescriptor.types.push(identityModdleDescriptor.identity);
sfModdleDescriptor.types.push(transitionModdleDescriptor.transition);
sfModdleDescriptor.types.push(gatewayModdleDescriptor.gateway);
sfModdleDescriptor.types.push(multisignModdleDescriptor.multisign);
sfModdleDescriptor.types = sfModdleDescriptor.types.concat(actionModdleDescriptor.action);
sfModdleDescriptor.types = sfModdleDescriptor.types.concat(sectionModdleDescriptor.section);
sfModdleDescriptor.types = sfModdleDescriptor.types.concat(boundaryModdleDescriptor.boundary);
sfModdleDescriptor.types = sfModdleDescriptor.types.concat(servicetaskModdleDescriptor.service);
sfModdleDescriptor.types = sfModdleDescriptor.types.concat(scripttaskModdleDescriptor.script);
sfModdleDescriptor.types = sfModdleDescriptor.types.concat(performersModdleDescriptor.performers);

3)屬性維護提供器

對增加的每一個屬性映射到相應的介面控制項,讀寫屬性的數值,並用於維護。

import actionPropertiesProviderModule from './slickflow/provider/action';
import transitionPropertiesProviderModule from './slickflow/provider/transition';
import sectionPropertiesProviderModule from './slickflow/provider/section/';
import boundaryPropertiesProviderModule from './slickflow/provider/boundary/';
import gatewayPropertiesProviderModule from './slickflow/provider/gateway/';
import multisignPropertiesProviderModule from './slickflow/provider/multisign/';
import triggerPropertiesProviderModule from './slickflow/provider/trigger/';
import servicetaskPropertiesProviderModule from './slickflow/provider/servicetask/';
import scripttaskPropertiesProviderModule from './slickflow/provider/scripttask/';
import performersPropertiesProviderModule from './slickflow/provider/performers/';
import identityPropertiesProviderModule from './slickflow/provider/identity';

4)bpmnModeler的初始化載入

var bpmnModeler = new BpmnModeler({
  container: '#js-canvas',
  propertiesPanel: {
    parent: '#js-properties-panel'
    },
    moddleExtensions: {
        sf: sfModdleDescriptor,
        magic: magicModdleDescriptor
    },
  additionalModules: [
    BpmnPropertiesPanelModule,
      SfCommandInterceptor,
      SfCommandExtension,
      identityPropertiesProviderModule,
      actionPropertiesProviderModule,
      transitionPropertiesProviderModule,
      sectionPropertiesProviderModule,
      boundaryPropertiesProviderModule,
      gatewayPropertiesProviderModule,
      multisignPropertiesProviderModule,
      triggerPropertiesProviderModule,
      servicetaskPropertiesProviderModule,
      scripttaskPropertiesProviderModule,
      performersPropertiesProviderModule
/*      expressionPropertiesProviderModule,*/
/*      customContextModule*/
  ]
});

 五:Demo體驗

為了方便各類用戶的流程設計需求,可以在官網設計器地址進行體驗,設計器本身提供XML和SVG文件的下載,便於流程設計人員體驗和文件交互。

//demo.slickflow.com/sfd/

1)基本繪製操作

一個非常典型的企業業務過程之請假流程示例如下:

 

 2)模板創建

企業中有一些常見的業務流程,也可以通過流程模板來配置創建,Demo中提供了常見的序列,分支和多實例會簽等模式模板,方便用戶創建流程。

 

 

六:總結

集成BpmnJS流程設計器,得到了客戶的好評和認可,這是一款業界公認的優秀流程設計器,希望更多的企業客戶可以使用。