胖蔡说技术
随便扯扯

bpmn-js 多实例配置实现或签会签

使用bpmn-js流程图开发过程中会遇到会签和或签的问题,这个时候我们就需要使用多实例配置来实现BPMN 2.0的配置实现了,多实例任务,是从流程编辑概念之初也就是Activiti时期就存在的一个方式。所谓的多实例任务也就是字面意思,一个任务由多个人完成,常见于我们的审批流程的或签【一个审批完成即可】和会签【多个用户审批都通过才算结束】,由于存在多个成员的操作,引入了多实例的概念。

多实例

分类

多实例的出现其实就是确定重复的多成员操作的工作流顺序关系,按此可区分为串行和并行:

  • 串行多实例:按先后顺序执行,依序执行
  • 并行多实例:完成任务没有先后顺序的要求,并行执行

flowable中的多实例的配置样式如下所示:

如上就是一个并行多实例审批的图示,生成xml格式如下:

<bpmn2:userTask id="Activity_1vv1m6z" name="审批">
      <bpmn2:incoming>Flow_0w3q52d</bpmn2:incoming>
      <bpmn2:outgoing>Flow_1ugegu7</bpmn2:outgoing>
      <bpmn2:multiInstanceLoopCharacteristics flowable:collection="assigneeList" flowable:elementVariable="assignee">
        <bpmn2:extensionElements>
          <flowable:executionListener class="cn.com.fsg.hcmplus.flowable.service.flowservice.flowlistener.ParallelListener" event="start" />
        </bpmn2:extensionElements>
//       <bpmn2:loopDataInputRef>assigneeList</bpmn2:loopDataInputRef>
//        <bpmn2:inputDataItem name="assignee" />
        <bpmn2:completionCondition xsi:type="bpmn2:tFormalExpression">${multiInstanceCompleteTask.accessCondition(execution)}</bpmn2:completionCondition>
      </bpmn2:multiInstanceLoopCharacteristics>
    </bpmn2:userTask>

配置属性

如上:bpmn2:multiInstanceLoopCharacteristics节点就是多实例审批配置节点,通过上述节点我们了解下基础的节点配置属性:

  • isSequentialtrue为串行多实例,false为并行多实例
  • collection:适配flowable中该属性为:flowable:collection, 表示多实例的人员集合的变量名,,同时也支持通过loopDataInputRef设置
  • elementVariable:适配flowable中该属性为:flowable:elementVariable,表示多实例集合中的元素的变量名,同时也支持通过inputDataItem 设置
  • completionCondition:配置多实例完成的条件
  • loopCardinality:使用 loopCardinality 子元素直接指定一个数字作为多实例的数量
  • FailedJobRetryTimeCycle: 重试周期

支持元素

bpmn中常用的任务类型元素模型均支持使用多实例方式配置,如下提供部分支持的元素模型:

  • User Task
  • Script Task
  • Java Service Task
  • Call Activity
  • Manual Task
  • Receive Task
  • Embedded Sub-Process
  • Web Service Task
  • Business Rule Task

创建多实例

多实例的创建其实就是上述xml创建的过程,由于我这边大多配置都是固定的,没有单独添加多实例配置,有需要的可以根据需要添加配置设置,按配置动态写入元素,如下为我这边写入的代码:

  // 更新多实例配置
  const creatMultiInstance= () => {
    const type = model.value.parallelType
    if (isNil(type))
      return
    const isSerial = type === MultiInstanceTypes.SERIAL // 是否是串行
    const moddle = toRaw(bpmnInstances.value?.moddle)
    const modeling = toRaw(bpmnInstances.value?.modeling)
    const element = toRaw(bpmnInstances.value?.bpmnElement)

    let multiLoopInstance
    let extensionElements
    // isSequential: true是串行,false是并行
    if (isSerial) {
      // 串行实例
      extensionElements = moddle.create('bpmn:ExtensionElements', {
        values: [],
      })
      multiLoopInstance = moddle.create('bpmn:MultiInstanceLoopCharacteristics', {
        isSequential: true,
        collection: 'assigneeList',
        elementVariable: 'assignee',
        extensionElements,
      })
    }
    else {
      // 并行实例
      const executionListener = moddle.create('flowable:ExecutionListener', {
        class: 'cn.xxxx.JavaListener',
        event: 'start',
      })

      extensionElements = moddle.create('bpmn:ExtensionElements', {
        values: [executionListener],
      })

      const completionCondition = moddle.create('bpmn:FormalExpression', {
        // eslint-disable-next-line no-template-curly-in-string
        body: '${multiInstanceCompleteTask.accessCondition(execution)}',
      })

      multiLoopInstance = moddle.create('bpmn:MultiInstanceLoopCharacteristics', {
        isSequential: false,
        collection: 'assigneeList',
        elementVariable: 'assignee',
        completionCondition,
        extensionElements,
      })
    }

    modeling.updateProperties(element, {

      loopCharacteristics: multiLoopInstance,
    })
  }

赞(1) 打赏
转载请附上原文出处链接:胖蔡说技术 » bpmn-js 多实例配置实现或签会签
分享到: 更多 (0)

请小编喝杯咖啡~

支付宝扫一扫打赏

微信扫一扫打赏