CustomContextPad.js 8.67 KB
import {changeElementSize} from '@/components/VueBpmn/custom/util'
import {getNewShapePosition} from 'bpmn-js/lib/features/auto-place/BpmnAutoPlaceUtil.js'
import {assign} from 'min-dash'
export default class CustomContextPad {
  constructor(
    config,
    contextPad,
    create,
    elementFactory,
    injector,
    translate,
    modeling,
    bpmnFactory,
    selection
  ) {
    this.create = create
    this.elementFactory = elementFactory
    this.translate = translate
    this.modeling = modeling
    this.bpmnFactory = bpmnFactory
    this.selection = selection

    if (config.autoPlace !== false) {
      this.autoPlace = injector.get('autoPlace', false)
    }

    contextPad.registerProvider(this) // // 定义这是一个contextPad
  }

  getContextPadEntries(element) {
    // 自定义右键菜单 如果点击的是线 不出现自定义菜单
    if (element.type == 'bpmn:SequenceFlow') {
      return {}
    }
    const {
      autoPlace,
      create,
      elementFactory,
      translate,
      modeling,
      bpmnFactory,
      selection
    } = this
    // 删除功能
    function removeElement(e) {
      modeling.removeElements([element])
    }

    function clickElement(e) {}

    function appendTask(event, element) {
      if (autoPlace) {
        const shape = elementFactory.createShape({type: 'bpmn:UserTask'})
        changeElementSize(shape)
        autoPlace.append(element, shape)
      } else {
        appendTaskStart(event, element)
      }
    }

    function appendTaskStart(event, element) {
      const shape = elementFactory.createShape({type: 'bpmn:UserTask'})
      changeElementSize(shape)
      create.start(event, shape, element)
    }

    function editElement() {
      // 创建编辑图标
      return {
        group: 'edit',
        className: 'icon-custom icon-custom-edit',
        title: translate('编辑'),
        action: {
          click: clickElement
        }
      }
    }

    function deleteElement() {
      return {
        group: 'edit',
        className: 'icon-custom icon-custom-delete',
        title: translate('删除'),
        action: {
          click: removeElement
        }
      }
    }

    function appendAndClickAnnotation(color) {
      return function(event, element) {
        const businessObject = bpmnFactory.create('bpmn:TextAnnotation')
        if (color) {
          businessObject.color = color
        }
        const shape = elementFactory.createShape({
          type: 'bpmn:TextAnnotation',
          businessObject
        })
        autoPlace.append(element, shape)
      }
    }

    function createSignTask(append, isSequential) {
      return function(event, element) {
        let loopCharacteristics = bpmnFactory.create(
          'bpmn:MultiInstanceLoopCharacteristics'
        )

        const businessObject = bpmnFactory.create('bpmn:UserTask', {
          loopCharacteristics: loopCharacteristics
        })
        businessObject['custom'] = 1
        businessObject.name = '会签并行'
        if (isSequential) {
          loopCharacteristics.isSequential = true
          businessObject.name = '会签串行'
        }
        const shape = elementFactory.createShape({
          type: 'bpmn:UserTask',
          businessObject
        })
        changeElementSize(shape)
        if (append) {
          autoPlace.append(element, shape)
        } else {
          create.start(event, shape)
        }
      }
    }
    function createSubprocessCollapsed(append) {
      return function (event, element) {
        const businessObject = bpmnFactory.create('bpmn:CallActivity');
        businessObject['custom'] = 1
        businessObject.name = "外部子流程";
        const shape = elementFactory.createShape({
          type: 'bpmn:CallActivity',
          businessObject
        });
        changeElementSize(shape);
        if (append) {
          autoPlace.append(element, shape);
        } else {
          create.start(event, shape);
        }
      }
    }
    // 内部子流程
    function createSubprocessExpanded(append) {
      return function(event, element) {
        var subProcess = elementFactory.createShape({
          type: 'bpmn:SubProcess',
          x: 0,
          y: 0,
          isExpanded: true
        })

        var startEvent = elementFactory.createShape({
          type: 'bpmn:StartEvent',
          x: 40,
          y: 82,
          parent: subProcess
        })
        changeElementSize(startEvent);
        changeElementSize(subProcess);
        if (append) {
          // 获取位置
          let position = getNewShapePosition(element,subProcess);
          // 创建内部子流程元素
          modeling.createShape(subProcess, position, element.parent)
          // 获取位置
          position.x = position.x - subProcess.width/2 + 56;
          // 创建内部子流程第一个开始事件shape
          modeling.createShape(startEvent, position, subProcess)
          // 连线
          modeling.connect(element, subProcess);  
        } else {
          create.start(event, [subProcess, startEvent])
        }
        // 默认选中内部子流程第一个节点
        selection.select([startEvent]);
      }
    }
    function createEndEvent(append) {
      return function(event, element) {
        const shape = elementFactory.createShape({type: 'bpmn:EndEvent'})
        changeElementSize(shape)
        if (append) {
          autoPlace.append(element, shape)
        } else {
          create.start(event, shape)
        }
      }
    }

    function createGateWay(type, append) {
      return function(event, element) {
        const shape1 = elementFactory.createShape({type: type})
        changeElementSize(shape1)
        if (append) {
          autoPlace.append(element, shape1)
          if (type != 'bpmn:ExclusiveGateway') {
            const shape2 = elementFactory.createShape({type: type})
            changeElementSize(shape2)
            autoPlace.append(element, shape2)
          }
        } else {
          create.start(event, shape1)
        }
      }
    }

    // 创建同步
    return {
      'append.user-task': {
        group: 'model',
        className: 'bpmn-icon-user-task',
        title: translate('用户任务'),
        action: {
          click: appendTask,
          dragstart: appendTaskStart
        }
      },
      'append.sign-task': {
        group: 'model',
        className: 'bpmn-icon-parallel-mi-marker',
        title: translate('会签并行'),
        action: {
          click: createSignTask(true, false),
          dragstart: createSignTask(false, false)
        }
      },
      'append.sign-task-sequential': {
        group: 'model',
        className: 'bpmn-icon-sequential-mi-marker',
        title: translate('会签串行'),
        action: {
          click: createSignTask(true, true),
          dragstart: createSignTask(false, true)
        }
      },
      'append.gateway2': {
        group: 'model',
        className: 'bpmn-icon-gateway-xor',
        title: translate('条件网关'),
        action: {
          click: createGateWay('bpmn:ExclusiveGateway', true),
          dragstart: createGateWay('bpmn:ExclusiveGateway', false)
        }
      },
      'append.parallelGateway': {
        group: 'model',
        className: 'bpmn-icon-gateway-parallel',
        title: translate('同步网关'),
        action: {
          click: createGateWay('bpmn:ParallelGateway', true),
          dragstart: createGateWay('bpmn:ParallelGateway', false)
        }
      },
      'append.inclusiveGateway': {
        group: 'model',
        className: 'bpmn-icon-gateway-or',
        title: translate('条件同步网关'),
        action: {
          click: createGateWay('bpmn:InclusiveGateway', true),
          dragstart: createGateWay('bpmn:InclusiveGateway', false)
        }
      },
      'create.subprocess-collapsed': {
        group: 'model',
        className: 'bpmn-icon-subprocess-collapsed',
        title: translate('外部子流程'),
        action: {
          click: createSubprocessCollapsed(true),
          dragstart: createSubprocessCollapsed(false)
        }
      },
      'create.subprocess-expanded': {
        group: 'model',
        className: 'bpmn-icon-subprocess-expanded',
        title: translate('内部子流程'),
        action: {
          click: createSubprocessExpanded(true),
          dragstart: createSubprocessExpanded(false)
        }
      },
      'append.end-event2': {
        group: 'model',
        className: 'bpmn-icon-end-event-none',
        title: translate('结束'),
        action: {
          click: createEndEvent(true),
          dragstart: createEndEvent(false)
        }
      }
    }
  }
}

CustomContextPad.$inject = [
  'config',
  'contextPad',
  'create',
  'elementFactory',
  'injector',
  'translate',
  'modeling',
  'bpmnFactory',
  'selection'
]