vue3使用工作流bpmn.js实现保存 ,新增,修改 ,右边工具栏自定义,属性栏自定义

这篇具有很好参考价值的文章主要介绍了vue3使用工作流bpmn.js实现保存 ,新增,修改 ,右边工具栏自定义,属性栏自定义。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

vue3使用工作流bnpm.js实现保存 ,新增,修改 ,右边工具栏自定义,属性栏自定义文章来源地址https://www.toymoban.com/news/detail-534890.html

<template>
  <div class="containers">
    <div class="canvas" ref="canvas"></div>
    <div id="js-properties-panel" class="panel"></div>
    <!--xml-->
    <!--自定义右边属性面板-->
    <div class="custom-properties-panel">
      <div class="empty" v-if="selectedElementsArr.selectedElements.length <= 0"
        >请选择一个元素</div
      >
      <div class="empty" v-else-if="selectedElementsArr.selectedElements.length > 1"
        >只能选择一个元素</div
      >
      <div v-else>
        <fieldset class="element-item">
          <label>节点id</label>
          <span>{{ element.id }}</span>
        </fieldset>
        <fieldset class="element-item">
          <label>名称&nbsp;&nbsp;&nbsp;&nbsp;</label>
          <input :value="element.nmae" @change="(event) => changeField(event, 'name')" />
        </fieldset>
        <fieldset class="element-item">
          <label>用户名</label>
          <select
            @change="changeEventType"
            :value="eventType"
            style="width: 182px; border: 1px solid #d9d9d9; border-radius: 5px"
          >
            <option
              v-for="option in eventTypesArr.eventTypes"
              :key="option.value"
              :value="option.value"
              >{{ option.label }}</option
            >
          </select>
        </fieldset>
      </div>
    </div>
    <!--自定义右边属性面板完-->
    <ul class="buttons">
      <li>
        <a-button ref="saveDiagramlink" title="保存为bpmn" @click="getXML()"
          >保存最新的xml文件</a-button
        >
      </li>
    </ul>
  </div>
</template>
<script setup>
  // import { workFlowApi} from '/@/api/bnpm/bnpm'
  import { workFlowApi } from '../../../api/bnpm/bnpm'
  import { ref, onMounted, reactive } from 'vue'
  // import { message } from 'ant-design-vue'
  // import { ElMessage } from 'element-plus'
  import BpmnModeler from 'bpmn-js/lib/Modeler'

  import { useRouter } from 'vue-router'
  import { xmlStr } from '../../../mock/xmlStr'
  //右侧属性栏
  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'

  //引入mitt
  // import emitter from '../../../utils/mitt/bus'
  import { vmviewdata, vmviewname } from '../bnpmtext/index.vue'

  import { ElMessage, ElMessageBox } from 'element-plus'
  // import type { Action } from 'element-plus'

  // 汉化组件
  import customTranslate from './customTranslate'
  // import { BpmnpropertiesProviderModule, BpmnpropertiesPanelModule } from 'bpmn-js-properties-panel'
  // bpmn建模器
  let bpmnModeler = reactive({})
  // let container = ref(null)
  let canvas = ref()
  let dataONE = reactive({})
  const saveDiagramlink = ref()
  const form = reactive({
    region: '',
  })

  // let defaultXML = ref()
  // 自定义右边属性面板属性定义
  //当前选择的元素合集
  let selectedElementsArr = reactive({
    selectedElements: [],
  })

  let element = ref(null)
  let eventType = ref()

  //邮件发送参数
  // let recipientmail = reactive({
  //   recipient: ['dingzicool@sina.com', 'dingzicool@sina.com'],
  // })

  let eventTypesArr = reactive({
    eventTypes: [
      { label: '请选择用户', value: '' },
      { label: '张三', value: 'bpmn:MessageEventDefinition' },
      { label: '李四', value: 'bpmn:TimerEventDefinition' },
      { label: '王五', value: 'bpmn:ConditionalEventDefinition' },
    ],
  })
  const router = useRouter()

  //保存最新的bpmn文件
  let bnpmXML = reactive({
    workname: '',
    content: '',
  })

  //let content =ref()
  //挂载时初始化
  onMounted(() => {
    init()
  })

  function init() {
    //汉化组件的引入使用
    const customTranslateModule = {
      translate: ['value', customTranslate],
    }

    //可操作时候创建实例为BpmnModeler
    bpmnModeler = new BpmnModeler({
      container: canvas.value,
      //添加控制板
      //添加控制板
      propertiesPanel: {
        parent: '#js-properties-panel',
      },
      additionalModules: [
        // 右边的属性栏
        propertiesPanelModule,
        propertiesProviderModule,
        //汉化
        customTranslateModule,
      ],
      moddleExtensions: {
        camunda: camundaModdleDescriptor,
        // authority: authorityModdleDescriptor,
      },
    })
    createNewDiagram()
    //  createNewDiagram(zhangcheng)

    // selection.changed监听选中的元素
    bpmnModeler.on('selection.changed', (e) => {
      // console.log('###HH', e)
      selectedElementsArr.selectedElements = e.newSelection // 数组, 可能有多个
      // console.log('###H', selectedElementsArr.selectedElements)
      console.log(element, e.newSelection[0])
      element = e.newSelection[0] // 默认取第一个
    })

    //使用element.changed监听发生改变的元素
    bpmnModeler.on('element.changed', (e) => {
      const { element } = e
      console.log('@@@$$$', element)
      // const { element: currentElement } = this
      // 如果没有 element
      if (!element.value) {
        return
      }
      if (element.id === element.value.id) {
        element.value = element
      }
    })
  }

  //自定义面板内容
  /**
   * 更新元素属性
   * @param { Object } 要更新的属性, 例如 { name: '', id: '' }
   *
   */

  function updateProperties(properties) {
    const modeling = bpmnModeler.get('modeling')
    console.log(element, properties)
    modeling.updateProperties(element, properties)
  }

  /**
   * 改变控件触发的事件
   * @param { Object } input的Event
   * @param { String } 要修改的属性的名称
   *
   *
   */
  // 当控件内的内容发生改变时, 同步更新element.
  function changeField(event, type) {
    const value = event.target.value
    let properties = {}
    properties[type] = value
    element[type] = value
    updateProperties(properties) // 调用属性更新方法
  }

  // 用户下拉菜单
  function changeEventType(event) {
    const value = event.target.value
    const bpmnReplace = bpmnModeler.get('bpmnReplace')
    eventType.value = value
    bpmnReplace.replaceElement(element, {
      type: element.value.businessObject.$type,
      eventDefinitionType: value,
    })
  }

  function createNewDiagram() {
    // console.log('我是数据', vmviewdata)
    if (vmviewdata.value == undefined || vmviewdata.value == '') {
      // 新增操作时,界面的初始化
      bpmnModeler.importXML(xmlStr, (err) => {
        if (err) {
          // console.error(err)
        } else {
          // 这里是成功之后的回调, 可以在这里做一系列事情
          success()
        }
        // 让图能自适应屏幕
        var canvas = bpmnModeler.get('canvas')
        canvas.zoom('fit-viewport')
      })
    } else {
      // 修改操作时,界面的初始化
      bpmnModeler.importXML(vmviewdata.value, (err) => {
        if (err) {
          // console.error(err)
        } else {
          // 这里是成功之后的回调, 可以在这里做一系列事情
          success()
        }
        // 让图能自适应屏幕
        var canvas = bpmnModeler.get('canvas')
        canvas.zoom('fit-viewport')
      })
    }
  }

  function success() {
    // console.log('创建成功!')
    addBpmnListener()
  }

  function addBpmnListener() {
    // 给图绑定事件,当图有发生改变就会触发这个事件
    bpmnModeler.on('commandStack.changed', () => {
      saveDiagram(function (err, xml) {
        bnpmXML.content = xml
        // 这里获取到的就是最新的xml信息
        console.log('zx', xml)
        //setEncoded(saveDiagramlink, 'diagram.bpmn', err ? null : xml)
      })

      // //邮件发送
      // getSendmail(recipientmail).then((res) => {
      //   console.log('邮件发送', res)
      // })
    })
  }

  //绘制图形保存最新的xml
  function getXML() {
    if (vmviewdata.value == undefined || vmviewdata.value == '') {
      ElMessageBox.prompt('请输入保存的文件名称', {
        confirmButtonText: '保存',
        cancelButtonText: '取消',
        inputErrorMessage: '文件名称不能为空',
      })
        .then(({ value }) => {
          // ElMessage({
          //   type: 'success',
          //   message: `Your email is:${value}`,
          // })
          bnpmXML.workname = value
          workFlowApi(bnpmXML).then((res) => {
            ElMessage({
              type: 'success',
              message: '成功',
            })

            if (res) {
              router.push({
                name: 'bnpmtext',
              })
            }
            console.log('bj', res)
          })

          bnpmXML.content = ''
        })
        .catch(() => {
          ElMessage({
            type: 'info',
            message: '保存失败',
          })
        })
    } else {
      // 修改时的文件名
      let xmlName = vmviewname.value
      // 文件名去除前缀和后缀的字符 /bpmn .
      let name = xmlName
        .replace(/bpmn/g, '')
        .replace(/\//g, '')
        .replace(/\\/g, '')
        .replace(/\./g, '')

      ElMessageBox.prompt('请输入修改的文件名称', {
        confirmButtonText: '保存',
        cancelButtonText: '取消',
        inputErrorMessage: '文件名称不能为空',
        inputValue: name, // 赋值文本框
      })
        .then(({ value }) => {
          bnpmXML.workname = value
          // ElMessage({
          //   type: 'success',
          //   message: `Your email is:${value}`,
          // })

          // value = vmviewname
          workFlowApi(bnpmXML).then((res) => {
            ElMessage({
              type: 'success',
              message: '成功',
            })

            if (res) {
              router.push({
                name: 'bnpmtext',
              })
            }

            // 保存后清空原有的文件名和xml内容
            vmviewdata.value = ''
            vmviewname.value = ''

            console.log('bj', res)
          })
        })
        .catch(() => {
          ElMessage({
            type: 'info',
            message: '保存失败',
          })
        })
    }

    console.log('weihao:', bnpmXML.content)
  }

  // 下载为bpmn格式,done是个函数,调用的时候传入的
  function saveDiagram(done) {
    //console.log("weu",done)
    // 把传入的done再传给bpmn原型的saveXML函数调用
    bpmnModeler.saveXML({ format: true }, function (err, xml) {
      // return (urlq = xml)
      //console.log('iiii', urlq)
      done(err, xml)
    })
  }
  function setEncoded(link, name, data) {
    //   console.log('222223333', data)
    dataONE = data
    // console.log('dataONE', dataONE)

    // const dataONE = data
    // 把xml转换为URI,下载要用到的
    const encodedData = encodeURIComponent(data)
    //console.log('222224444', encodedData)
    // 下载图的具体操作,改变a的属性,className令a标签可点击,href令能下载,download是下载的文件的名字
    //  console.log('hahhah', link, name, data)
    let xmlFile = new File([data], 'test.bpmn')
    //console.log('22222222222222222', xmlFile)
    // if (data) {
    //   link.className = 'active'
    //   link.href = 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData
    //   link.download = name
    // }
  }
</script>
<style scoped>
  .containers {
    position: absolute;
    background-color: #fff;
    width: 100%;
    height: 55.5rem;
  }

  .canvas {
    width: 100%;
    height: 100%;
  }

  .panel {
    position: absolute;
    right: 0;
    top: 0;
    width: 300px;
  }

  .buttons {
    position: absolute;
    left: 20px;
    bottom: 20px;
  }

  .buttons li {
    display: inline-block;
    margin: 5px;
  }

  .buttons li a {
    color: #999;
    background: #eee;
    cursor: not-allowed;
    padding: 8px;
    border: 1px solid #ccc;
    text-decoration: none;
  }

  .buttons li a.active {
    color: #333;
    background: #fff;
    cursor: pointer;
  }

  /** 自定义属性面板样式 **/
  .custom-properties-panel {
    position: absolute;
    right: 0;
    top: 0;
    width: 300px;
    background-color: #fff9f9;
    border-color: rgba(0, 0, 0, 0.09);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
    padding: 20px;
  }

  .custom-properties-panel {
    position: absolute;
    right: 300px;
    top: 0;
    width: 300px;
    background-color: #fff9f9;
    border-color: rgba(0, 0, 0, 0.09);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.09);
    padding: 20px;
  }

  .empty {
    height: 200px;
    line-height: 200px;
    font-weight: 700;
  }

  .element-item {
    padding: 10px;
    margin-top: 5px;
    border: 1px solid;
    border-color: rgb(182, 182, 182);
    border-radius: 8px;
  }

  .element-item:first-child {
    margin-top: 0;
  }

  .custom-properties-panel input,
  .custom-properties-panel textarea {
    padding: 4px 11px;
    color: rgba(0, 0, 0, 0.65);
    font-size: 14px;
    background-color: #fff;
    background-image: none;
    border: 1px solid #d9d9d9;
    border-radius: 4px;
    transition: all 0.3s;
    outline: none;
  }

  .custom-properties-panel input:focus,
  .custom-properties-panel button:focus,
  .custom-properties-panel textarea:focus,
  .custom-properties-panel [contenteditable]:focus {
    border-color: rgb(239, 112, 96);
    box-shadow: 0 0 1px 2px rgb(239, 112, 96, 0.2);
  }

  .custom-properties-panel label {
    font-weight: bold;
  }

  .custom-properties-panel label:after {
    content: ': ';
  }

  .custom-properties-panel button + button {
    margin-left: 10px;
  }
</style>

到了这里,关于vue3使用工作流bpmn.js实现保存 ,新增,修改 ,右边工具栏自定义,属性栏自定义的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Camunda 7工作流引擎 API 以及与Springboot集成实现工作流配置全纪录

    项目中需要用到工作流引擎来设计部分业务流程,框架选型最终选择了 Camunda7,关于 Camunda以及 Activity 等其他工作流 引擎的介绍及对比不再介绍,这里只介绍与现有Springboot项目的集成以及具体使用及配置 流程(PROCESS): 通过工具建模最终生成的BPMN文件,里面有整个流程的定

    2024年02月10日
    浏览(58)
  • 工作流flowable实现撤回

    Flowable是一个开源的工作流引擎,可以实现工作流程的自动化管理,包括任务分配、流转、审批等。如果需要实现撤回功能,可以考虑以下方案: 在流程定义中添加一个撤回节点,允许任务的发起人在任务未被处理前撤回任务。当发起人选择撤回任务时,任务将被撤回至撤回

    2024年02月09日
    浏览(59)
  • 若依(RuoYi-Vue)+Flowable工作流前后端整合教程

    此教程适合若依前后端分离项目,其他项目可以在扩展列表中进行查找。 近期公司里需要对很久以前的RuoYi-Vue前后端分离项目扩展出flowable的功能,当然这个重任也是落在了我的身上(不然也不会有这篇文章),然后我在官网看到了RuoYi-Vue-Flowable这个项目,按照文档提供的迁

    2023年04月21日
    浏览(58)
  • 芋道视频199 - 工作流 - 关系图 - ruoyi-vue-pro

    数据库:bpm_form。实体类:BpmFormDO.java:  页面操作: 数据库:ACT_RE_MODEL 流程模板信息表,存储流程模板相关描述信息。但其真正内容存储在act_ge_bytearray表中,以字节形式存储;实体类:Model.java。 字段名 字段值 字段含义 ID_ c64059b7-a4d1-11ee-a7ee-3cf01158cd6c 主键 REV_ 1 数据版本

    2024年02月02日
    浏览(52)
  • GitHub工作流的使用笔记

    有些东西真的就是要不断的试错不断地试错才能摸索到一点点,就是摸索到凌晨两三点第二天要8点起床感觉要死。 为什么我会用这个东东,因为我搞的阿里云服务器2个g的运行内存,打包这玩意贼消耗内存,本来想搞Jenkins但是服务器上搞更要内存,本机搞又没必要,刚好之

    2024年04月26日
    浏览(31)
  • Spring Boot 整合 Camunda 实现工作流

    工作流是我们开发企业应用几乎必备的一项功能,工作流引擎发展至今已经有非常多的产品。最近正好在接触 Camunda ,所以来做个简单的入门整合介绍。如果您也刚好在调研或者刚开始计划接入,希望本文对您有所帮助。如果您是一名Java开发或Spring框架爱好者,欢迎关注我程

    2024年01月18日
    浏览(68)
  • Spring Boot + Activiti 结合,实现工作流

    Activiti是一个工作流引擎,Activiti可以将业务系统中复杂的业务流程抽取出来,使用专门的建模语言BPMN2.0进行定义,业务流程按照预先定义的流程进行执行,实现了系统的流程由Activiti进行管理,减少业务系统由于流程变更进行系统升级改造的工作量,Activiti流程就是数据库表

    2023年04月13日
    浏览(78)
  • [AIGC] 如何设计和实现工作流的审批项目?

    工作流的审批项目是指一个系统化、可重复的审批过程,它能够帮助你更有效地完成审批任务和达成目标。无论你是一个项目经理、一个审批官还是一个企业主管,设计和实现工作流的审批项目都是一个重要的步骤。 工作流的审批项目能够帮助你: 节省时间:工作流的审批

    2024年02月19日
    浏览(36)
  • Java工作流框架:探索流程引擎的实现和应用

    目前,市面上有很多基于SpringBoot+Vue前后端分离的Java快速开发框架和工作流开发框架可供选择。以下是一些比较流行的框架: 1. Spring Cloud:Spring Cloud是一套基于Spring Boot的开发工具,用于快速构建分布式系统中的服务。它利用Spring Boot的便利来简化了分布式系统的开发,并通

    2024年02月14日
    浏览(48)
  • Springboot整合Camunda工作流引擎实现审批流程实例

    环境:Spingboot2.6.14 + camunda-spring-boot-starter7.18.0 依赖配置 应用程序配置 通过上面的配置后访问控制台: http://localhost:8100/workflow/ 默认是没有上面的tasks中的内容,这里是我之前测试数据 环境准备好后,接下来就可以设计工作流程。 上面的 camunda-bpm-spring-boot-starter-rest依赖中定义

    2024年02月09日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包