天天看點

BPMN 自定義流水線

BPMN 自定義流水線

跟着教程做就可以

​​https://juejin.cn/post/6844904017567416328​​
<template>

  <div class="containers">
    <div>
      <el-form :model="formData" label-position="right" label-width="60px">
        <el-form-item label="名字:">
          <el-input v-model="formData.name" clearable placeholder="請輸入" />
        </el-form-item>
      </el-form>
    </div>
    <el-button size="mini" type="primary"  @click="open">儲存</el-button>
    <div class="canvas" ref="canvas"></div>
<!--    <div id="js-properties-panel" class="panel"></div>-->
    <properties-view v-if="bpmnModeler" :modeler="bpmnModeler"></properties-view>
  </div>



</template>


<script>
import {
  createBpmn,
  deleteBpmn,
  deleteBpmnByIds,
  updateBpmn,
  findBpmn,
  getBpmnList
} from '@/api/bpmn' //  此處請自行替換位址
import BpmnModeler from 'bpmn-js/lib/Modeler'
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 CustomModeler from './custom/customModeler'
import contextPadProvider  from './custom/CustomContextPad'
import CustomRenderer from './custom/CustomRenderer'

import { mapGetters } from 'vuex'
import customTranslate from "./translations";
import {createDataItem} from "@/api/dataItem";
import {findConfigexeclog} from "@/api/configexeclog";
// 自定義的 properties-panel内容
// import propertiesProviderModule from './properties-panel-extension/provider/authority';
// import authorityModdleDescriptor from './properties-panel-extension/descriptors/authority'
import PropertiesView from './custom-properties-panel/PropertiesView'

var customTranslateModule = {
  translate: ['value', customTranslate]
};

export default {
  name: 'bpmncreate',
  components: {
    PropertiesView
  },
  data() {
    return {
      bpmnModeler: null,
      container: null,
      canvas: null,
      formData:{
        name:'',
        text:'',
      }

    }
  },
  created() {
    const id = this.$route.query.id
    if (id){
      const res = findBpmn({ID: id}).then(data => {
        this.formData = data.data.rebpmn
        this.createNewDiagram()
      });
    }
  },
  mounted(){
    const canvas = this.$refs.canvas
    // 模組化
    this.bpmnModeler = new CustomModeler({
      container: canvas,
      //添加控制闆
      propertiesPanel: {
        parent: '#js-properties-panel'
      },
      additionalModules: [
        propertiesProviderModule,
        // propertiesPanelModule,  // 原版 右邊
        contextPadProvider,
        CustomRenderer,
        customTranslateModule
      ],
      moddleExtensions: {
        // camunda: camundaModdleDescriptor
        // authority: authorityModdleDescriptor  // 右邊 注釋
      }
    })
    this.createNewDiagram()
  },
  computed: {
    ...mapGetters('user', ['userInfo'])
  },
  methods: {
    createNewDiagram () {
      let bpmnXmlStr = ''
      if (this.formData.text === ""){
        bpmnXmlStr = `
      <?xml version="1.0" encoding="UTF-8"?>
        <bpmn2:definitions xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" id="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
          <bpmn2:process id="a12345" name="">
          </bpmn2:process>
          <bpmndi:BPMNDiagram id="">
            <bpmndi:BPMNPlane id="" bpmnElement="">

            </bpmndi:BPMNPlane>
          </bpmndi:BPMNDiagram>
        <processType id="test"/></bpmn2:definitions>
      `
      }else{
        bpmnXmlStr = this.formData.text
      }
      this.bpmnModeler.importXML(bpmnXmlStr, (err) => {
        if (err) {
          console.error(err)
        }
      })
    },

    open () {
      if( this.formData.name === ""){
        this.$message({
          type: 'error',
          message: '名字不能為空,未儲存!請輸入名字後,再儲存!'
        })
        return
      }

      const that = this
      that.saveDiagram(async function (err, xml) {
        const id = that.$route.query.id
        if (!id){
          const res = await createBpmn({"text":xml,"name":that.formData.name})
          if (res["code"]=== 0 ){
            that.$message({
              type: 'success',
              message: '建立送出成功!'
            })
          }else{
            that.$message({
              type: 'error',
              message: '建立送出失敗!'
            })
          }
        }else{
          that.formData.text=xml
          const res = await updateBpmn(that.formData)
          if (res["code"]=== 0 ){
            that.$message({
              type: 'success',
              message: '更新送出成功!'
            })
          }else{
            that.$message({
              type: 'error',
              message: '更新送出失敗!'
            })
          }
        }

      })

    },
    // 下載下傳為bpmn格式,done是個函數,調用的時候傳入的
    saveDiagram(done) {
      // 把傳入的done再傳給bpmn原型的saveXML函數調用
      this.bpmnModeler.saveXML({ format: true }, function(err, xml) {
        done(err, xml)
      })
    }
  }
}
</script>

<style scoped>

@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';

.containers{
  position: absolute;
  background-color: #ffffff;
  width: 100%;
  height: 100%;
}
.canvas{
  width: 100%;
  height: 100%;
}
.panel{
  position: absolute;
  right: 0;
  top: 0;
  width: 600px;
}
</style>      
BPMN 自定義流水線

生成的xml

<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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="sample-diagram" targetNamespace="http://bpmn.io/schema/bpmn" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd">
    <bpmn2:process id="a123456" name="腳本112222">
        <bpmn2:startEvent id="Event_05qt21g" name="開始">
            <bpmn2:outgoing>Flow_1t09x1a</bpmn2:outgoing>
        </bpmn2:startEvent>
        <bpmn2:task id="Activity_1ictc73" name="腳本1" shell="腳本1">
            <bpmn2:incoming>Flow_1t09x1a</bpmn2:incoming>
            <bpmn2:outgoing>Flow_0s57kw1</bpmn2:outgoing>
        </bpmn2:task>
        <bpmn2:sequenceFlow id="Flow_1t09x1a" sourceRef="Event_05qt21g" targetRef="Activity_1ictc73" />
        <bpmn2:task id="Activity_0ka4fqg" name="腳本2" shell="腳本2">
            <bpmn2:incoming>Flow_0s57kw1</bpmn2:incoming>
            <bpmn2:outgoing>Flow_00gs2sy</bpmn2:outgoing>
        </bpmn2:task>
        <bpmn2:sequenceFlow id="Flow_0s57kw1" sourceRef="Activity_1ictc73" targetRef="Activity_0ka4fqg" />
        <bpmn2:task id="Activity_0l7dnwm" name="腳本3" shell="腳本3">
            <bpmn2:incoming>Flow_00gs2sy</bpmn2:incoming>
            <bpmn2:outgoing>Flow_1qn797p</bpmn2:outgoing>
        </bpmn2:task>
        <bpmn2:sequenceFlow id="Flow_00gs2sy" sourceRef="Activity_0ka4fqg" targetRef="Activity_0l7dnwm" />
        <bpmn2:endEvent id="Event_0f2wok6" name="結束">
            <bpmn2:incoming>Flow_1qn797p</bpmn2:incoming>
        </bpmn2:endEvent>
        <bpmn2:sequenceFlow id="Flow_1qn797p" sourceRef="Activity_0l7dnwm" targetRef="Event_0f2wok6" />
    </bpmn2:process>
    <bpmndi:BPMNDiagram id="">
        <bpmndi:BPMNPlane id="" bpmnElement="a123456">
            <bpmndi:BPMNEdge id="Flow_1t09x1a_di" bpmnElement="Flow_1t09x1a">
                <di:waypoint x="230" y="100" />
                <di:waypoint x="356" y="100" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge id="Flow_0s57kw1_di" bpmnElement="Flow_0s57kw1">
                <di:waypoint x="404" y="100" />
                <di:waypoint x="530" y="100" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge id="Flow_00gs2sy_di" bpmnElement="Flow_00gs2sy">
                <di:waypoint x="578" y="100" />
                <di:waypoint x="710" y="100" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge id="Flow_1qn797p_di" bpmnElement="Flow_1qn797p">
                <di:waypoint x="758" y="100" />
                <di:waypoint x="900" y="100" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNShape id="Event_05qt21g_di" bpmnElement="Event_05qt21g">
                <dc:Bounds x="190" y="80" width="40" height="40" />
                <bpmndi:BPMNLabel>
                    <dc:Bounds x="199" y="127" width="22" height="14" />
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape id="Activity_1ictc73_di" bpmnElement="Activity_1ictc73">
                <dc:Bounds x="356" y="76" width="48" height="48" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape id="Activity_0ka4fqg_di" bpmnElement="Activity_0ka4fqg">
                <dc:Bounds x="530" y="76" width="48" height="48" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape id="Activity_0l7dnwm_di" bpmnElement="Activity_0l7dnwm">
                <dc:Bounds x="710" y="76" width="48" height="48" />
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape id="Event_0f2wok6_di" bpmnElement="Event_0f2wok6">
                <dc:Bounds x="900" y="80" width="40" height="40" />
                <bpmndi:BPMNLabel>
                    <dc:Bounds x="909" y="127" width="22" height="14" />
                </bpmndi:BPMNLabel>
            </bpmndi:BPMNShape>
        </bpmndi:BPMNPlane>
    </bpmndi:BPMNDiagram>
</bpmn2:definitions>      

後端寫解析器

package main

import (
    "fmt"
    "github.com/beevik/etree"
)


func main() {
    doc := etree.NewDocument()
    if err := doc.ReadFromFile("test/1.xml"); err != nil {
        panic(err)
    }
    root := doc.SelectElement("bpmn2:definitions")
    fmt.Println("ROOT element:", root.Tag)
    for _, book := range root.SelectElements("bpmn2:process") {
        fmt.Println("CHILD element:", book.Tag)
            if title := book.SelectElement("bpmn2:task"); title != nil {
                id := title.SelectAttrValue("id", "unknown")
                name := title.SelectAttrValue("name", "unknown")
                shell := title.SelectAttrValue("shell", "unknown")
                fmt.Println(id,name,shell)
                for _, attr := range title.Attr {
                    fmt.Printf("  ATTR: %s=%s\n", attr.Key, attr.Value)
                }
            }

    }
}      

繼續閱讀