提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 项目中需要前端做一个流程设计器,后端拿到流程数据去执行相关任务。前端使用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;
总结
工作准则:多做多错,少错少错、不做不错。