【bpmn.js】 学习笔记(更新中...)

背景

基于业务,我们要开发一个 OA 审批流程系统,前端决定采用 bpmn.jsform-create-designer

前期参考资料

http://82.157.68.9/#/login

概念学习(task/event)
全网最详bpmn.js教材目录
符号解释下载地址

bpmn2.0 业务过程模型和符号

遇到的问题

1. console Error: failed to parse document as <bpmn:Definitions>

引入 xml 字符串文件的时候:

var 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:omgdi="http://www.omg.org/spec/DD/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" isExecutable="false">
    <startEvent id="StartEvent_1y45yut" name="开始">
    <outgoing>SequenceFlow_0h21x7r</outgoing>
    </startEvent>
    <task id="Task_1hcentk">
    <incoming>SequenceFlow_0h21x7r</incoming>
    </task>
    <sequenceFlow id="SequenceFlow_0h21x7r" sourceRef="StartEvent_1y45yut" targetRef="Task_1hcentk" />
</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:BPMNShape id="Task_1hcentk_di" bpmnElement="Task_1hcentk">
        <omgdc:Bounds x="240" y="80" width="100" height="80" />
    </bpmndi:BPMNShape>
    <bpmndi:BPMNEdge id="SequenceFlow_0h21x7r_di" bpmnElement="SequenceFlow_0h21x7r">
        <omgdi:waypoint x="188" y="120" />
        <omgdi:waypoint x="240" y="120" />
    </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>`

这里的文件格式,并不符合目前我所使用的 "bpmn-js": "^11.2.0" 解析所需的文件格式。
解决思路:去 bpmn-js 项目中查看正确格式的 xml文件:

正确demo文件格式

export const xmlStr = `<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
    <bpmn:process id="Process_1" isExecutable="false">
        <bpmn:startEvent id="StartEvent_1" />
        <bpmn:task id="Task_1" />
    </bpmn: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 x="173" y="102" width="36" height="36" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape id="Task_1_di" bpmnElement="Task_1">
                <dc:Bounds x="353" y="80" width="100" height="80" />
            </bpmndi:BPMNShape>
        </bpmndi:BPMNPlane>
    </bpmndi:BPMNDiagram>
</bpmn:definitions>`

2. 引入 xml 格式的字符串,使用 importXML 函数,页面上并没有画出流程图。

原代码:

import BpmnModeler from 'bpmn-js/lib/Modeler'
const canvasRef = ref()
const bpmnModeler = new BpmnModeler({
    container: canvasRef.value
})

const success = () => {
    console.log('创建成功')
}

onMounted(async() => {
    try {
        const result = await bpmnModeler.importXML(xmlStr)
        const { warnings } = result
        console.log(warnings)
        success()
    } catch (err) {
        console.error(err)
    }
})

这里的 bpmnModeler 必须是一个响应式数据。正确代码:

import BpmnModeler from 'bpmn-js/lib/Modeler'
const canvasRef = ref()
const bpmnModeler = ref(null)

const success = () => {
    console.log('创建成功')
}

onMounted(async() => {
    bpmnModeler.value = new BpmnModeler({
        container: canvasRef.value
    })
    try {
        const result = await bpmnModeler.value.importXML(xmlStr)
        const { warnings } = result
        console.log(warnings)
        success()
    } catch (err) {
        console.error(err)
    }
})

3. 使用右侧属性栏,需要安装三个库,具体请参考:

https://github.com/bpmn-io/bpmn-js-examples/tree/master/properties-panel

4. 打开一个新的画布来创建流程图:

const CustomTranslate = {
        translate: ['value', customTranslate]
    }
    bpmnModeler.value = new BpmnModeler({
        container: canvasRef.value,
        propertiesPanel: {
            parent: '#js-properties-panel'
        },
        additionalModules: [
            BpmnPropertiesProviderModule,
            BpmnPropertiesPanelModule,
            CamundaPlatformPropertiesProviderModule,
            CustomTranslate
        ],
        moddleExtensions: {
            camunda: camundaModdleDescriptor
        }
    })
    try {
        const result = props.xml
            ? await bpmnModeler.value.importXML(props.xml)  // 打开已有的流程图进行编辑
            : await bpmnModeler.value.createDiagram()		// 从头开始创建流程图
        const { warnings } = result
        console.log(warnings)
        success()
    } catch (err) {
        console.error(err)
    }

5. 定制化 properties-panel 来支持为流程图中的 user task 设置业务的属性写到 bpmn.xml 文件中。

参考资料
https://github.com/bpmn-io/bpmn-js-examples/tree/master/properties-panel
https://github.com/bpmn-io/bpmn-js-examples/tree/master/properties-panel-extension
https://github.com/bpmn-io/bpmn-js-examples/tree/master/properties-panel-async-extension

1. 先定义 getGroups 方法再注册
2. SelectEntry 的用法,用方法的方式使用,而不是<SelectEntry />
3. 有异步的请求,所以参考 https://github.com/bpmn-io/bpmn-js-examples/tree/master/properties-panel-async-extension

6. 支持画布上的快捷键。

bpmnModeler.value = new BpmnModeler({
    container: canvasRef.value,
    keyboard: {
        bindTo: window
    }
})

bpmn 支持的快捷键有:

ctrl + z : 撤销
ctrl + y : 恢复
ctrl + c : 复制
ctrl + v : 粘贴
ctrl + + : 放大
ctrl + - : 缩小
ctrl + 0 : 恢复
ctrl + del : 删除
ctrl + 箭头 : 上下左右移动

7. viewer 的 缩放和拖动画布功能

import MoveCanvasModule from 'diagram-js/lib/navigation/movecanvas'

const handleFitViewport = () => {
    const canvas = bpmnViewer.value.get('canvas')
    if (!canvas) {
        return
    }
    canvas.zoom('fit-viewport', 'auto')
}

const handleZoomViewport = zoomOut => {
    const canvas = bpmnViewer.value.get('canvas')
    if (!canvas) {
        return
    }
    let zoom = canvas.zoom()
    zoom += (zoomOut ? -0.1 : 0.1)
    canvas.zoom(zoom)
}

bpmnViewer.value = new BpmnViewer({
        container: canvasRef.value,
        height: 420,
        additionalModules: [
            MoveCanvasModule
        ]
    })

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值