.NET 开源工作流: Slickflow流程引擎高级开发(十) -- BpmnJS流程设计器集成

前言: 在Slickflow产品开发过程中,前端流程设计器经历了几个不同的版本(jsPlumb, mxGraph等),目的是为了在设计流程时的用户体验更加良好,得到客户的好评和认可。BpmnJS流程设计器的集成,更加让客户体验到了优秀的前端流程设计器带来的改变。通过这篇文章的介绍,让我们来认识一下Slickflow产品对BpmnJS设计器的集成和使用。

BPMN(Business Process Modeling Notation)是一种流程建模的通用和标准语言,用来绘制业务流程图,其好处是便于业务人员和技术人员共同参与对流程的分析和维护,其容易理解,更大程度地能够消除节点标识的歧义。目前BPMN的版本是2.0版本,关于BPMN标准的详细介绍,可以通过以下文章进行了解:

https://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地址如下:https://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文件的下载,便于流程设计人员体验和文件交互。

http://demo.slickflow.com/sfd/

1)基本绘制操作

一个非常典型的企业业务过程之请假流程示例如下:

 

 2)模板创建

企业中有一些常见的业务流程,也可以通过流程模板来配置创建,Demo中提供了常见的序列,分支和多实例会签等模式模板,方便用户创建流程。

 Slickflow产品流程设计器的特色之一就是可以通过Slickflow.Graph类库,使用C#代码语法来创建流程图,其中主要包括了节点集合以及节点在画布上布局和位置关系。尤其是分支结构的图形中,需要计算分支节点和合并节点的位置关系,详细使用可以参考前期博客文章(https://www.cnblogs.com/slickflow/p/11936786.html),模板创建代码示例如下:

pmb.Start("start")
  .Task(
        VertexBuilder.CreateTask("Task-001", "task001")
  )
  .AndSplit("and-split", "andsplit001")
  .Parallels(
        () => pmb.Branch(
            () => pmb.Task("task-010", "task010")
        )
        , () => pmb.Branch(
             () => pmb.Task("task-020", "task020")
         )
  )
  .AndJoin("and-join", "andjoin001")
  .Task("task-100", "task100")
  .End("end")
  .Serialize();

3) 流程模板创建动画演示

 

六:总结

集成BpmnJS流程设计器,得到了客户的好评和认可,这是一款业界公认的优秀流程设计器,希望更多的企业客户可以使用。

Slickflow开源项目网站地址:https://github.com/besley/slickflow

欢迎下载使用!

    
posted on 2022-08-29 21:52  slickflowteam  阅读(3944)  评论(0编辑  收藏  举报