vue项目中使用bpmn-节点篇

时间:2024-01-26 19:48:19

前情提要

  根据之前的操作,我们可以创建、导入、导出流程图,并对其进预览。通过此篇可以学到:

  • 为节点添加点击、鼠标悬浮等事件
  • 获取流程图内所有指定类型的节点
  • 通过外部更新节点名字
  • 获取节点实例的两种方法

step1:为节点添加点击、鼠标悬浮等事件

  方案:bpmnModeler中的eventBus,只要你要,只要它有

  代码:

const eventBus = this.bpmnModeler.get('eventBus');
// 注册节点事件,eventTypes中可以写多个事件
const eventTypes = ['element.click', 'element.hover'];
eventTypes.forEach((eventType) => {
  eventBus.on(eventType, (e) => {
    const {element} = e;
    if (!element.parent) return;
    if (!e || element.type === 'bpmn:Process') {
      return false;
    } else {
      if (eventType === 'element.click') {
        // 节点点击后想要做的处理
        // 此时想要点击节点后,拿到节点实例,通过外部输入更新节点名称
        this.currentElement = element;
      } else if (eventType === 'element.hover') {
        // 鼠标滑过节点后想要做的处理
        console.log('鼠标经过节点啦~');
      }
    }
  });
});
View Code

step2:获取流程图内所有指定类型的节点

  场景:需要获取流程图里所有的用户节点信息,以列表形式展示在另外地方。查了很多文档,并没有找到。事实证明,源码才是王道!  

  方案:elementRegistry提供了方案,并且支持过滤

  代码:

const elementRegistry = this.bpmnModeler.get('elementRegistry');
const userTaskList = elementRegistry.filter(
  (item) => item.type === 'bpmn:UserTask'
);

step3 : 通过外部更新节点名字

  方案:bpmnModeler的modeling,提供了updateLabel方法,modeling.updateLabel(节点id,新名字);

step4: 获取节点实例的两种方法  

  4.1 通过step1中的点击事件等,可以直接拿到目标对象e,e.element就是节点实例

eventBus.on('element.click', (e) => {console.log(e.element);})

  4.2  没有任何事件可以触发,手里空空只有一个节点id

    方案:bpmnModeler的elementRegistry来解围!

const elementRegistry = this.bpmnModeler.get('elementRegistry');
console.log(elementRegistry.get(节点id));

后续

  上文代码都是片段,特此附上完整代码:老规矩:data中的chart变量流程图xml文件数据,由于行数过多,附在了附件中(点我!点我),使用时,将附件内容复制过来,赋值给chart即可

<template>
    <div class="containerBox">
        <div style="margin-left: 250px">
            选中的节点名称:
            <el-input
                    v-model.trim="nodeName"
                    placeholder="请输入节点名称"
                    clearable
                    @input="inputChange"
                    style="width: 200px">
            </el-input>
        </div>
        <div id="container"></div>
    </div>
</template>
<script>
  import BpmnModeler from 'bpmn-js/lib/Modeler';
  import CustomPaletteProvider from './customPalette';
  import customModule from './customPalette/custom';
  import camundaExtension from './resources/camunda';
  import {tempDetail, saveCanvas} from '@api/processConfig';

  export default {
    name: 'index',
    data() {
      return {
        containerEl: null,
        bpmnModeler: null,
        currentElement: {},
        nodeName: "",
        // chart变量流程图xml文件数据,由于行数过多,附在了附件中,使用时,将附件整个赋值给chart即可
        chart: ''
      };
    },
    mounted() {
      this.containerEl = document.getElementById('container');
      this.bpmnModeler = new BpmnModeler({
        container: this.containerEl,
        moddleExtensions: {camunda: camundaExtension},
        additionalModules: [CustomPaletteProvider, customModule]
      });
      this.showChart();
    },
    methods: {
      getShapeById() {
        const elementRegistry = this.bpmnModeler.get('elementRegistry');
        console.log(elementRegistry.get('Activity_0ozmm5p'));
      },
      inputChange(val) {
        const modeling = this.bpmnModeler.get('modeling');
        if (JSON.stringify(this.currentElement) === '{}') {
          this.$message.info('请保证要更改的节点处于选中状态!');
          return false;
        } else {
          modeling.updateLabel(this.currentElement, val);
        }
      },
      // 流程图回显
      showChart() {
        this.bpmnModeler.importXML(this.chart, (err) => {
          if (!err) {
            this.addEventBusListener();
            this.getNodeInfoList();
            this.getShapeById();
          }
        });
      },
      // 获取流程图中所有节点信息
      getNodeInfoList() {
        const elementRegistry = this.bpmnModeler.get('elementRegistry');
        const userTaskList = elementRegistry.filter(
          (item) => item.type === 'bpmn:UserTask'
        );
        // 此时得到的userTaskList 便是流程图中所有的用户节点的集合
        console.log(userTaskList);
      },
      addEventBusListener() {
        const eventBus = this.bpmnModeler.get('eventBus');
        // 注册节点事件,eventTypes中可以写多个事件
        const eventTypes = ['element.click', 'element.hover'];
        eventTypes.forEach((eventType) => {
          eventBus.on(eventType, (e) => {
            const {element} = e;
            if (!element.parent) return;
            if (!e || element.type === 'bpmn:Process') {
              return false;
            } else {
              if (eventType === 'element.click') {
                // 节点点击后想要做的处理
                // 此时想要点击节点后,拿到节点实例,通过外部输入更新节点名称
                this.currentElement = element;
              } else if (eventType === 'element.hover') {
                // 鼠标滑过节点后想要做的处理
                console.log('鼠标经过节点啦~');
              }
            }
          });
        });
      }
    }
  };
</script>
<style lang="scss">
    .containerBox {
        height: calc(100vh - 220px);
        position: relative;

        #container {
            height: calc(100% - 50px);
        }
    }
</style>
View Code

 

相关文章