思路:BPMN的流程模拟启动,主要是通过生成令牌,并启动令牌模拟
流程模拟的开启需要关键性工具:bpmn-js-token-simulation,需要先行下载
注:BPMN2.0的流程模拟工具版本不同,启动方式也不一样,需要自行阅读源码或官方文档,本文主要正对的是0.10.0版本的simulation工具。
"bpmn-js-token-simulation": "^0.10.0",
在你的BPMN组件中引入
// 模拟流转流程
import tokenSimulation from "bpmn-js-token-simulation";
把他加载到BPMN对象中:
computed: {
additionalModules() {
const Modules = [];
....
// 模拟流转模块
if (this.simulation) {
Modules.push(tokenSimulation);
}
...
return Modules;
},
}
mounted() {
/*初始化Bpmn*/
this.initBpmnModeler();
},
methods: {
initBpmnModeler() {
this.bpmnModeler = new BpmnModeler({
...
additionalModules: this.additionalModules,
...
});
//此处开启模拟
this.processSimulation();
},
在初始化的时候我们来开启模拟,这就是第一步
第一步:开启模拟
this.simulation && this.bpmnModeler.get("toggleMode").toggleMode();
this.simulationStatus = !this.simulationStatus;
第二步:创建令牌并执行
令牌创建之前我们要有个意识:BPMN的开始节点在哪里?有几个开始节点?我们需要开启的节点是哪个?
因此,我们第一步是要获取到所有的开始节点,在这里我们要用到工具:elementRegistry,通过它我们就可以获取到所有的element对象
// 获取BPMN模拟器中的ElementRegistry对象
const elementRegistry = this.bpmnModeler.get('elementRegistry');
// 获取所有的开始事件节点
const startEvents = elementRegistry.filter(element => {
return element.type === 'bpmn:StartEvent';
});
通过筛选,我们得到了所有的开始节点
有了开始任务节点,就可以针对性的来创建令牌,并启动令牌。
创建令牌需要用到工具tokenSimulationBehavior,他提供BPMN模拟执行的行为设置。
通过打印我们可以看到,他有很多的处理函数。
在这里我们看到了bpmn:StartEvent这个事件,让我们看看他里面有什么
nice,我们可以看到,在他的原型上面有一个generate函数,可以用来生成令牌。
generate函数应该怎么使用呢?
让我们来看看他的源码:
StartEventHandler.prototype.generate = function(context) {
var self = this;
var element = context.element,
parentProcessInstanceId = context.parentProcessInstanceId;
var outgoingSequenceFlows = element.outgoing.filter(function(outgoing) {
return is(outgoing, 'bpmn:SequenceFlow');
});
// create new process instance
var parent = element.parent,
processInstanceId = this._processInstances.create(parent, parentProcessInstanceId);
outgoingSequenceFlows.forEach(function(connection) {
self._animation.createAnimation(connection, processInstanceId, function() {
self._eventBus.fire(CONSUME_TOKEN_EVENT, {
element: connection.target,
processInstanceId: processInstanceId
});
});
});
if (is(element.parent, 'bpmn:SubProcess')) {
return;
}
var startEvents = this._elementRegistry.filter(function(element) {
return is(element, 'bpmn:StartEvent');
});
this._eventBus.fire(UPDATE_ELEMENTS_EVENT, {
elements: startEvents
});
};
在这里我们可以看到,他需要一个上下文,
- element: 当前开始事件对象
- parentProcessInstanceId:父进程实例(流程定义)的 ID
那就可以知道了,我们可以通过传入这两个对象来创建一个令牌
OK,既然如此,我们就可以有针对性的来进行定义对象了
挑选一个开始事件
let context={
element:startEvents[0],
parentProcessInstanceId:startEvents[0].parent.id
}
将这个上下文传入后,那么这个节点的开启任务就创建成功了
const tokenSimulationBehavior = this.bpmnModeler.get('tokenSimulationBehavior');
tokenSimulationBehavior.handlers["bpmn:StartEvent"].generate(context)
最终效果如下: