步骤一:引入依赖
我的vue3项目使用的包管理器是yarn,各位按需使用自己的包管理器引入依赖即可,但是各依赖版本号一定要跟我的一样,不同的版本适配很差我研究了半天找到这些版本是可以适配用的,基本都是24年末25年初时间段发布的也算比较新了,看文档说是优化了性能,后续的新版本我再慢慢啃官方文档研究吧。
属性面板的官方的README地址:bpmn-js-examples/properties-panel/README.md at main · bpmn-io/bpmn-js-examples · GitHub
1. 最核心的流程绘制工具:
yarn add bpmn-js@15.0.0 -D
2. 配置流程节点的属性信息:
yarn add bpmn-js-properties-panel@5.20.0 -D
yarn add @bpmn-io/properties-panel@3.22.4 -D
3. 配置流程支持的任务:
yarn add camunda-bpmn-moddle@7.0.1 -D
安装结果如图:
步骤二:添加BPMN相关样式
找到脚手架中的 main.ts 文件,引入以下样式
/**
* 导入 bpmn-js 和 bpmn-js-properties-panel 所需的样式文件。
*
* 该代码块主要用于加载 bpmn-js 及其属性面板相关的 CSS 样式资源,
* 确保在使用 bpmn-js 渲染流程图时,界面能够正确显示所需的视觉效果。
*
* 样式文件说明:
* - `diagram-js.css`: 提供基础的流程图渲染样式。
* - `bpmn.css`: 包含 BPMN 图形元素的基本样式。
* - `bpmn-codes.css`: 定义 BPMN 图形中使用的编码样式。
* - `bpmn-embedded.css`: 针对嵌入式 BPMN 图形的样式优化。
* - `bpmn-js-properties-panel.css`: 提供属性面板的样式支持。
*/
import 'bpmn-js/dist/assets/diagram-js.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
import '@bpmn-io/properties-panel/dist/assets/properties-panel.css'
步骤三:准备一个基础的流程文件
我准备的基础流程xml如下,大家如果有自己的好的可以替换,保存的位置大家自己根据实际项目需求放就好了
export const xmlStr: string = `<?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>`
步骤四:创建流程设计器页面
注释:这一步比较自由每个脚手架创建方法都不一样,以下展示只是我的脚手架的创建页面方式,没什么特殊的技巧,有问题可以在文章下评论
4.1 创建 vue 本体文件
具体代码如下方便大家cv
<script lang="ts" setup>
/**
* 引入 BPMN XML 字符串,用于初始化 BPMN 图表。
*/
import { xmlStr } from '@/views/process/files/xmlStr'
/**
* 从 bpmn-js-properties-panel 包中引入模块,用于支持属性面板功能。
*/
import {
BpmnPropertiesPanelModule,
BpmnPropertiesProviderModule,
CamundaPlatformPropertiesProviderModule,
} from 'bpmn-js-properties-panel'
/**
* 引入 BpmnModeler 类,用于创建和操作 BPMN 图表。
*/
import BpmnModeler from 'bpmn-js/lib/Modeler'
/**
* 引入 Camunda Moddle 描述符,用于扩展 BPMN 模型以支持 Camunda 特性。
*/
import CamundaBpmnModdle from 'camunda-bpmn-moddle/resources/camunda.json'
/**
* 从 Vue 中引入生命周期钩子和响应式引用。
*/
import { onMounted, ref } from 'vue'
/**
* 定义 canvasRef,用于引用 BPMN 图表的容器 DOM 元素。
*/
const canvasRef = ref<HTMLDivElement | null>(null)
/**
* 定义 propertiesPanelRef,用于引用属性面板的容器 DOM 元素。
*/
const propertiesPanelRef = ref<HTMLDivElement | null>(null)
/**
* 在组件挂载完成后初始化 BPMN 图表和属性面板。
*
* @function onMounted
* @description
* 1. 检查 canvasRef 和 propertiesPanelRef 是否存在。
* 2. 创建 BpmnModeler 实例,配置容器、属性面板、附加模块和 Camunda 扩展。
* 3. 使用预定义的 BPMN XML 字符串导入图表模型。
*/
onMounted(() => {
if (canvasRef.value && propertiesPanelRef.value) {
// 初始化 BpmnModeler 实例,配置容器、属性面板和扩展模块。
const modeler = new BpmnModeler({
container: canvasRef.value,
propertiesPanel: {
parent: propertiesPanelRef.value,
},
additionalModules: [
BpmnPropertiesPanelModule,
BpmnPropertiesProviderModule,
CamundaPlatformPropertiesProviderModule,
],
moddleExtensions: {
camunda: CamundaBpmnModdle,
},
})
// 导入 BPMN XML 字符串并处理成功后的逻辑。
modeler.importXML(xmlStr).then(() => {
// 成功后操作(此处可添加具体逻辑)。
})
}
})
</script>
<template>
<div class="bpmn-container">
<!-- BPMN 图表的主画布区域 -->
<div ref="canvasRef" class="canvas" />
<!-- 属性面板区域 -->
<div ref="propertiesPanelRef" class="properties-panel" />
</div>
</template>
<style scoped>
.bpmn-container {
display: flex;
height: 100vh;
}
.canvas {
flex: 3; /* 占据 3/4 的宽度 */
border: 1px solid #ccc; /* 添加边框以便区分区域 */
}
.properties-panel {
flex: 1; /* 占据 1/4 的宽度 */
border-left: 1px solid #ccc; /* 左侧边框分隔画布和属性面板 */
overflow-y: auto; /* 支持垂直滚动 */
}
</style>
另外有一个注意点,我踩坑的,如果遇到相同问题可以按照我以下的方案解决,下面这段引入可能会遇到【bpmn-js-properties-panel】类型无法辨认,我没找到官方的@type包
/**
* 从 bpmn-js-properties-panel 包中引入模块,用于支持属性面板功能。
*/
import {
BpmnPropertiesPanelModule,
BpmnPropertiesProviderModule,
CamundaPlatformPropertiesProviderModule,
} from 'bpmn-js-properties-panel'
所以我采取的是自定义 declare,大家放在自己的【declarations.d.ts】文件里就好了,没有的话就新建一个呗
declare module 'bpmn-js-properties-panel';
4.2 创建一级菜单(流程管理)
4.3 创建二级菜单(流程设计器)
4.4 创建按钮
这一步可以不添加,只是我的分配角色权限功能树形结构数据勾选的时候展示有个BUG,一个按钮都没有的话,菜单就会显示不勾选,这是前端对于树形结构的叶子节点做了额外的判断,实际权限是有的,这个BUG我后续优化吧
4.5 分配权限
给当前登录admin账户绑定的超级管理员角色绑定菜单权限
4.6 重新登录查询界面
我这边二级菜单变成一级菜单是因为我在动态菜单里做了处理,如果一级菜单下只有一个二级菜单那么就把二级菜单作为一级菜单展示,可以看到xml已经导入画布,并且属性菜单已扩展成功。
后记
代码仓库:
https://gitee.com/wang-baohai/eal-pm-web.git
我是打算一个文章就是一个分支,后续我自己复习也好看,大家如果真的要跟项目也轻松点,所及即所得,本篇文章的分支是 process,下一篇文章打算做一下汉化操作,工作也比较忙,更新可能不快,但是我会坚持一直学习下去的。