vue+activiti做工作流,前端bpmn-js的一些配置

vue+activiti做工作流,前端bpmn-js的一些配置

bpmn的使用

bpmn.io官网,可下载bpmn-js用于前端制作流程图,用于配合后端activiti,使用流程定义工具,按照BPMN规范,用流程符号将流程描述出来创建bpmn文件(实为xml文件):

Download bpmn-js | Toolkits | bpmn.io

pnpm install bpmn-js@7.3.1
pnpm install bpmn-js-properties-panel@0.37.2
pnpm install camunda-bpmn-moddle@4.4.0

【注】bpmn-js版本不一样,会提示装相应的版本其他插件。此处标准版本,仅在例子中使用

1.创建,编辑(包含左侧工具栏和右侧工具栏)

(此处有些因为需求而修改代理人、候选人、候选组维护方式,不需要可忽略。维护方式参考bpmn-js画流程图 (四)右侧属性面板中执行人,候选人与候选组可以通过 用户、机构(角色)选择 - 猪脚踏浪 - 博客园 (cnblogs.com)

<template>
  <div>
    <div class="containers">
      <div class="canvas" ref="canvas"></div>
      <div id="js-properties-panel" class="panel"></div>
    </div>
    <EmpModal @register="registerModalEmp" @success="empSubmit" />
    <EmpModalCheck
      @register="registerModalEmpCheck"
      @success="empSubmitCheck"
    />
    <RoleModal
      @register="registerModalRole"
      @success="roleSubmitCheck"
    ></RoleModal>
  </div>
</template>

<script lang='ts'>
import { defineComponent, onMounted, ref } from 'vue'

import BpmnModeler from 'bpmn-js/lib/Modeler' //画流程图
// import { xmlStr } from './mock' //初始流程图配置文件

import propertiesPanelModule from 'bpmn-js-properties-panel'
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'
import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
import customTranslate from './customTranslate/customTranslate' // 汉化包引入
import DefaultEmptyXML from './default/defaultEmpty'
import { EmpModal } from '@/components/Common' //单选
import { EmpModalCheck } from '@/components/Common' //多选
import { RoleModal } from '@/components/Common' //多选
import { useModal } from '@/components/Modal'
import $ from 'jquery'
export default defineComponent({
  name: 'bpmnDesigner',
  components: { EmpModal, EmpModalCheck, RoleModal },
  emits: ['save'],
  props: ['processId', 'processName', 'xmlStr'],
  setup(props, { emit }) {
    // bpmn建模器
    const bpmnModeler = ref(null)
    const container = ref(null)
    const canvas = ref(null)
    const processId = ref('')
    const processName = ref('')
    const xmlStr = ref('')
    processId.value = props.processId
    processName.value = props.processName
    xmlStr.value = props.xmlStr
    // 将汉化包包装成一个模块
    const customTranslateMolude = {
      translate: ['value', customTranslate],
    }
    function init() {
      // 获取到属性ref为“canvas”的dom节点
      const canvasTmp = canvas.value
      // 建模
      bpmnModeler.value = new BpmnModeler({
        container: canvasTmp, //
        //添加控制板
        propertiesPanel: {
          parent: '#js-properties-panel',
        },
        additionalModules: [
          // 右边的属性栏
          //低版本
          propertiesPanelModule,
          propertiesProviderModule,
          customTranslateMolude,
        ],
        moddleExtensions: {
          camunda: camundaModdleDescriptor,
        },
      })
      createNewDiagram()
    }
    /* 创建新的流程图 */
    function createNewDiagram() {
      // 将字符串转换成图显示出来,
      let prefix = 'activiti'
      let newId = processId.value ||`Process_${new Date().getTime()}` //processId.value ||
      let newName = processName.value || `业务流程_${new Date().getTime()}`
      let xmlString = xmlStr.value || DefaultEmptyXML(newId, newName, prefix)//xmlStr用于回显
      bpmnModeler.value.importXML(xmlString, (err) => {
        if (err) {
          // console.error(err)
        } else {
          // 这里是成功之后的回调, 可以在这里做一系列事情
          success()
        }
      })
    }
    function success() {
      // console.log('创建成功!')
    }
    //----------------修改属性人员相关内容------------
    function empSelect(value) {
      if (value == 'assignee') {
        openModalEmp(true)
      } else if (value == 'candidateUsers') {
        openModalEmpCheck(true)
      } else if (value == 'candidateGroups') {
        openModalRole(true)
      }
    }
    //---------------代理人
    const [registerModalEmp, { openModal: openModalEmp }] = useModal()
    const empSubmit = (values: any) => {
      setAassignee(values.empNo)
    }
    //----------------候选选用户--------------------
    const [registerModalEmpCheck, { openModal: openModalEmpCheck }] = useModal()
    const empSubmitCheck = (values: any) => {
      setCandidateUsers(values.ids)
    }
    //------------------候选用户组------------------
    const [registerModalRole, { openModal: openModalRole }] = useModal()
    const roleSubmitCheck = (values: any) => {
      setCandidateGroups(values.roleKeys)
    }
    //---------------------------------------
    onMounted(() => {
      init()
      $('#js-properties-panel').on(
        'click',
        '#camunda-assignee',
        function () {
          empSelect('assignee')
        },
      )
      $('#js-properties-panel').on(
        'click',
        '#camunda-candidateUsers',
        function () {
          empSelect('candidateUsers')
        },
      )
      $('#js-properties-panel').on(
        'click',
        '#camunda-candidateGroups',
        function () {
          empSelect('candidateGroups')
        },
      )
    })

    function save() {
      bpmnModeler.value.saveXML({ format: true }, function (err, xml) {
        if (err) {
          console.log('保存失败')
        } else {
          emit('save', xml)
        }
      })
    }
    //camunda-assignee代理人
    function setAassignee(value) {
        //触发修改事件,触发绑定的事件,更新数据
      $('#camunda-assignee').val(value)
      var changeEvent = document.createEvent('HTMLEvents')
      changeEvent.initEvent('change', true, true)
      $('#camunda-assignee')[0].dispatchEvent(changeEvent)
    }
    //camunda-candidateUsers候选用户
    function setCandidateUsers(value) {
      $('#camunda-candidateUsers').val(value)
      var changeEvent = document.createEvent('HTMLEvents')
      changeEvent.initEvent('change', true, true)
      $('#camunda-candidateUsers')[0].dispatchEvent(changeEvent)
    }
    //camunda-candidateGroups候选组
    function setCandidateGroups(value) {
      $('#camunda-candidateGroups').val(value)
      var changeEvent = document.createEvent('HTMLEvents')
      changeEvent.initEvent('change', true, true)
      $('#camunda-candidateGroups')[0].dispatchEvent(changeEvent)
    }

    return {
      canvas,
      bpmnModeler,
      save,
      processId,
      init,
      registerModalEmp,
      empSubmit,
      registerModalEmpCheck,
      empSubmitCheck,
      registerModalRole,
      roleSubmitCheck,
    }
  },
})
</script>
<style scoped lang="less">
.containers {
  position: absolute;
  background-color: #ffffff;
  /* width: 100%; 
  height: 100%;*/
  width: 94%;
  height: calc(100% - 45px - 120px);
}

.canvas {
  width: 80%;
  height: 100%;
}
.panel {
  position: absolute;
  right: 0;
  top: 0;
  width: 20%;
  height: calc(100% - 45px - 120px);
  .bpp-properties-panel {
    height: 100%;
    .bpp-properties {
      height: 100%;
      .bpp-properties-tabs-container {
        height: 100%;
        :deep(.bpp-properties-tab) {
          overflow-y: scroll;
        }
      }
    }
  }
}
:deep(.bpp-properties-tab) {
  height: calc(100vh - 350px);
  overflow-y: scroll;
}
:deep(#camunda-id) {
  pointer-events: none;
  background-color: #f8f8f8;
}
:deep(#camunda-name) {
  pointer-events: none;
  background-color: #f8f8f8;
}
:deep(.clear) {
  display: none;
}
:deep(#camunda-id + .bpp-error-message) {
    display: none;
  }
</style>

2.main.ts或main.js需要引入bpmn-js相关样式

//工作流样式
import 'bpmn-js/dist/assets/diagram-js.css' // 左边工具栏以及编辑节点的样式
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'

// import 'bpmn-js-properties-panel/dist/assets/properties-panel.css'//右侧信息栏(高版本)
import 'bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css'//右侧信息栏(低版本)
import $ from 'jquery'

3.初始模板DefaultEmptyXML.js文件

export default (key, name, type) => {
  if (!type) type = "camunda";
  const TYPE_TARGET = {
    activiti: "http://activiti.org/bpmn",
    camunda: "http://bpmn.io/schema/bpmn",
    flowable: "http://flowable.org/bpmn"
  };
  return `<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL"
  xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
  xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
  xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
  id="diagram_${key}"
  targetNamespace="${TYPE_TARGET[type]}">
  <bpmn2:process id="${key}" name="${name}" isExecutable="true">
  </bpmn2:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="${key}">
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn2:definitions>`;
};

4.汉化见另外一篇文章

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
EasyUI是一个基于jQuery的UI库,它提供了一组易于使用的UI组件和工具,可以帮助开发人员在前端快速构建简洁美观的界面。Activiti是一个开源的业务流程管理(BPM)框架,它提供了完整的工作流引擎,可以用于管理和执行各种类型的工作流程。 EasyUI结合Activiti可以实现一个Web版的流程设计器,通过这个设计器,用户可以在前端界面上进行工作流程的设计和配置。具体实现步骤如下: 1. 引入EasyUI和Activiti的相关库文件,确保开发环境中能够正常加载这些资源。 2. 创建一个Web页面,使用EasyUI提供的布局和组件进行界面的搭建。可以使用EasyUI提供的面板(Panel)、标签页(Tabs)等组件来实现一个分区域的界面布局,方便用户进行操作。 3. 在页面中添加流程设计器所需的元素,例如画布(Canvas)、工具栏(Toolbar)等。可以使用EasyUI提供的拖拽功能来实现元素的可拖拽和放置。 4. 通过EasyUI的事件机制,添加相关事件处理函数。例如,当用户在工具栏中选择了某个任务节点的图标后,可以通过事件处理函数在画布上创建该任务节点的图形表示。 5. 使用EasyUI提供的交互功能,实现一些操作的响应效果。例如,当用户在画布上选择了某个已有的任务节点图形后,可以使用EasyUI提供的高亮效果来标识用户的选择。 6. 结合Activiti的API,将用户的设计配置保存到数据库中,以便后续的流程执行。可以使用EasyUI提供的表单组件和验证规则来方便地收集和验证用户的输入。 通过以上步骤,就可以使用EasyUI实现一个基于Activiti的Web版流程设计器。用户可以通过页面上的操作,设计和配置工作流程,并将其保存到数据库中。在实际的应用中,可以将该设计器嵌入到公司的内部系统中,方便各个部门的员工进行流程的设计和管理。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值