提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 项目中需要前端做一个流程设计器,后端拿到流程数据去执行相关任务。前端使用bpmn-js,后端使用flowable。
- 一、自定义Palette
- 二、重写Palette
- 三、自定义节点样式
- 四、bpmn的一些常用监听事件可以做自己的对应操作
- 五、自定义ContextPad
- 总结
前言
项目中需要前端做一个流程设计器,后端拿到流程数据去执行相关任务。前端使用bpmn-js,后端使用flowable。
效果图:
一、自定义Palette
1.使用 paletteProvider 同名参数 覆盖 默认 paletteProvider 构造函数
import rerenderPaletteProvider from "./rewritePaletteProvider"; const RerenderPalette = { __init__: ["paletteProvider"], paletteProvider: ["type", rerenderPaletteProvider] }; export default RerenderPalette;
复制
2.使用PaletteProvider配置自定义Palette
import PaletteProvider from "bpmn-js/lib/features/palette/PaletteProvider"; import { assign } from "min-dash"; import { createAction } from "../utils"; class RewritePaletteProvider extends PaletteProvider { constructor(palette, create, elementFactory, spaceTool, lassoTool, handTool, globalConnect) { super(palette, create, elementFactory, spaceTool, lassoTool, handTool, globalConnect, 2000); this._create = create; this._elementFactory = elementFactory; this._lassoTool = lassoTool; this._handTool = handTool; this._globalConnect = globalConnect; } getPaletteEntries() { const actions = {}, create = this._create, elementFactory = this._elementFactory, lassoTool = this._lassoTool, handTool = this._handTool, globalConnect = this._globalConnect; function createOutputLabelTask(event) { const acrossLinkTask = elementFactory.createShape({ type: "miyue:OutputLabelTask", }); create.start(event, acrossLinkTask); } assign(actions, { "create.service-task-scbq": { group: "任务", className: "miyue-output-label-task", title: "输出标签", action: { click: createOutputLabelTask, dragstart: createOutputLabelTask } }, }); return actions; } } RewritePaletteProvider.$inject = [ "palette", "create", "elementFactory", "spaceTool", "lassoTool", "handTool", "globalConnect" ]; export default RewritePaletteProvider;
复制
3.向additionalModules中添加自定义扩展
import Modeler from "bpmn-js/lib/Modeler"; import RewritePalette from "./RewritePalette"; new Modeler({ container:'', additionalModules:[RewritePalette] });
复制
4.效果图
二、重写Palette
1.将原有的Palette隐藏掉
.djs-accordion-palette.open { display: none; }
复制
2.搭建操作栏样式
<el-collapse> <el-collapse-item title="事件"> <div @mousedown="paletteChange($event, 'bpmn:StartEvent')" class="collapse-item"> <div class="icon-before start-event-icon"></div> <span>开始事件</span> </div> <div @mousedown="paletteChange($event, 'bpmn:EndEvent')" class="collapse-item"> <div class="icon-before end-event-icon"></div> <span>结束事件</span> </div> </el-collapse-item> <el-collapse-item title="数据读取"> <div style="padding-left: 16px"> <el-collapse> <el-collapse-item v-for="item in dataDbList" :title="item.dbNameCn" :key="item.id"> <div v-for="val in item.dataTables" :key="val.id" @mousedown="paletteChange($event, 'bpmn:ServiceTask', val)" class="collapse-item"> <div class="service-task-icon"></div> <span>{{ val.tabNameEn }}</span> </div> </el-collapse-item> </el-collapse> </div> </el-collapse-item> <el-collapse-item title="数据关联"> <div @mousedown="paletteChange($event, 'miyue:AcrossLinkTask')" class="collapse-item"> <div class="acrossLink-task-icon"></div> <span>横连接</span> </div> </el-collapse-item> <el-collapse-item title="数据输出"> <div @mousedown="paletteChange($event, 'miyue:OutputLabelTask')" class="collapse-item"> <div class="outputLabel-task-icon"></div> <span>输出标签</span> </div> </el-collapse-item> </el-collapse>
复制
3.点击操作栏调用节点创建事件
paletteChange(event, type, val) { //获取根节点 const rootElement = this.getModeler.get("canvas").getRootElement(); let elementFactory = this.getModeler.get("elementFactory"); let create = this.getModeler.get("create"); let branchShape = elementFactory.createShape({ type: type, }); create.start(event, branchShape); }
复制
4.效果图
三、自定义节点样式
"miyue:OutputLabelTask": function (parentGfx, element, attr) { // 渲染外层边框 const attrs = { fill: '#FFFFFF', fillOpacity: 1, stroke: getStrokeColor(element, defaultTaskColor), strokeWidth:'1px' }; //修改外层边框样式 element.width = 64; element.height = 56; renderer("bpmn:Activity")(parentGfx, element, attrs); // 自定义节点 const customIcon = svgCreate("image"); svgAttr(customIcon, { ...(attr || {}), width: element.width - 22, height: element.height - 22, x:11, y:11, href: labelIcon }); svgAppend(parentGfx, customIcon); //渲染lable renderEmbeddedLabel(parentGfx, element, "center-bottom"); return customIcon; }
复制
四、bpmn的一些常用监听事件可以做自己的对应操作
//节点创建时触发 modeler.on("commandStack.shape.create.postExecuted", (event) => {}); //双击节点时触发 modeler.on("element.dblclick", (event) => {}); //单击节点时出发 modeler.on("element.click", (event) => {}); //选中当前节点时触发 modeler.on("selection.changed", () => {});
复制
在双击节点时拿到节点信息弹出表单框,填写信息后将数据插入节点属性中。
将数据保存在节点属性中
//attribute 你要插入的数据 const attribute; modeler.get("modeling").updateProperties( modeler.get("elementRegistry").get(event.context.shape.id), attribute );
复制
五、自定义ContextPad
因为默认的ContextPad有很多功能,我只需要移除和连接。
修改前:
修改后:
1.使用contextPadProvider参数覆盖同名构造函数
import rewriteContextPadProvider from "./rewriteContextPadProvider"; const rewriteContextPad = { __init__: ["contextPadProvider"], contextPadProvider: ["type", rewriteContextPadProvider] }; export default rewriteContextPad;
复制
2.引入ContextPadProvider进行重写
import ContextPadProvider from "bpmn-js/lib/features/context-pad/ContextPadProvider"; class RewriteContextPadProvider extends ContextPadProvider { constructor( config, injector, eventBus, contextPad, modeling, elementFactory, connect, create, popupMenu, canvas, rules, translate, globalConnect ) { super( config, injector, eventBus, contextPad, modeling, elementFactory, connect, create, popupMenu, canvas, rules, translate, globalConnect, 2000 ); this._contextPad = contextPad; this._modeling = modeling; this._elementFactory = elementFactory; this._connect = connect; this._create = create; this._popupMenu = popupMenu; this._canvas = canvas; this._rules = rules; this._translate = translate; this._autoPlace = injector.get("autoPlace", false); this._globalConnect = globalConnect; } getContextPadEntries(element) { const actions = {}; const modeling = this._modeling; const globalConnect = this._globalConnect; const connect = this._connect; actions["enhancement-op"] = { group: "操作栏", className: "bpmn-icon-trash", title: "移除", action: { click: function (event, delElement) { modeling.removeElements([...(delElement.incoming || []), ...(delElement.outgoing || []), delElement]); } } }; actions["enhancement-op-1"] = { group: "操作栏", className: "bpmn-icon-connection-multi", title: "连接", action: { click: function (event, element) { connect.start(event, element); } } }; return actions; } } export default RewriteContextPadProvider;
复制
总结
工作准则:多做多错,少错少错、不做不错。