复习步骤21- 25 BPMN其他元素(3)流程活动的特性

多实例流程活动

 

 

设置循环数据

  在要循环的流程节点中加入下标签,表示循环执行

       后台设置循环数据

 

跳出循环

如上图加标签就是执行2次就会跳出循环

 

补偿处理者

 

 

一、参照下图,弄个最简单的循环执行这个Service  Task节点

 1.1 新建 foreach-test1.bpmn

 1.2 修改foreach-test1.bpmn -- 给Service Task 加如下标签,让其执行5次

 

1.3测试方法

/**

     * 测试最简单的循环执行这个Service  Task节点

     *  <serviceTask id="servicetask1" name="Service Task">

          <multiInstanceLoopCharacteristics

               isSequential="false" >

               <loopCardinality>5</loopCardinality>

          </multiInstanceLoopCharacteristics>

    </serviceTask>

     */

    public static void testForeachTest1(){

       ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();

       // 存储服务

       RepositoryService rs = engine.getRepositoryService();

       // 运行时服务

       RuntimeService runService = engine.getRuntimeService();

       // 任务服务

       TaskService taskService = engine.getTaskService();

       Deployment dep = rs.createDeployment().addClasspathResource("foreach-test1.bpmn").deploy();

       ProcessDefinition pd = rs.createProcessDefinitionQuery().deploymentId(dep.getId()).singleResult();

      

      

       // 启动流程

       ProcessInstance pi = runService.startProcessInstanceById(pd.getId());

       /*

        * 执行Service Task 5--即执行 Foreach1Delegate execute5

        * 输出结果:

        *  测试最简单的循环执行

           测试最简单的循环执行

           测试最简单的循环执行

           测试最简单的循环执行

           测试最简单的循环执行

 

        * */

     }

 

   二、参照下图  测试后台设置循环数据

2.1 新建 foreach-test2.bpmn

     

         新建 Foreach2Delegate.java

2.2 修改  foreach-test2.bpmn

 

2.3 测试方法

/**

     *  lqx

     *  测试后台设置循环数据--遍历 datas1value 并将遍历出来的数据放入执行流变量名为data

     *  <serviceTask id="servicetask1" name="Service Task"  activiti:class="com.xiangshuai.act.c24.Foreach2Delegate">

          <multiInstanceLoopCharacteristics

               isSequential="false"  activiti:elementVariable="data">

               <loopDataInputRef>datas1</loopDataInputRef>

          </multiInstanceLoopCharacteristics>

    </serviceTask>

     */

    public static void testForeachTest2(){

       ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();

       // 存储服务

       RepositoryService rs = engine.getRepositoryService();

       // 运行时服务

       RuntimeService runService = engine.getRuntimeService();

       // 任务服务

       TaskService taskService = engine.getTaskService();

       Deployment dep = rs.createDeployment().addClasspathResource("foreach-test2.bpmn").deploy();

       ProcessDefinition pd = rs.createProcessDefinitionQuery().deploymentId(dep.getId()).singleResult();

      

      

       // 启动流程

       Map<String, Object> map=new HashMap<String, Object>();

       ArrayList<Object> list = new ArrayList<>();

       list.add("aaaaa");

       list.add("bbbbb");

       list.add("CCCC");

       list.add("bbbDDDbb");

       list.add("EEEE");

       map.put("datas1", list);

       ProcessInstance pi = runService.startProcessInstanceById(pd.getId(),map);

       /*

        * 遍历 datas1 执行Service Task --即执行 Foreach2Delegate execute

        * 输出结果:

        *  测试后台设置循环数据--foreach-test2.bpmn--遍历datas1data:aaaaa

           测试后台设置循环数据--foreach-test2.bpmn--遍历datas1data:bbbbb

           测试后台设置循环数据--foreach-test2.bpmn--遍历datas1data:CCCC

           测试后台设置循环数据--foreach-test2.bpmn--遍历datas1data:bbbDDDbb

           测试后台设置循环数据--foreach-test2.bpmn--遍历datas1data:EEEE

 

        * */

    }

 

三、测试跳出循环

 

   3.1 新建 foreach-test3.bpmn

 

 3.2 修改 foreach-test3.bpmn

 

 

3.3 测试方法

/**

     *  lqx

     *  测试后台设置循环数据,两次后跳出循环--遍历 datas1value 并将遍历出来的数据放入执行流变量名为data

     * <serviceTask id="servicetask1" name="Service Task"  activiti:class="com.xiangshuai.act.c24.Foreach3Delegate">

          <multiInstanceLoopCharacteristics

               isSequential="false"  activiti:elementVariable="data">

               <loopDataInputRef>datas1</loopDataInputRef>

               <completionCondition>${nrOfCompletedInstances >= 2}</completionCondition>

          </multiInstanceLoopCharacteristics>

       </serviceTask>

       nrOfCompletedInstances--循环参数,已完成的实例数,详见循环参数

     */

    public static void testForeachTest3(){

       ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();

       // 存储服务

       RepositoryService rs = engine.getRepositoryService();

       // 运行时服务

       RuntimeService runService = engine.getRuntimeService();

       // 任务服务

       TaskService taskService = engine.getTaskService();

       Deployment dep = rs.createDeployment().addClasspathResource("foreach-test3.bpmn").deploy();

       ProcessDefinition pd = rs.createProcessDefinitionQuery().deploymentId(dep.getId()).singleResult();

      

      

       // 启动流程

       Map<String, Object> map=new HashMap<String, Object>();

       ArrayList<Object> list = new ArrayList<>();

       list.add("aaaaa");

       list.add("bbbbb");

       list.add("CCCC");

       list.add("bbbDDDbb");

       list.add("EEEE");

       map.put("datas1", list);

       ProcessInstance pi = runService.startProcessInstanceById(pd.getId(),map);

       /*

        * 遍历 datas1 执行Service Task --即执行 Foreach2Delegate execute

        * 输出结果:

        *  测试后台设置循环数据,两次后跳出循环--foreach-test2.bpmn--遍历datas1data:aaaaa

                      测试后台设置循环数据,两次后跳出循环--foreach-test2.bpmn--遍历datas1data:bbbbb

           可以看到Service Task 执行两次后不再执行

        * */

    }

 

总执行类 ForeachTest.java

package com.xiangshuai.act.c24;

 

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Map;

 

import org.activiti.engine.ProcessEngine;

import org.activiti.engine.ProcessEngines;

import org.activiti.engine.RepositoryService;

import org.activiti.engine.RuntimeService;

import org.activiti.engine.TaskService;

import org.activiti.engine.repository.Deployment;

import org.activiti.engine.repository.ProcessDefinition;

import org.activiti.engine.runtime.ProcessInstance;

 

/**

 * @author lqx

 *文件在 E:\学习文档子目录压缩\框架\工作流引擎\Activiti6.0\window\复习步骤21-  25 BPMN其他元素(3)流程活动的特性

 * 或 我的网盘\我的笔记\学习文档子目录压缩\框架\工作流引擎\Activiti6.0\window\复习步骤21-  25 BPMN其他元素(3)流程活动的特性

 */

public class ForeachTest {

         public static void main(String[] args) {

                  //testForeachTest1();

                  //testForeachTest2();

                  testForeachTest3();

         }

        

     /**

     * 测试最简单的循环执行这个Service  Task节点

     *  <serviceTask id="servicetask1" name="Service Task">

          <multiInstanceLoopCharacteristics

               isSequential="false" >

               <loopCardinality>5</loopCardinality>

          </multiInstanceLoopCharacteristics>

    </serviceTask>

     */

    public static void testForeachTest1(){

             ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();

             // 存储服务

             RepositoryService rs = engine.getRepositoryService();

             // 运行时服务

             RuntimeService runService = engine.getRuntimeService();

             // 任务服务

             TaskService taskService = engine.getTaskService();

             Deployment dep = rs.createDeployment().addClasspathResource("foreach-test1.bpmn").deploy();

             ProcessDefinition pd = rs.createProcessDefinitionQuery().deploymentId(dep.getId()).singleResult();

            

            

             // 启动流程

             ProcessInstance pi = runService.startProcessInstanceById(pd.getId());

             /*

              * 执行Service Task 5次--即执行 Foreach1Delegate 的execute5次

              * 输出结果:

              *  测试最简单的循环执行

                          测试最简单的循环执行

                          测试最简单的循环执行

                          测试最简单的循环执行

                          测试最简单的循环执行

 

              * */

     }

   

   

    /**

     *  lqx

     *  测试后台设置循环数据--遍历 datas1的value值 并将遍历出来的数据放入执行流变量名为data中

     *  <serviceTask id="servicetask1" name="Service Task"  activiti:class="com.xiangshuai.act.c24.Foreach2Delegate">

          <multiInstanceLoopCharacteristics

               isSequential="false"  activiti:elementVariable="data">

               <loopDataInputRef>datas1</loopDataInputRef>

          </multiInstanceLoopCharacteristics>

    </serviceTask>

     */

    public static void testForeachTest2(){

             ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();

             // 存储服务

             RepositoryService rs = engine.getRepositoryService();

             // 运行时服务

             RuntimeService runService = engine.getRuntimeService();

             // 任务服务

             TaskService taskService = engine.getTaskService();

             Deployment dep = rs.createDeployment().addClasspathResource("foreach-test2.bpmn").deploy();

             ProcessDefinition pd = rs.createProcessDefinitionQuery().deploymentId(dep.getId()).singleResult();

            

            

             // 启动流程

             Map<String, Object> map=new HashMap<String, Object>();

             ArrayList<Object> list = new ArrayList<>();

             list.add("aaaaa");

             list.add("bbbbb");

             list.add("CCCC");

             list.add("bbbDDDbb");

             list.add("EEEE");

             map.put("datas1", list);

             ProcessInstance pi = runService.startProcessInstanceById(pd.getId(),map);

             /*

              * 遍历 datas1 执行Service Task --即执行 Foreach2Delegate 的execute

              * 输出结果:

              *  测试后台设置循环数据--foreach-test2.bpmn--遍历datas1,data:aaaaa

                          测试后台设置循环数据--foreach-test2.bpmn--遍历datas1,data:bbbbb

                          测试后台设置循环数据--foreach-test2.bpmn--遍历datas1,data:CCCC

                          测试后台设置循环数据--foreach-test2.bpmn--遍历datas1,data:bbbDDDbb

                          测试后台设置循环数据--foreach-test2.bpmn--遍历datas1,data:EEEE

 

              * */

    }

    /**

     *  lqx

     *  测试后台设置循环数据,两次后跳出循环--遍历 datas1的value值 并将遍历出来的数据放入执行流变量名为data中

     * <serviceTask id="servicetask1" name="Service Task"  activiti:class="com.xiangshuai.act.c24.Foreach3Delegate">

          <multiInstanceLoopCharacteristics

               isSequential="false"  activiti:elementVariable="data">

               <loopDataInputRef>datas1</loopDataInputRef>

               <completionCondition>${nrOfCompletedInstances >= 2}</completionCondition>

          </multiInstanceLoopCharacteristics>

       </serviceTask>

       nrOfCompletedInstances--循环参数,已完成的实例数,详见循环参数

     */

    public static void testForeachTest3(){

             ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();

             // 存储服务

             RepositoryService rs = engine.getRepositoryService();

             // 运行时服务

             RuntimeService runService = engine.getRuntimeService();

             // 任务服务

             TaskService taskService = engine.getTaskService();

             Deployment dep = rs.createDeployment().addClasspathResource("foreach-test3.bpmn").deploy();

             ProcessDefinition pd = rs.createProcessDefinitionQuery().deploymentId(dep.getId()).singleResult();

            

            

             // 启动流程

             Map<String, Object> map=new HashMap<String, Object>();

             ArrayList<Object> list = new ArrayList<>();

             list.add("aaaaa");

             list.add("bbbbb");

             list.add("CCCC");

             list.add("bbbDDDbb");

             list.add("EEEE");

             map.put("datas1", list);

             ProcessInstance pi = runService.startProcessInstanceById(pd.getId(),map);

             /*

              * 遍历 datas1 执行Service Task --即执行 Foreach2Delegate 的execute

              * 输出结果:

              *  测试后台设置循环数据,两次后跳出循环--foreach-test2.bpmn--遍历datas1,data:aaaaa

                      测试后台设置循环数据,两次后跳出循环--foreach-test2.bpmn--遍历datas1,data:bbbbb

           可以看到Service Task 执行两次后不再执行

              * */

    }

}

 

 

 

     

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Vue3 中集成 `bpmn-js` 在线设计 `flowable` 流程图的实现代码如下: ```vue <template> <div> <div ref="canvas" class="bpmn-canvas"></div> <div> <button @click="save">保存</button> <button @click="undo">撤销</button> <button @click="redo">重做</button> </div> </div> </template> <script> import BpmnModeler from 'bpmn-js/lib/Modeler'; import 'bpmn-js/dist/assets/diagram-js.css'; import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'; import 'bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css'; import 'bpmn-js-properties-panel/dist/assets/properties.css'; import 'bpmn-js-properties-panel/dist/assets/properties-panel.css'; export default { mounted() { this.bpmnModeler = new BpmnModeler({ container: this.$refs.canvas, propertiesPanel: { parent: '#properties-panel', }, additionalModules: [ // properties panel module require('bpmn-js-properties-panel'), // properties provider module require('bpmn-js-properties-panel/lib/provider/camunda'), // custom module require('./CustomModule'), ], moddleExtensions: { camunda: require('camunda-bpmn-moddle/resources/camunda'), }, }); this.bpmnModeler.createDiagram(() => { this.bpmnModeler.get('canvas').zoom('fit-viewport'); }); }, methods: { save() { this.bpmnModeler.saveXML((err, xml) => { if (err) { console.error('保存失败', err); } else { console.log('保存成功', xml); // 发送给后台进行保存 } }); }, undo() { this.bpmnModeler.get('commandStack').undo(); }, redo() { this.bpmnModeler.get('commandStack').redo(); }, }, }; </script> ``` 首先,我们需要引入 `bpmn-js` 和 `bpmn-js-properties-panel` 两个依赖。然后,在 `additionalModules` 中添加我们自定义的 `CustomModule` 模块,该模块将在后面实现。 在 `mounted` 生命周期中,我们创建了一个 `BpmnModeler` 实例,并使用 `createDiagram` 方法创建一个新的 BPMN 图表。最后,我们将 BPMN 图表缩放以适应视口大小。 在 `methods` 中,我们实现了保存、撤销和重做功能。`save` 方法将当前 BPMN 图表保存为 XML 字符串,你可以将该字符串发送给后台进行保存。`undo` 和 `redo` 方法分别实现了撤销和重做操作。 接下来我们需要实现 `CustomModule` 模块。该模块可以添加自定义的工具栏按钮和事件监听器。下面是实现代码: ```js const CustomModule = { __init__: [ 'customRenderer', 'customPalette', 'customContextPad', ], customRenderer: ['type', require('./CustomRenderer')], customPalette: ['type', require('./CustomPalette')], customContextPad: ['type', require('./CustomContextPad')], }; module.exports = CustomModule; ``` 这里我们定义了三个模块:`customRenderer`、`customPalette` 和 `customContextPad`。分别用来实现自定义的渲染器、自定义的工具栏和自定义的上下文菜单。 下面是 `CustomRenderer` 的实现代码: ```js function CustomRenderer(eventBus, bpmnRenderer) { bpmnRenderer.drawShape = function (p, element) { const shape = bpmnRenderer.drawShape(p, element); if (element.type === 'bpmn:ServiceTask') { const rect = drawRect(p, 2, shape.width - 4, shape.height - 4, 10, '#000000'); const path = drawPath(p, `M ${shape.width / 2} ${shape.height / 2 + 10} L ${shape.width / 2} ${shape.height - 10}`, { strokeWidth: 2, stroke: '#ffffff' }); return [shape, rect, path]; } return shape; }; } CustomRenderer.$inject = ['eventBus', 'bpmnRenderer']; module.exports = CustomRenderer; // 封装绘制矩形方法 function drawRect(p, x, y, width, height, color) { return p.rect(x, y, width, height, 10).attr({ fill: color }); } // 封装绘制线段方法 function drawPath(p, path, attrs) { return p.path(path).attr(attrs); } ``` 这里我们实现了自定义的渲染器,通过修改 `bpmnRenderer` 来实现。我们在 `bpmn:ServiceTask` 上添加了一个矩形和一条竖线,用来表示该节点需要进行某个操作。 下面是 `CustomPalette` 的实现代码: ```js function CustomPalette(palette, create) { this._create = create; palette.registerProvider(this); } CustomPalette.$inject = ['palette', 'create']; module.exports = CustomPalette; CustomPalette.prototype.getPaletteEntries = function () { const create = this._create; function createAction(type) { return function (event) { const shape = create.start(event, type); create.end(event, shape); }; } return { 'create.service-task': { group: 'activity', className: 'bpmn-icon-service-task', title: 'Service Task', action: { dragstart: createAction('bpmn:ServiceTask'), click: createAction('bpmn:ServiceTask'), }, }, }; }; ``` 这里我们实现了自定义的工具栏,通过 `getPaletteEntries` 方法返回一个工具栏项,并在 `createAction` 方法中实现具体的操作。 最后是 `CustomContextPad` 的实现代码: ```js function CustomContextPad(eventBus, contextPad, create, elementFactory) { this._eventBus = eventBus; this._contextPad = contextPad; this._create = create; this._elementFactory = elementFactory; eventBus.on('shape.added', 2000, (event) => { const shape = event.element; if (shape.type === 'bpmn:ServiceTask') { this.appendAction(shape, 'Edit', 'bpmn-icon-service-task', 'custom-action', { action: 'edit', icon: 'bpmn-icon-service-task', }); } }); } CustomContextPad.$inject = ['eventBus', 'contextPad', 'create', 'elementFactory']; module.exports = CustomContextPad; CustomContextPad.prototype.appendAction = function (element, name, cssClass, title, options = {}) { const { action, icon, } = options; const self = this; const click = options.click || function (event, element) { self.triggerAction(action, element); }; const button = document.createElement('div'); button.title = title; button.className = `entry ${cssClass}`; button.innerHTML = `<i class="${icon}"></i>`; this._contextPad.registerProvider(element, { getEntries: () => { const entries = {}; entries[name] = { action: click, className: cssClass, id: action, title, }; return entries; }, }); return button; }; CustomContextPad.prototype.triggerAction = function (action, element) { switch (action) { case 'edit': this._eventBus.fire('serviceTask.edit', { element }); break; default: console.warn(`未知操作: ${action}`); break; } }; ``` 这里我们实现了自定义的上下文菜单,通过在 `shape.added` 事件中添加自定义的菜单项。 至此,我们实现了在 Vue3 中集成 `bpmn-js` 在线设计 `flowable` 流程图的完整代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值