因为项目组需要一个工作流,所以我也是第一次使用bpmn-js工作流。

做的前后端分离的版本,前端是vue-element框架,后端是activiti的。

写这篇主要是为了记录(仅记录前端)自己从开始搭建看的教学贴 & 中间遇到的一些小问题的解决方法,如果后续还有别的问题也都会一并更新到这里,内容比较多。

(先放一下自己搭建好的工作流绘制页面)

bpmn官网: https://bpmn.io/toolkit/bpmn-js/

bpmn官方在线绘制流程图:https://demo.bpmn.io/

如果想细学LinDaiDai大佬写的教程比较全面:全网最详bpmn.js教材目录

1.搭建bpmn-js

前端搭建bpmn的教程一搜全都有,这个就不细写了,放下当时我搭建时看的教程。一个是搭建,一个是汉化,搭建后自己看到部分没有汉化后的可以自己再在汉化文件里自己写。

(1)前端搭建:vue中bpmn-js的使用(创建,编辑,使用)

(2)这个里面的汉化是目前比较完整的汉化:关于流程设计器: bpmn.js 彻底汉化

(3)左右侧工具栏的样式:

        调整侧边栏样式(最后有作者提供的样式git地址)

        ps:如果觉得原生的不好看可以换,如果觉得还行就不用换了

2.关于bpmn最上面一行让人眼馋的操作小功能按钮(包括但不限于放大、缩小、还原等功能)

        VUE+bpmn.js+iview 页面绘制流程图 里面的代码有这些小按钮的方法~

3.根据实际用户操作情况可能会涉及到更改右侧属性面板properties-panel的情况

        因为我的“用户任务”的代理人需要弹窗选择然后再写入到bpmn中,而不是输入框的形式,所以我需要找到更改右侧属性面板properties-panel的方法。

        有以下两种更改方式::

(1)如果不要下载的依赖里的右侧操作面板properties-panel的所有东西!推荐看:

        bpmnjs自定义右侧属性面板properties-panel 以及LinDaiDai大佬的教程全网最详bpmn.js教材-properties-panel篇(下)里也有写。

(2)如果只是想改里面部分的操作方式,而不是整改都换掉,比如只是将一个“input”框改写为“select”,推荐看:

        bpmn-js-properties-panel改造尝试,思路代码

        我是选的第二种的方式,但是我的水平有点低,我只看懂了一半,并且我需要在面板上增加一个按钮来弹窗,举一反三我是真的改不出来了,于是我又搜到了下面的更改方式,这个真的很简单!!

        右侧属性面板中执行人,候选人与候选组可以通过 用户、机构(角色)选择

上面的教程中js页面里拼接的方法,在自己写的工作流页面里可以通过写window.xxx来使用(我也不知道这么用对不对,但是目前用没出现什么问题)

放一下我自己写这块的部分代码:

mounted() {
    window.openSingleUserDlg = this.openUserDlag 
    //openSingleUserDlg 是我拼接里button的方法
},
methods: {
    openUserDlag(){
      this.handleDialogWin = true
    },
},

4.保存的时候

        这个本来看别人写的bpmn也没有很复杂,但是我做到这块的时候和后端纠结了好久,我就单独拿出来写一下。

(1)给activiti后端传参数的问题

        后端当时参照的样例是闲鹿写的一个前后端不分离的bpmn工作流+activiti,然后因为不分离,所以当时保存的时候传的参数里面有一个“json”还有一个“svg”。

        svg格式的可以用bpmn自带的saveSVG()这个来生成,但是json却是我自己通过xml转json传给后端的,但是后端接收总是报错:

        “org.activiti.bpmn.exceptions.XMLException: Error writing BPMN XML”

        后来看了好久才意识到json可能是大佬自己拼出来的.....我还特意装了x2js依赖来将xml转成json结果还是不行,最后我和后端商量了一下,我传xml和svg格式的给他,然后他在他那边处理。

       关于自己根据xml拼接json的思路可以看看这个:vue项目中使用bpmn-流程图xml文件中节点属性转json结构

        这里也放一下闲鹿的工作流git,感兴趣的可以自己下下来研究一下:

        闲鹿工作流-开源工作流管理系统~git地址

(2)activiti接收到的xml参数里如含有camunda等字符串,需要替换

        因为bpmn适配的是camunda,而我的后端是activiti,所以这里还有一个坑:xml格式的camunda往activiti替换,然后回显的时候还需要再替换回来。

        或者就直接安装网上一个大佬写的适配activiti插件“houtaroy-bpmn-js-properties-panel-activiti”。

//下载一个插件
npm i houtaroy-bpmn-js-properties-panel-activiti
//引入
import propertiesProviderModule from 'houtaroy-bpmn-js-properties-panel-activiti/lib/provider/activiti';

        回归正题,使用camunda时保存和回显需替换的代码方法:

async saveModel() {
    const result = await this.bpmnModeler.saveXML({ format: true });
    const xml = result.xml;
    xml = this.formXML(xml);
    ......
},

// 保存的时候camunda转activiti
formXML(data){
    let temp = data.replace(/camunda/ig,"activiti");
    temp = temp.replace(/FormField/ig,"formProperty");
    return temp ;
},

// 回显的时候activiti转camunda
reformXML(data){
    let temp = data.replace(/activiti/ig,"camunda");
    temp = temp.replace(/formProperty/ig,'FormField');
    return temp ;
},

(3)后台使用activiti,流程配置时勾选Executable(汉化过后就是 可执行文件)

        害怕忘记的话也可以前端一开始就写成true

5.一点小细节

(1)关于最外面的<bpmn:definitions>标签不同的问题

        在一开始页面中没有流程图的时候,做法一般都是设置一个默认的xmlStr生成一个默认的开始流程,但是我搜到的、教程里的等等,都不太一样,我见到的就三种了,分别是<process>、<bpmn:process>、<bpmn2:process> 。

        虽然都能显示出来,但是这个关系到画布的监听shape.type的值的判断、或者赋值的问题,所以一开始一旦定下来了,就不要轻易去更换,除非前端或后端遇到什么问题。

        我放一下这三种不同的xmlStr

this.xmlStr = `<?xml version="1.0" encoding="UTF-8"?>
          <bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                            xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" 
                            xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" 
                            xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" 
                            id="Definitions_092z8lr" 
                            targetNamespace="http://bpmn.io/schema/bpmn" 
                            exporter="bpmn-js (https://demo.bpmn.io)" 
                            exporterVersion="9.0.3">
            <bpmn:process id="Process_1" name="" isExecutable="false" camunda:versionTag="">
              <bpmn:startEvent id="StartEvent_1663frp" name="开始" />
            </bpmn:process>
            <bpmndi:BPMNDiagram id="BPMNDiagram_1">
              <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0nmeuzf">
                <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1663frp">
                  <dc:Bounds x="156" y="81" width="36" height="36" />
                  <bpmndi:BPMNLabel>
                    <dc:Bounds x="163" y="124" width="22" height="14" />
                  </bpmndi:BPMNLabel>
                </bpmndi:BPMNShape>
              </bpmndi:BPMNPlane>
            </bpmndi:BPMNDiagram>
          </bpmn:definitions>`;



this.xmlStr = `<?xml version="1.0" encoding="UTF-8"?>
           <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 
                        xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" 
                        xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" 
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                        id="sid-38422fae-e03e-43a3-bef4-bd33b32041b2" 
                        targetNamespace="http://bpmn.io/bpmn" 
                        exporter="bpmn-js (https://demo.bpmn.io)" 
                        exporterVersion="5.1.2">
                <process id="Process_1" name="" isExecutable="false" camunda:versionTag="">
                  <startEvent id="StartEvent_1y45yut" name="开始" />
                </process>
                <bpmndi:BPMNDiagram id="BpmnDiagram_1">
                  <bpmndi:BPMNPlane id="BpmnPlane_1" bpmnElement="Process_1">
                    <bpmndi:BPMNShape id="StartEvent_1y45yut_di" bpmnElement="StartEvent_1y45yut">
                      <omgdc:Bounds x="152" y="102" width="36" height="36" />
                      <bpmndi:BPMNLabel>
                        <omgdc:Bounds x="160" y="145" width="22" height="14" />
                      </bpmndi:BPMNLabel>
                    </bpmndi:BPMNShape>
                  </bpmndi:BPMNPlane>
                </bpmndi:BPMNDiagram>
              </definitions>`



this.xmlStr = `<?xml version="1.0" encoding="UTF-8"?>
       <bpmn2:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                          xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" 
                          xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" 
                          xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" 
                          xmlns:di="http://www.omg.org/spec/DD/20100524/DI"     
                          xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" 
                          id="sample-diagram" 
                          targetNamespace="http://bpmn.io/schema/bpmn">
            <bpmn2:process id="Process_1" name="" isExecutable="false" camunda:versionTag="">
              <bpmn2:startEvent id="StartEvent_1"/>
            </bpmn2:process>
            <bpmndi:BPMNDiagram id="BPMNDiagram_1">
              <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
                <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
                  <dc:Bounds height="36.0" width="36.0" x="412.0" y="240.0"/>
                </bpmndi:BPMNShape>
              </bpmndi:BPMNPlane>
            </bpmndi:BPMNDiagram>
          </bpmn2:definitions>`

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐