当前位置:   article > 正文

vue antv/x6流程图_vue2 流程拖拽 antv x6

vue2 流程拖拽 antv x6

vue antv/x6流程图

自己设计的流程图 vue2加element-ui 有类似可以直接修改拿去用 每个流程都可以配置,只是流程线没加配置 有需要流程线配置可以看官文档 https://x6.antv.vision/zh/docs/tutorial/basic/graph 我用的antv/x6版本是"@antv/x6": “~1.16.0”,

<template>
  <div>
    <el-button
      style="float: right; margin-top: -70px; margin-right: 180px"
      size="mini"
      type="primary"
      @click="saveFlow"
    >
      保存
    </el-button>
    <el-button
      style="float: right; margin-top: -70px; margin-right: 100px"
      size="mini"
      type="primary"
      @click="$router.back(-1)"
    >
      返回
    </el-button>
    <el-container class="process-edit-container">
      <!-- 顶部功能区域 -->
      <el-header>
        <el-form ref="workflow" :model="workflow" :rules="rules" label-width="80px" style="display: flex">
          <el-form-item label="名称" prop="name" style="width: 300px">
            <el-input v-model="workflow.name" size="mini" :disabled="disables" />
          </el-form-item>
          <el-form-item label="描述" prop="description" style="width: 300px">
            <el-input v-model="workflow.description" size="mini" />
          </el-form-item>
          <el-form-item label="产品线" prop="productLine" style="width: 300px">
            <el-select
              v-model="workflow.productLine"
              clearable
              filterable
              placeholder="请选择产品线"
              size="mini"
              style="width: 100%"
              :disabled="disables"
              @change="getJobName"
            >
              <el-option
                v-for="(option, index) in [ { label: 'mall', value: 1 }, { label: 'store', value: 2 } ]"
                :key="index"
                :label="option.label"
                :value="option.value"
              />
            </el-select>
          </el-form-item>
        </el-form>
      </el-header>
      <el-container>
        <!-- 左侧组件区域 -->
        <el-aside width="200px">
          <div class="process-component-list">
            <img
              data-color="#FA8C16"
              data-label="开始"
              data-shape="circle"
              data-size="72*72"
              data-type="node"
              src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0ic3RhcnRfbm9kZSIgd2lkdGg9IjgwcHgiIGhlaWdodD0iODBweCIgdmlld0JveD0iMCAwIDgwIDgwIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPgogICAgPCEtLSBHZW5lcmF0b3I6IFNrZXRjaCA0OS4xICg1MTE0NykgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+R3JvdXAgMjwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPgogICAgICAgIDxjaXJjbGUgaWQ9InBhdGgtMSIgY3g9IjM2IiBjeT0iMzYiIHI9IjM2Ij48L2NpcmNsZT4KICAgICAgICA8ZmlsdGVyIHg9Ii05LjclIiB5PSItNi45JSIgd2lkdGg9IjExOS40JSIgaGVpZ2h0PSIxMTkuNCUiIGZpbHRlclVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgaWQ9ImZpbHRlci0yIj4KICAgICAgICAgICAgPGZlT2Zmc2V0IGR4PSIwIiBkeT0iMiIgaW49IlNvdXJjZUFscGhhIiByZXN1bHQ9InNoYWRvd09mZnNldE91dGVyMSI+PC9mZU9mZnNldD4KICAgICAgICAgICAgPGZlR2F1c3NpYW5CbHVyIHN0ZERldmlhdGlvbj0iMiIgaW49InNoYWRvd09mZnNldE91dGVyMSIgcmVzdWx0PSJzaGFkb3dCbHVyT3V0ZXIxIj48L2ZlR2F1c3NpYW5CbHVyPgogICAgICAgICAgICA8ZmVDb21wb3NpdGUgaW49InNoYWRvd0JsdXJPdXRlcjEiIGluMj0iU291cmNlQWxwaGEiIG9wZXJhdG9yPSJvdXQiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSI+PC9mZUNvbXBvc2l0ZT4KICAgICAgICAgICAgPGZlQ29sb3JNYXRyaXggdmFsdWVzPSIwIDAgMCAwIDAgICAwIDAgMCAwIDAgICAwIDAgMCAwIDAgIDAgMCAwIDAuMDQgMCIgdHlwZT0ibWF0cml4IiBpbj0ic2hhZG93Qmx1ck91dGVyMSI+PC9mZUNvbG9yTWF0cml4PgogICAgICAgIDwvZmlsdGVyPgogICAgPC9kZWZzPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9IuWfuuehgOa1geeoi+Wbvi0wMSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTEwNi4wMDAwMDAsIC05My4wMDAwMDApIj4KICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwLTIiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDExMC4wMDAwMDAsIDk1LjAwMDAwMCkiPgogICAgICAgICAgICAgICAgPGcgaWQ9Ik92YWwiPgogICAgICAgICAgICAgICAgICAgIDx1c2UgZmlsbD0iYmxhY2siIGZpbGwtb3BhY2l0eT0iMSIgZmlsdGVyPSJ1cmwoI2ZpbHRlci0yKSIgeGxpbms6aHJlZj0iI3BhdGgtMSI+PC91c2U+CiAgICAgICAgICAgICAgICAgICAgPHVzZSBmaWxsLW9wYWNpdHk9IjAuOTIiIGZpbGw9IiNGRkYyRTgiIGZpbGwtcnVsZT0iZXZlbm9kZCIgeGxpbms6aHJlZj0iI3BhdGgtMSI+PC91c2U+CiAgICAgICAgICAgICAgICAgICAgPGNpcmNsZSBzdHJva2U9IiNGRkMwNjkiIHN0cm9rZS13aWR0aD0iMSIgY3g9IjM2IiBjeT0iMzYiIHI9IjM1LjUiPjwvY2lyY2xlPgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgPHRleHQgaWQ9IuW8gOWni+iKgueCuSIgZm9udC1mYW1pbHk9IlBpbmdGYW5nU0MtUmVndWxhciwgUGluZ0ZhbmcgU0MiIGZvbnQtc2l6ZT0iMTIiIGZvbnQtd2VpZ2h0PSJub3JtYWwiIGxpbmUtc3BhY2luZz0iMTIiIGZpbGw9IiMwMDAwMDAiIGZpbGwtb3BhY2l0eT0iMC42NSI+CiAgICAgICAgICAgICAgICAgICAgPHRzcGFuIHg9IjEyIiB5PSI0MSI+5byA5aeL6IqC54K5PC90c3Bhbj4KICAgICAgICAgICAgICAgIDwvdGV4dD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+"
              @mousedown="addNodeToGraph"
            >
            <img
              draggable="false"
              src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iODhweCIgaGVpZ2h0PSI1NnB4IiB2aWV3Qm94PSIwIDAgODggNTYiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDQ5LjEgKDUxMTQ3KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Hcm91cDwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPgogICAgICAgIDxyZWN0IGlkPSJwYXRoLTEiIHg9IjAiIHk9IjAiIHdpZHRoPSI4MCIgaGVpZ2h0PSI0OCIgcng9IjQiPjwvcmVjdD4KICAgICAgICA8ZmlsdGVyIHg9Ii04LjglIiB5PSItMTAuNCUiIHdpZHRoPSIxMTcuNSUiIGhlaWdodD0iMTI5LjIlIiBmaWx0ZXJVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIGlkPSJmaWx0ZXItMiI+CiAgICAgICAgICAgIDxmZU9mZnNldCBkeD0iMCIgZHk9IjIiIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJzaGFkb3dPZmZzZXRPdXRlcjEiPjwvZmVPZmZzZXQ+CiAgICAgICAgICAgIDxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjIiIGluPSJzaGFkb3dPZmZzZXRPdXRlcjEiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSI+PC9mZUdhdXNzaWFuQmx1cj4KICAgICAgICAgICAgPGZlQ29tcG9zaXRlIGluPSJzaGFkb3dCbHVyT3V0ZXIxIiBpbjI9IlNvdXJjZUFscGhhIiBvcGVyYXRvcj0ib3V0IiByZXN1bHQ9InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVDb21wb3NpdGU+CiAgICAgICAgICAgIDxmZUNvbG9yTWF0cml4IHZhbHVlcz0iMCAwIDAgMCAwICAgMCAwIDAgMCAwICAgMCAwIDAgMCAwICAwIDAgMCAwLjA0IDAiIHR5cGU9Im1hdHJpeCIgaW49InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVDb2xvck1hdHJpeD4KICAgICAgICA8L2ZpbHRlcj4KICAgIDwvZGVmcz4KICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSLln7rnoYDmtYHnqIvlm74tMDEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02LjAwMDAwMCwgLTEwNS4wMDAwMDApIj4KICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMC4wMDAwMDAsIDEwNy4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJSZWN0YW5nbGUtMTUtQ29weSI+CiAgICAgICAgICAgICAgICAgICAgPHVzZSBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIxIiBmaWx0ZXI9InVybCgjZmlsdGVyLTIpIiB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgICAgICAgICA8dXNlIGZpbGwtb3BhY2l0eT0iMC45MiIgZmlsbD0iI0U2RjdGRiIgZmlsbC1ydWxlPSJldmVub2RkIiB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgICAgICAgICA8cmVjdCBzdHJva2U9IiMxODkwRkYiIHN0cm9rZS13aWR0aD0iMSIgeD0iMC41IiB5PSIwLjUiIHdpZHRoPSI4MiIgaGVpZ2h0PSI0NyIgcng9IjQiPjwvcmVjdD4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDx0ZXh0IGlkPSLlrqHmibnoioLngrkiIGZvbnQtZmFtaWx5PSJQaW5nRmFuZ1NDLVJlZ3VsYXIsIFBpbmdGYW5nIFNDIiBmb250LXNpemU9IjEyIiBmb250LXdlaWdodD0ibm9ybWFsIiBsaW5lLXNwYWNpbmc9IjEyIiBmaWxsPSIjMDAwMDAwIiBmaWxsLW9wYWNpdHk9IjAuNjUiPgogICAgICAgICAgICAgICAgICAgIDx0c3BhbiB4PSI2IiB5PSIyNiI+SmVua2luc19UYXNrPC90c3Bhbj4KICAgICAgICAgICAgICAgIDwvdGV4dD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+"
              data-type="node"
              data-shape="rect"
              data-size="90*48"
              data-color="#1890FF"
              data-label="Jenkins_Task"
              @mousedown="addNodeToGraph"
            >
            <img
              draggable="false"
              src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iODhweCIgaGVpZ2h0PSI1NnB4IiB2aWV3Qm94PSIwIDAgODggNTYiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDQ5LjEgKDUxMTQ3KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Hcm91cDwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPgogICAgICAgIDxyZWN0IGlkPSJwYXRoLTEiIHg9IjAiIHk9IjAiIHdpZHRoPSI4MCIgaGVpZ2h0PSI0OCIgcng9IjQiPjwvcmVjdD4KICAgICAgICA8ZmlsdGVyIHg9Ii04LjglIiB5PSItMTAuNCUiIHdpZHRoPSIxMTcuNSUiIGhlaWdodD0iMTI5LjIlIiBmaWx0ZXJVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIGlkPSJmaWx0ZXItMiI+CiAgICAgICAgICAgIDxmZU9mZnNldCBkeD0iMCIgZHk9IjIiIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJzaGFkb3dPZmZzZXRPdXRlcjEiPjwvZmVPZmZzZXQ+CiAgICAgICAgICAgIDxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjIiIGluPSJzaGFkb3dPZmZzZXRPdXRlcjEiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSI+PC9mZUdhdXNzaWFuQmx1cj4KICAgICAgICAgICAgPGZlQ29tcG9zaXRlIGluPSJzaGFkb3dCbHVyT3V0ZXIxIiBpbjI9IlNvdXJjZUFscGhhIiBvcGVyYXRvcj0ib3V0IiByZXN1bHQ9InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVDb21wb3NpdGU+CiAgICAgICAgICAgIDxmZUNvbG9yTWF0cml4IHZhbHVlcz0iMCAwIDAgMCAwICAgMCAwIDAgMCAwICAgMCAwIDAgMCAwICAwIDAgMCAwLjA0IDAiIHR5cGU9Im1hdHJpeCIgaW49InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVDb2xvck1hdHJpeD4KICAgICAgICA8L2ZpbHRlcj4KICAgIDwvZGVmcz4KICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSLln7rnoYDmtYHnqIvlm74tMDEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02LjAwMDAwMCwgLTEwNS4wMDAwMDApIj4KICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMC4wMDAwMDAsIDEwNy4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJSZWN0YW5nbGUtMTUtQ29weSI+CiAgICAgICAgICAgICAgICAgICAgPHVzZSBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIxIiBmaWx0ZXI9InVybCgjZmlsdGVyLTIpIiB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgICAgICAgICA8dXNlIGZpbGwtb3BhY2l0eT0iMC45MiIgZmlsbD0iI0U2RkZGQiIgZmlsbC1ydWxlPSJldmVub2RkIiB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgICAgICAgICA8cmVjdCBzdHJva2U9IiMxODkwRkYiIHN0cm9rZS13aWR0aD0iMSIgeD0iMC41IiB5PSIwLjUiIHdpZHRoPSI3OSIgaGVpZ2h0PSI0NyIgcng9IjQiPjwvcmVjdD4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDx0ZXh0IGlkPSLlrqHmibnoioLngrkiIGZvbnQtZmFtaWx5PSJQaW5nRmFuZ1NDLVJlZ3VsYXIsIFBpbmdGYW5nIFNDIiBmb250LXNpemU9IjEyIiBmb250LXdlaWdodD0ibm9ybWFsIiBsaW5lLXNwYWNpbmc9IjEyIiBmaWxsPSIjMDAwMDAwIiBmaWxsLW9wYWNpdHk9IjAuNjUiPgogICAgICAgICAgICAgICAgICAgIDx0c3BhbiB4PSI2IiB5PSIyNiI+QWlyZmxvd19UYXNrPC90c3Bhbj4KICAgICAgICAgICAgICAgIDwvdGV4dD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+"
              data-type="node"
              data-shape="rect"
              data-size="90*48"
              data-color="#13C2C2"
              data-label="Airflow_Task"
              @mousedown="addNodeToGraph"
            >
            <img
              draggable="false"
              src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iODhweCIgaGVpZ2h0PSI1NnB4IiB2aWV3Qm94PSIwIDAgODggNTYiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDQ5LjEgKDUxMTQ3KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Hcm91cDwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPgogICAgICAgIDxyZWN0IGlkPSJwYXRoLTEiIHg9IjAiIHk9IjAiIHdpZHRoPSI4MCIgaGVpZ2h0PSI0OCIgcng9IjQiPjwvcmVjdD4KICAgICAgICA8ZmlsdGVyIHg9Ii04LjglIiB5PSItMTAuNCUiIHdpZHRoPSIxMTcuNSUiIGhlaWdodD0iMTI5LjIlIiBmaWx0ZXJVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIGlkPSJmaWx0ZXItMiI+CiAgICAgICAgICAgIDxmZU9mZnNldCBkeD0iMCIgZHk9IjIiIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJzaGFkb3dPZmZzZXRPdXRlcjEiPjwvZmVPZmZzZXQ+CiAgICAgICAgICAgIDxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjIiIGluPSJzaGFkb3dPZmZzZXRPdXRlcjEiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSI+PC9mZUdhdXNzaWFuQmx1cj4KICAgICAgICAgICAgPGZlQ29tcG9zaXRlIGluPSJzaGFkb3dCbHVyT3V0ZXIxIiBpbjI9IlNvdXJjZUFscGhhIiBvcGVyYXRvcj0ib3V0IiByZXN1bHQ9InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVDb21wb3NpdGU+CiAgICAgICAgICAgIDxmZUNvbG9yTWF0cml4IHZhbHVlcz0iMCAwIDAgMCAwICAgMCAwIDAgMCAwICAgMCAwIDAgMCAwICAwIDAgMCAwLjA0IDAiIHR5cGU9Im1hdHJpeCIgaW49InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVDb2xvck1hdHJpeD4KICAgICAgICA8L2ZpbHRlcj4KICAgIDwvZGVmcz4KICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSLln7rnoYDmtYHnqIvlm74tMDEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02LjAwMDAwMCwgLTEwNS4wMDAwMDApIj4KICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMC4wMDAwMDAsIDEwNy4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJSZWN0YW5nbGUtMTUtQ29weSI+CiAgICAgICAgICAgICAgICAgICAgPHVzZSBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIxIiBmaWx0ZXI9InVybCgjZmlsdGVyLTIpIiB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgICAgICAgICA8dXNlIGZpbGwtb3BhY2l0eT0iMC45MiIgZmlsbD0iIzAwNzc5OSIgZmlsbC1ydWxlPSJldmVub2RkIiB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgICAgICAgICA8cmVjdCBzdHJva2U9IiMxODkwRkYiIHN0cm9rZS13aWR0aD0iMSIgeD0iMC41IiB5PSIwLjUiIHdpZHRoPSI3OSIgaGVpZ2h0PSI0NyIgcng9IjQiPjwvcmVjdD4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDx0ZXh0IGlkPSLlrqHmibnoioLngrkiIGZvbnQtZmFtaWx5PSJQaW5nRmFuZ1NDLVJlZ3VsYXIsIFBpbmdGYW5nIFNDIiBmb250LXNpemU9IjEyIiBmb250LXdlaWdodD0ibm9ybWFsIiBsaW5lLXNwYWNpbmc9IjEyIiBmaWxsPSIjMDAwMDAwIiBmaWxsLW9wYWNpdHk9IjAuNjUiPgogICAgICAgICAgICAgICAgICAgIDx0c3BhbiB4PSI5IiB5PSIyNiI+U2hlbGxfVGFzazwvdHNwYW4+CiAgICAgICAgICAgICAgICA8L3RleHQ+CiAgICAgICAgICAgIDwvZz4KICAgICAgICA8L2c+CiAgICA8L2c+Cjwvc3ZnPg=="
              data-type="node"
              data-shape="rect"
              data-size="90*48"
              data-color="#008080"
              data-label="Shell_Task"
              @mousedown="addNodeToGraph"
            >
            <img
              draggable="false"
              src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iODhweCIgaGVpZ2h0PSI1NnB4IiB2aWV3Qm94PSIwIDAgODggNTYiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDQ5LjEgKDUxMTQ3KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Hcm91cDwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPgogICAgICAgIDxyZWN0IGlkPSJwYXRoLTEiIHg9IjAiIHk9IjAiIHdpZHRoPSI4MCIgaGVpZ2h0PSI0OCIgcng9IjQiPjwvcmVjdD4KICAgICAgICA8ZmlsdGVyIHg9Ii04LjglIiB5PSItMTAuNCUiIHdpZHRoPSIxMTcuNSUiIGhlaWdodD0iMTI5LjIlIiBmaWx0ZXJVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIGlkPSJmaWx0ZXItMiI+CiAgICAgICAgICAgIDxmZU9mZnNldCBkeD0iMCIgZHk9IjIiIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJzaGFkb3dPZmZzZXRPdXRlcjEiPjwvZmVPZmZzZXQ+CiAgICAgICAgICAgIDxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjIiIGluPSJzaGFkb3dPZmZzZXRPdXRlcjEiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSI+PC9mZUdhdXNzaWFuQmx1cj4KICAgICAgICAgICAgPGZlQ29tcG9zaXRlIGluPSJzaGFkb3dCbHVyT3V0ZXIxIiBpbjI9IlNvdXJjZUFscGhhIiBvcGVyYXRvcj0ib3V0IiByZXN1bHQ9InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVDb21wb3NpdGU+CiAgICAgICAgICAgIDxmZUNvbG9yTWF0cml4IHZhbHVlcz0iMCAwIDAgMCAwICAgMCAwIDAgMCAwICAgMCAwIDAgMCAwICAwIDAgMCAwLjA0IDAiIHR5cGU9Im1hdHJpeCIgaW49InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVDb2xvck1hdHJpeD4KICAgICAgICA8L2ZpbHRlcj4KICAgIDwvZGVmcz4KICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSLln7rnoYDmtYHnqIvlm74tMDEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02LjAwMDAwMCwgLTEwNS4wMDAwMDApIj4KICAgICAgICAgICAgPGcgaWQ9Ikdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxMC4wMDAwMDAsIDEwNy4wMDAwMDApIj4KICAgICAgICAgICAgICAgIDxnIGlkPSJSZWN0YW5nbGUtMTUtQ29weSI+CiAgICAgICAgICAgICAgICAgICAgPHVzZSBmaWxsPSJibGFjayIgZmlsbC1vcGFjaXR5PSIxIiBmaWx0ZXI9InVybCgjZmlsdGVyLTIpIiB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgICAgICAgICA8dXNlIGZpbGwtb3BhY2l0eT0iMC45MiIgZmlsbD0iI0ZGRkYwMCIgZmlsbC1ydWxlPSJldmVub2RkIiB4bGluazpocmVmPSIjcGF0aC0xIj48L3VzZT4KICAgICAgICAgICAgICAgICAgICA8cmVjdCBzdHJva2U9IiMxODkwRkYiIHN0cm9rZS13aWR0aD0iMSIgeD0iMC41IiB5PSIwLjUiIHdpZHRoPSI3OSIgaGVpZ2h0PSI0NyIgcng9IjQiPjwvcmVjdD4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDx0ZXh0IGlkPSLlrqHmibnoioLngrkiIGZvbnQtZmFtaWx5PSJQaW5nRmFuZ1NDLVJlZ3VsYXIsIFBpbmdGYW5nIFNDIiBmb250LXNpemU9IjEyIiBmb250LXdlaWdodD0ibm9ybWFsIiBsaW5lLXNwYWNpbmc9IjEyIiBmaWxsPSIjMDAwMDAwIiBmaWxsLW9wYWNpdHk9IjAuNjUiPgogICAgICAgICAgICAgICAgICAgIDx0c3BhbiB4PSI3IiB5PSIyNiI+UHl0aG9uX1Rhc2s8L3RzcGFuPgogICAgICAgICAgICAgICAgPC90ZXh0PgogICAgICAgICAgICA8L2c+CiAgICAgICAgPC9nPgogICAgPC9nPgo8L3N2Zz4="
              data-type="node"
              data-shape="rect"
              data-size="90*48"
              data-color="#66FF00"
              data-label="Python_Task"
              @mousedown="addNodeToGraph"
            >
            <img
              draggable="false"
              src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iODhweCIgaGVpZ2h0PSI1NnB4IiB2aWV3Qm94PSIwIDAgODggNTYiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDQ5LjEgKDUxMTQ3KSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Hcm91cCA0PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+CiAgICAgICAgPHJlY3QgaWQ9InBhdGgtMSIgeD0iMCIgeT0iMCIgd2lkdGg9IjgwIiBoZWlnaHQ9IjQ4IiByeD0iMjQiPjwvcmVjdD4KICAgICAgICA8ZmlsdGVyIHg9Ii04LjglIiB5PSItMTAuNCUiIHdpZHRoPSIxMTcuNSUiIGhlaWdodD0iMTI5LjIlIiBmaWx0ZXJVbml0cz0ib2JqZWN0Qm91bmRpbmdCb3giIGlkPSJmaWx0ZXItMiI+CiAgICAgICAgICAgIDxmZU9mZnNldCBkeD0iMCIgZHk9IjIiIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJzaGFkb3dPZmZzZXRPdXRlcjEiPjwvZmVPZmZzZXQ+CiAgICAgICAgICAgIDxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjIiIGluPSJzaGFkb3dPZmZzZXRPdXRlcjEiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSI+PC9mZUdhdXNzaWFuQmx1cj4KICAgICAgICAgICAgPGZlQ29tcG9zaXRlIGluPSJzaGFkb3dCbHVyT3V0ZXIxIiBpbjI9IlNvdXJjZUFscGhhIiBvcGVyYXRvcj0ib3V0IiByZXN1bHQ9InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVDb21wb3NpdGU+CiAgICAgICAgICAgIDxmZUNvbG9yTWF0cml4IHZhbHVlcz0iMCAwIDAgMCAwICAgMCAwIDAgMCAwICAgMCAwIDAgMCAwICAwIDAgMCAwLjA0IDAiIHR5cGU9Im1hdHJpeCIgaW49InNoYWRvd0JsdXJPdXRlcjEiPjwvZmVDb2xvck1hdHJpeD4KICAgICAgICA8L2ZpbHRlcj4KICAgIDwvZGVmcz4KICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPgogICAgICAgIDxnIGlkPSLln7rnoYDmtYHnqIvlm74tMDEiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMDIuMDAwMDAwLCAtMTk1LjAwMDAwMCkiPgogICAgICAgICAgICA8ZyBpZD0iR3JvdXAtNCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTA2LjAwMDAwMCwgMTk3LjAwMDAwMCkiPgogICAgICAgICAgICAgICAgPGcgaWQ9IlJlY3RhbmdsZS0xNS1Db3B5LTM1Ij4KICAgICAgICAgICAgICAgICAgICA8dXNlIGZpbGw9ImJsYWNrIiBmaWxsLW9wYWNpdHk9IjEiIGZpbHRlcj0idXJsKCNmaWx0ZXItMikiIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPgogICAgICAgICAgICAgICAgICAgIDx1c2UgZmlsbC1vcGFjaXR5PSIwLjkyIiBmaWxsPSIjRjlGMEZGIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPgogICAgICAgICAgICAgICAgICAgIDxyZWN0IHN0cm9rZT0iI0IzN0ZFQiIgc3Ryb2tlLXdpZHRoPSIxIiB4PSIwLjUiIHk9IjAuNSIgd2lkdGg9Ijc5IiBoZWlnaHQ9IjQ3IiByeD0iMjMuNSI+PC9yZWN0PgogICAgICAgICAgICAgICAgPC9nPgogICAgICAgICAgICAgICAgPHRleHQgaWQ9Iue7k+adn+iKgueCuSIgZm9udC1mYW1pbHk9IlBpbmdGYW5nU0MtUmVndWxhciwgUGluZ0ZhbmcgU0MiIGZvbnQtc2l6ZT0iMTIiIGZvbnQtd2VpZ2h0PSJub3JtYWwiIGxpbmUtc3BhY2luZz0iMTIiIGZpbGw9IiMwMDAwMDAiIGZpbGwtb3BhY2l0eT0iMC42NSI+CiAgICAgICAgICAgICAgICAgICAgPHRzcGFuIHg9IjE2IiB5PSIyOSI+57uT5p2f6IqC54K5PC90c3Bhbj4KICAgICAgICAgICAgICAgIDwvdGV4dD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+"
              data-type="node"
              data-shape="ellipse"
              data-size="80*48"
              data-color="#722ED1"
              data-label="结束"
              @mousedown="addNodeToGraph"
            >
          </div>
        </el-aside>
        <el-main>
          <div ref="processCanvas" class="process-canvas" />
        </el-main>
        <!-- 右侧配置区域 -->
        <el-aside style="width: 200px; height: 700px">
          <!--          <div-->
          <!--            style="display: inline-block;-->
          <!--           width: 400px; height: 650px;-->
          <!--            border: 1px solid #E4E7ED; padding-right: 4px;"-->
          <!--          >-->
          <!--          <el-tabs v-model="activeTab"  style="height: 650px">-->
          <!--            <el-tab-pane label="流程信息" name="processInfo">-->
          <!--            </el-tab-pane>-->
          <!--            <el-tab-pane label="配置信息" name="cellInfo">-->
          <!--            <el-card shadow="never" style="height: 600px">-->
          <el-drawer
            title="节点配置信息"
            :visible.sync="drawer"
            :direction="direction"
          >
            <!--            <template #header>-->
            <!--              <div class="card-header">-->
            <!--                <span>配置信息</span>-->
            <!--              </div>-->
            <!--            </template>-->
            <el-form
              v-if="selectCell &&
                selectCell.shape !== 'edge' &&
                selectCell.shape !== 'circle' &&
                selectCell.shape !== 'ellipse'"
              ref="node"
              :model="node"
              :rules="rules"
              label-width="88px"
              class="father"
            >
              <el-form-item label="节点名称" prop="name" style="margin-right: 20px">
                <el-input v-model="node.name" size="mini" placeholder="请输入节点名称" @input="updateNodeName" />
              </el-form-item>
              <el-form-item label="描述" prop="description" style="margin-top: -20px;margin-right: 20px">
                <el-input v-model="node.description" type="textarea" size="mini" />
              </el-form-item>
              <el-form-item label="节点类型" prop="type" style="margin-top: -20px;margin-right: 20px">
                <el-select
                  v-model.number="node.type"
                  filterable
                  placeholder="请选择处理人类型"
                  size="mini"
                  style="width: 100%"
                  disabled
                  @change="getJobName"
                >
                  <el-option
                    v-for="item in nodeTypeList"
                    :key="item.type"
                    :label="item.name"
                    :value="item.type"
                  />
                </el-select>
              </el-form-item>
              <el-form-item label="Job组件" style="margin-top: -20px;margin-right: 20px">
                <el-select
                  v-model.number="node.component_id"
                  filterable
                  placeholder="请选择job"
                  size="mini"
                  style="width: 100%"
                  @change="getJobParam"
                >
                  <el-option
                    v-for="item in jobList"
                    :key="item.id"
                    :label="item.version > 0?`${item.name}(version:${item.version})`:`${item.name}`"
                    :value="item.id"
                  />
                </el-select>
              </el-form-item>
              <div style="margin-left: 5px">
                输入参数:
              </div>
              <el-card class="process-box" shadow="never">
                <template v-for="(item, index) of node.paramList">
                  <div :key="index">
                    <!-- <el-tooltip class="item" effect="dark" :content="item.description" placement="top-start"> -->
                    <span> {{ item.name }}:</span>&nbsp;
                    <!-- </el-tooltip> -->
                    <!-- <el-form-item :label="item.name" style="margin-top: -20px;"> -->
                    <el-form-item style="margin-left: -50px;">
                      <!--                  33.3%-->
                      <el-select
                        v-model="item.param"
                        filterable
                        placeholder="请选择"
                        size="mini"
                        style="width: 30%;"
                        @change="selectData"
                      >
                        <el-option
                          v-for="key in [{ label: '缺省值', value: 0 },
                                         { label: '定值', value: 1 }, { label: '节点输出值', value: 2 },
                                         { label: '全局参数', value: 3 } ]"
                          :key="key.value"
                          :label="key.label"
                          :value="key.value"
                        />
                      </el-select>&nbsp;
                      <!--                  58.5%-->
                      <el-input
                        v-if="item.param === 0 || item.param === 3"
                        :value="String(item.defaultValue)"
                        size="mini"
                        style="width: 40%"
                        disabled
                      />
                      <el-input
                        v-if="item.param === 1"
                        v-model="item.defaultValue"
                        size="mini"
                        style="width: 40%"
                      />
                      <!--                  28%-->
                      <el-select
                        v-if="item.param === 2"
                        v-model="item.nodeName"
                        filterable
                        placeholder="请选择"
                        size="mini"
                        style="width: 32%"
                        @change="selectJobName"
                      >
                        <el-option
                          v-for="key in node.nodeViewList"
                          :key="key.id"
                          :label="key.name"
                          :value="key.id"
                        />
                      </el-select>&nbsp;
                      <el-select
                        v-if="item.param === 2"
                        v-model="item.export"
                        filterable
                        placeholder="请选择"
                        size="mini"
                        style="width: 32%"
                      >
                        <el-option
                          v-for="key in Object.keys(node.nowNodeExportParam)"
                          :key="key"
                          :label="key"
                          :value="key"
                        />
                      </el-select>&nbsp;
                      <br>
                      <span style="font-size: 12px; margin-top: -15px;">{{ item.description }}</span>
                    </el-form-item>
                  </div>
                </template>
              </el-card>
              <div style="margin: 20px 0 0 5px">
                输出参数:
              </div>
              <el-card class="export-box" shadow="never">
                <span>{{ Object.keys(node.exportParam).join() }}</span>
              </el-card><br>
            </el-form>
            <el-form
              v-if="selectCell && selectCell.shape === 'edge'"
              ref="edge"
              :model="edge"
              :rules="rules"
              label-width="80px"
            >
              <el-form-item v-show="false" label="源节点" prop="sourceStatus" style="margin-top: -20px">
                <el-input v-model.number="edge.sourceStatus" size="mini" placeholder="请输入源节点" readonly />
              </el-form-item>
              <el-form-item v-show="false" label="目标节点" prop="destinationStatus" style="margin-top: -20px;">
                <el-input v-model.number="edge.destinationStatus" size="mini" placeholder="请输入目标节点" readonly />
              </el-form-item>
            </el-form>
          </el-drawer>
          <!--            </el-card>-->
          <!--          </el-tabs>-->
        </el-aside>
      </el-container>
    </el-container>
  </div>
</template>

<script>
// import { getRegisterTestData, getRegisterJobName } from '@/api/integration_test';
import { Graph, Addon } from '@antv/x6';
import { deepCopy } from '../utils/utils';

const { Dnd } = Addon;

export default {
  name: 'ProcessEdit',
  props: {
    labelType: {
      type: Number,
      default: 1,
    },
    data: {
      type: Object,
      default: () => ({
        name: '',
        projectId: null,
        description: '',
        icon: 'el-icon-user',
        iconColor: 'blue',
        tpl: [],
        flow_chart: {
          nodes: [],
          edges: [],
          workflow: {},
        },
      }),
    },
  },
  data: () => ({
    cells: [],
    workflow: {},
    internalChange: false,
    graph: null,
    dnd: null,
    selectCell: null,
    activeTab: 'processInfo',
    projectListTmp: [],
    templateList: [],
    node: {
      importParam: [{ param: '' }],
    },
    edge: {},
    rules: {
      name: [
        { required: true, message: ' ', trigger: 'change' },
      ],
      icon: [
        { required: true, message: ' ', trigger: 'change' },
      ],
      orderId: [
        { required: true, message: ' ', trigger: 'change' },
      ],
      participant: [
        { required: true, message: ' ', trigger: 'change' },
      ],
      type: [
        { required: true, message: ' ', trigger: 'change' },
      ],
      distributeTypeId: [
        { required: true, message: ' ', trigger: 'change' },
      ],
      attributeTypeId: [
        { required: true, message: ' ', trigger: 'change' },
      ],
      sourceStatus: [
        { required: true, message: ' ', trigger: 'change' },
      ],
      created_by: [
        { required: true, message: ' ', trigger: 'change' },
      ],
      productLine: [
        { required: true, message: '请选择产品线', trigger: 'change' },
      ],
      destinationStatus: [
        { required: true, message: ' ', trigger: 'change' },
      ],
    },
    nodeTypeList: [
      { type: 1, name: 'JenkinsJob' },
      { type: 2, name: 'AirflowJob' },
      { type: 3, name: 'ShellJob' },
      { type: 4, name: 'PythonJob' },
    ],
    componentList: [
      { id: 0, name: 'mall' },
      { id: 1, name: 'store' },
      { id: 2, name: 'gate' },
      { id: 4, name: 'airport' },
    ],
    participantOptions: [],
    participantMap: {},
    clickCellMap: {},
    loadUserPromise: [],
    jobInfo: {},
    selectId: -1,
    jobList: [],
    nodeList: [],
    jobNode: {},
    jobCells: [],
    nodeTmpId: -1,
    exportParam: {},
    disables: false,
    dialogVisible: false,
    drawer: false,
    direction: 'rtl',
  }),
  computed: {
    currentTemplateList() {
      return this.templateList.filter((tpl) => {
        if (!this.workflow.tpl || !Array.isArray(this.workflow.tpl) || this.workflow.tpl.length === 0) {
          return false;
        }
        return this.workflow.tpl.indexOf(tpl.id) >= 0;
      });
    },
  },
  watch: {
    labelType: {
      handler(val) {
        if (val === 2) {
          this.disables = true;
        }
      },
      immediate: true,
    },
    data: {
      handler(val) {
        if (this.internalChange) {
          return;
        }
        this.workflow = {
          name: val.name,
          projectId: val.projectId,
          description: val.description,
          icon: val.icon,
          iconColor: val.iconColor,
          tpl: deepCopy(val.tpl),
          productLine: val.product_line,
          nodeConfigs: {},
          edgeConfigs: {},
        };
        const cells = [];
        if (val.flow_chart && val.flow_chart.nodes && val.flow_chart.nodes.length > 0) {
          val.flow_chart.nodes.forEach((node) => {
            const temp = deepCopy(node);
            this.workflow.nodeConfigs[node.id] = temp.valueData;
            delete temp.valueData;
            cells.push(temp);
          });
        }
        if (val.flow_chart && val.flow_chart.edges && val.flow_chart.edges.length > 0) {
          val.flow_chart.edges.forEach((edge) => {
            const temp = deepCopy(edge);
            this.workflow.edgeConfigs[edge.id] = temp.valueData;
            delete temp.valueData;
            cells.push(temp);
          });
        }
        if (this.graph) {
          this.graph.fromJSON({ cells });
          this.graph.centerContent();
        } else {
          this.cells = cells;
        }
      },
      deep: true,
      immediate: true,
    },
  },
  created() {
    this.workflow.name = '测试流程1';
    this.workflow.productLine = 1;
  },
  mounted() {
    this.initG6();
  },
  methods: {
    getRegisterTestData() {
      getRegisterTestData(1).then((res) => {
        console.log(res, 666);
      }, (err) => {
        this.$message({
          type: 'error',
          message: err.errmsg,
        });
        console.error(err);
      });
    },
    selectData(val) {
      this.selectId = val;
    },
    getJobName() {
      if (!this.workflow.productLine) {
        return;
      }
      if (!this.node.type) {
        return;
      }
      // getRegisterJobName(this.workflow.productLine, this.node.type).then((res) => {
      //   if (res) {
      //     this.jobList = res;
      //   }
      // }, (err) => {
      //   this.$message({
      //     type: 'error',
      //     message: err.errmsg,
      //   });
      //   console.error(err);
      // });
      // });
    },
    getJobParam(val) {
      this.jobList.forEach((item) => {
        if (item.id === val) {
          this.node.name = item.name;
          this.selectCell.setAttrs({
            label: {
              text: this.node.name,
            },
          });
          this.nodeList.forEach((keys) => {
            if (this.nodeTmpId === keys.id) {
              const ee = keys;
              ee.exportParam = item.export_param;
            }
          });
          this.workflow.nodeConfigs[this.nodeTmpId].paramList = item.import_param.map(val => Object.assign({}, deepCopy(val), { param: 0, nodeName: '', export: '' }));
          if (item.export_param) {
            this.workflow.nodeConfigs[this.nodeTmpId].exportParam = item.export_param;
          }
        }
      });
      this.getNodeNameList();
    },
    getNodeNameList() {
      if (Object.keys(this.jobNode).length) {
        Object.keys(this.jobNode).forEach((item) => {
          if (this.nodeTmpId === item) {
            this.workflow.nodeConfigs[this.nodeTmpId].nodeViewList = this.jobNode[item];
          }
        });
      }
    },
    selectJobName(val) {
      if (this.workflow.nodeConfigs[val].exportParam) {
        this.workflow.nodeConfigs[this.nodeTmpId].nowNodeExportParam = this.workflow.nodeConfigs[val].exportParam;
      }
    },
    handleCellClick(cell) {
      console.log(cell, 5676);
      if (cell.isNode() && cell.store.data.attrs.label.text !== '开始' && cell.store.data.attrs.label.text !== '结束') {
        this.drawer = true;
      }
      this.activeTab = 'cellInfo';
      this.selectCell = cell;
      const { id } = cell;
      const data = this.graph.toJSON();
      const { cells } = data;
      if (cell.isNode()) {
        if (!this.workflow.nodeConfigs[id]) {
          let type = 0;
          if (cell.attrs.label.text === 'Jenkins_Task') {
            type = 1;
          } else if (cell.attrs.label.text === 'Airflow_Task') {
            type = 2;
          } else if (cell.attrs.label.text === 'Shell_Task') {
            type = 3;
          } else if (cell.attrs.label.text === 'Python_Task') {
            type = 4;
          } else if (cell.label === 'ellipse') {
            type = 5;
          }
          this.workflow.nodeConfigs[id] = {
            tmpId: id,
            name: cell.attrs.label.text,
            type,
            participant: '',
            description: '',
            paramList: [],
            component_id: '',
            import_param: {},
            exportParam: {},
            nowNodeExportParam: {},
            nodeViewList: [],
          };
        }
        this.node = this.workflow.nodeConfigs[id];
        const list1 = cells.filter(item => item.shape === 'rect' && item.attrs.body.stroke === '#a2d2ff');
        const list2 = cells.filter(item => item.shape === 'rect' && item.attrs.body.stroke === '#a0e6e6');
        const list3 = cells.filter(item => item.shape === 'rect' && item.attrs.body.stroke === '#99cccc');
        const list4 = cells.filter(item => item.shape === 'rect' && item.attrs.body.stroke === '#c1ff99');
        if (this.node.name === 'Jenkins_Task') {
          this.node.name = `${this.node.name}${list1.length}`;
          this.selectCell.setAttrs({
            label: {
              text: this.node.name,
            },
          });
        }
        if (this.node.name === 'Airflow_Task') {
          this.node.name = `${this.node.name}${list2.length}`;
          this.selectCell.setAttrs({
            label: {
              text: this.node.name,
            },
          });
        }
        if (this.node.name === 'Shell_Task') {
          this.node.name = `${this.node.name}${list3.length}`;
          this.selectCell.setAttrs({
            label: {
              text: this.node.name,
            },
          });
        }
        if (this.node.name === 'Python_Task') {
          this.node.name = `${this.node.name}${list4.length}`;
          this.selectCell.setAttrs({
            label: {
              text: this.node.name,
            },
          });
        }
        this.getJobName();
        this.nodeTmpId = this.node.tmpId;
      } else {
        if (!this.workflow.edgeConfigs[id]) {
          this.workflow.edgeConfigs[id] = {
            tmpId: id,
            // label: [],
            // name: '',
            sourceStatus: cell.source.cell,
            destinationStatus: cell.target.cell,
            // attributeTypeId: '',
          };
        }
        this.edge = this.workflow.edgeConfigs[id];
      }
      this.nodeList = deepCopy(cells);
      const edgeList = deepCopy(cells);
      edgeList.forEach((item) => {
        if (item.source && item.target) {
          this.jobNode[item.target.cell] = [];
          // let list = this.jobNode[item.target.cell];
          let obj = {};
          const nodeObj = this.nodeList.find(key => item.source.cell === key.id);
          obj = {
            name: nodeObj.attrs.label.text,
            id: nodeObj.id,
          };
          if (obj.name !== '开始' && obj.name !== '结束') {
            this.jobNode[item.target.cell].push(obj);
            Object.keys(this.jobNode).forEach((key) => {
              if (item.source.cell === key) {
                this.jobNode[item.target.cell].push(...this.jobNode[key]);
              }
            });
          }
        }
      });
      this.getNodeNameList();
    },
    updateEdgeName(name) {
      this.selectCell.setLabels(name);
    },
    updateNodeName(name) {
      this.selectCell.setAttrs({
        label: {
          text: name,
        },
      });
    },
    addNodeToGraph(event) {
      const target = event.currentTarget;
      const type = target.getAttribute('data-type');
      let node = null;
      if (type === 'node') {
        const shape = target.getAttribute('data-shape');
        const size = target.getAttribute('data-size');
        const width = Number(size.split('*')[0]);
        const height = Number(size.split('*')[1]);
        const label = target.getAttribute('data-label');
        const color = target.getAttribute('data-color');
        const rgbToHex = (r, g, b) => {
          // eslint-disable-next-line no-bitwise
          const hex = ((r << 16) | (g << 8) | b).toString(16);
          return `#${new Array(Math.abs(hex.length - 7)).join('0')}${hex}`;
        };

        // hex to rgb
        const hexToRgb = (hex) => {
          const rgb = [];
          for (let i = 1; i < 7; i += 2) {
            // eslint-disable-next-line radix
            rgb.push(parseInt(`0x${hex.slice(i, i + 2)}`));
          }
          return rgb;
        };

        // 计算渐变过渡色
        const gradient = (startColor, endColor, step) => {
          // 将 hex 转换为rgb
          const sColor = hexToRgb(startColor);
          const eColor = hexToRgb(endColor);

          // 计算R\G\B每一步的差值
          const rStep = (eColor[0] - sColor[0]) / step;
          const gStep = (eColor[1] - sColor[1]) / step;
          const bStep = (eColor[2] - sColor[2]) / step;

          const gradientColorArr = [];
          for (let i = 0; i < step; i += 1) {
            // 计算每一步的hex值
            gradientColorArr.push(rgbToHex(
              // eslint-disable-next-line radix
              parseInt(rStep * i + sColor[0]), parseInt(gStep * i + sColor[1]), parseInt(bStep * i + sColor[2]),
            ));
          }
          return gradientColorArr;
        };
        const colorList = gradient(color, '#ffffff', 10);
        const halfColor = colorList[9];
        const fillColor = colorList[6];
        const ports = {
          groups: {
            top: {
              position: 'top',
              attrs: {
                circle: {
                  r: 4,
                  magnet: true,
                  stroke: '#31d0c6',
                  strokeWidth: 2,
                  fill: '#fff',
                },
              },
            },
            bottom: {
              position: 'bottom',
              attrs: {
                circle: {
                  r: 4,
                  magnet: true,
                  stroke: '#31d0c6',
                  strokeWidth: 2,
                  fill: '#fff',
                },
              },
            },
            left: {
              position: 'left',
              attrs: {
                circle: {
                  r: 4,
                  magnet: true,
                  stroke: '#31d0c6',
                  strokeWidth: 2,
                  fill: '#fff',
                },
              },
            },
            right: {
              position: 'right',
              attrs: {
                circle: {
                  r: 4,
                  magnet: true,
                  stroke: '#31d0c6',
                  strokeWidth: 2,
                  fill: '#fff',
                },
              },
            },
          },
          items: [
            {
              id: 'top',
              group: 'top',
            },
            {
              id: 'bottom',
              group: 'bottom',
            },
            {
              id: 'left',
              group: 'left',
            },
            {
              id: 'right',
              group: 'right',
            },
          ],
        };
        const nodeInfo = {
          shape,
          width,
          height,
          attrs: {
            label: {
              'font-size': 12,
              text: label,
              fill: 'black',
            },
            body: {
              stroke: fillColor,
              fill: halfColor,
              strokeWidth: 2,
            },
          },
          ports,
        };
        if (shape === 'polygon') {
          nodeInfo.points = '0,10 10,0 20,10 10,20';
        }
        node = this.graph.createNode(nodeInfo);
      } else {
        node = {};
      }
      this.dnd.start(node, event);
    },
    initG6() {
      const that = this;
      this.graph = new Graph({
        container: that.$refs.processCanvas,
        autoResize: true,
        connecting: {
          snap: true, // 自动吸附连接线
          allowBlank: false, // 不允许只有一个节点的线
          // allowMulti: false, // 不允许在两个节点间创建多个线
          highlight: true, // 高亮可被连接的点
        },
        grid: true,
        history: true,
        snapline: {
          enabled: true, // 对齐线
          sharp: true,
        },
        scroller: {
          enabled: true,
          pageVisible: false,
          pageBreak: false,
          pannable: true,
        },
        // mousewheel: {
        //   enabled: true,
        //   modifiers: ['ctrl', 'meta'],
        // },
      });
      this.dnd = new Dnd({
        target: this.graph,
        scaled: false,
        animation: true,
      });
      this.graph.on('edge:connected', ({ isNew, edge }) => {
        if (isNew) {
          that.handleCellClick(edge);
        }
      });
      this.graph.on('cell:mouseenter', ({ cell }) => {
        if (this.clickCellMap[cell.id]) {
          clearTimeout(this.clickCellMap[cell.id]);
          delete this.clickCellMap[cell.id];
        }
        if (cell.isNode()) {
          let offset = { x: 10, y: 10 };
          if (cell.shape === 'polygon') {
            offset = { x: 20, y: 20 };
          }
          cell.addTools([
            {
              name: 'boundary',
              args: {
                attrs: {
                  fill: '#7c68fc',
                  stroke: '#333',
                  'stroke-width': 1,
                  'fill-opacity': 0.2,
                },
              },
            },
            {
              name: 'button-remove',
              args: {
                x: 0,
                y: 0,
                offset,
              },
            },
          ]);
        } else {
          cell.addTools(['button-remove']);
        }
      });
      this.graph.on('cell:mouseleave', ({ cell }) => {
        cell.removeTools();
      });
      this.graph.on('cell:click', ({ cell }) => {
        that.handleCellClick(cell);
      });
      this.graph.on('node:added', ({ cell }) => {
        that.handleCellClick(cell);
      });
      if (this.cells.length > 0) {
        this.graph.fromJSON({ cells: this.cells });
        this.$nextTick(() => {
          this.graph.centerContent();
        });
        this.cells = [];
      }
    },
    async saveFlow() {
      let workflowValid;
      await this.$refs.workflow.validate((valid) => {
        workflowValid = valid;
      });
      if (!workflowValid) {
        this.$message({
          type: 'warning',
          message: '请完成流程信息的配置',
        });
        return;
      }
      const data = this.graph.toJSON();
      const { cells } = data;
      const workflow = {
        name: this.workflow.name,
        product_line: this.workflow.productLine,
        description: this.workflow.description,
        created: this.workflow.created,
        icon: this.workflow.icon,
        iconColor: this.workflow.iconColor,
        created_by: this.workflow.created_by,
        tpl: deepCopy(this.workflow.tpl),
      };
      const flowchart = {};
      flowchart.workflow = deepCopy(workflow);
      flowchart.nodes = [];
      flowchart.edges = [];
      const that = this;
      const cellValid = cells.every((cell) => {
        // 线
        if (cell.shape === 'edge') {
          const { id } = cell;
          if (!that.workflow.edgeConfigs[id]) {
            const cellObj = that.graph.getCell(id);
            that.handleCellClick(cellObj);
            that.$nextTick(() => {
              that.$refs.edge.validate();
            });
            return false;
          }
          const temp = deepCopy(cell);
          temp.valueData = that.workflow.edgeConfigs[id];
          flowchart.edges.push(temp);
          return true;
        }
        const { id } = cell;
        if (!that.workflow.nodeConfigs[id]) {
          const cellObj = that.graph.getCell(id);
          that.activeTab = 'cellInfo';
          that.handleCellClick(cellObj);
          that.$nextTick(() => {
            that.$refs.node.validate();
          });
          return false;
        }
        const temp = deepCopy(cell);
        temp.valueData = that.workflow.nodeConfigs[id];
        flowchart.nodes.push(temp);
        return true;
      });
      // workflow.flowchart = flowchart;
      if (!cellValid) {
        return;
      }
      this.internalChange = true;
      this.$emit('update', flowchart);
      this.$nextTick(() => {
        this.internalChange = false;
      });
    },
  },
};
</script>

<style scoped>
.process-edit-container {
  margin-top: 20px;
  height: calc(100% - 20px);
}

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

.process-component-list {
  height: 100%;
  background-color: #e6e6e6;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-around;
  align-content: flex-start;
}
.father {
  height: calc(100%);
}
.process-box {
  width: calc(100% - 15px);
  height: 280px;
  overflow-y: auto;
  margin-left: 10px;
}
.export-box {
  height: 200px;
  margin-left: 10px;
  width: calc(100% - 15px);
}

</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542
  • 543
  • 544
  • 545
  • 546
  • 547
  • 548
  • 549
  • 550
  • 551
  • 552
  • 553
  • 554
  • 555
  • 556
  • 557
  • 558
  • 559
  • 560
  • 561
  • 562
  • 563
  • 564
  • 565
  • 566
  • 567
  • 568
  • 569
  • 570
  • 571
  • 572
  • 573
  • 574
  • 575
  • 576
  • 577
  • 578
  • 579
  • 580
  • 581
  • 582
  • 583
  • 584
  • 585
  • 586
  • 587
  • 588
  • 589
  • 590
  • 591
  • 592
  • 593
  • 594
  • 595
  • 596
  • 597
  • 598
  • 599
  • 600
  • 601
  • 602
  • 603
  • 604
  • 605
  • 606
  • 607
  • 608
  • 609
  • 610
  • 611
  • 612
  • 613
  • 614
  • 615
  • 616
  • 617
  • 618
  • 619
  • 620
  • 621
  • 622
  • 623
  • 624
  • 625
  • 626
  • 627
  • 628
  • 629
  • 630
  • 631
  • 632
  • 633
  • 634
  • 635
  • 636
  • 637
  • 638
  • 639
  • 640
  • 641
  • 642
  • 643
  • 644
  • 645
  • 646
  • 647
  • 648
  • 649
  • 650
  • 651
  • 652
  • 653
  • 654
  • 655
  • 656
  • 657
  • 658
  • 659
  • 660
  • 661
  • 662
  • 663
  • 664
  • 665
  • 666
  • 667
  • 668
  • 669
  • 670
  • 671
  • 672
  • 673
  • 674
  • 675
  • 676
  • 677
  • 678
  • 679
  • 680
  • 681
  • 682
  • 683
  • 684
  • 685
  • 686
  • 687
  • 688
  • 689
  • 690
  • 691
  • 692
  • 693
  • 694
  • 695
  • 696
  • 697
  • 698
  • 699
  • 700
  • 701
  • 702
  • 703
  • 704
  • 705
  • 706
  • 707
  • 708
  • 709
  • 710
  • 711
  • 712
  • 713
  • 714
  • 715
  • 716
  • 717
  • 718
  • 719
  • 720
  • 721
  • 722
  • 723
  • 724
  • 725
  • 726
  • 727
  • 728
  • 729
  • 730
  • 731
  • 732
  • 733
  • 734
  • 735
  • 736
  • 737
  • 738
  • 739
  • 740
  • 741
  • 742
  • 743
  • 744
  • 745
  • 746
  • 747
  • 748
  • 749
  • 750
  • 751
  • 752
  • 753
  • 754
  • 755
  • 756
  • 757
  • 758
  • 759
  • 760
  • 761
  • 762
  • 763
  • 764
  • 765
  • 766
  • 767
  • 768
  • 769
  • 770
  • 771
  • 772
  • 773
  • 774
  • 775
  • 776
  • 777
  • 778
  • 779
  • 780
  • 781
  • 782
  • 783
  • 784
  • 785
  • 786
  • 787
  • 788
  • 789
  • 790
  • 791
  • 792
  • 793
  • 794
  • 795
  • 796
  • 797
  • 798
  • 799
  • 800
  • 801
  • 802
  • 803
  • 804
  • 805
  • 806
  • 807
  • 808
  • 809
  • 810
  • 811
  • 812
  • 813
  • 814
  • 815
  • 816
  • 817
  • 818
  • 819
  • 820
  • 821
  • 822
  • 823
  • 824
  • 825
  • 826
  • 827
  • 828
  • 829
  • 830
  • 831
  • 832
  • 833
  • 834
  • 835
  • 836
  • 837
  • 838
  • 839
  • 840
  • 841
  • 842
  • 843
  • 844
  • 845
  • 846
  • 847
  • 848
  • 849
  • 850
  • 851
  • 852
  • 853
  • 854
  • 855
  • 856
  • 857
  • 858
  • 859
  • 860
  • 861
  • 862
  • 863
  • 864
  • 865
  • 866
  • 867
  • 868
  • 869
  • 870
  • 871
  • 872
  • 873
  • 874
  • 875
  • 876
  • 877
  • 878
  • 879
  • 880
  • 881
  • 882
  • 883
  • 884
  • 885
  • 886
  • 887
  • 888
  • 889
  • 890
  • 891
  • 892
  • 893
  • 894
  • 895
  • 896
  • 897
  • 898
  • 899
  • 900
  • 901
  • 902
  • 903
  • 904
  • 905
  • 906
  • 907
  • 908
  • 909
  • 910
  • 911
  • 912
  • 913
  • 914
  • 915
  • 916
  • 917
  • 918
  • 919
  • 920
  • 921
  • 922
  • 923
  • 924
  • 925
  • 926
  • 927
  • 928
  • 929
  • 930
  • 931
  • 932
  • 933
  • 934
  • 935
  • 936
  • 937
  • 938
  • 939
  • 940
  • 941
  • 942
  • 943
  • 944
  • 945
  • 946
  • 947
  • 948
  • 949
  • 950
  • 951
  • 952
  • 953
  • 954
  • 955
  • 956
  • 957
  • 958
  • 959
  • 960
  • 961
  • 962
  • 963
  • 964
  • 965
  • 966
  • 967
  • 968
  • 969
  • 970
  • 971
  • 972
  • 973
  • 974
  • 975
  • 976
  • 977
  • 978
  • 979
  • 980
  • 981
  • 982
  • 983
  • 984
  • 985
  • 986
  • 987
  • 988
  • 989
  • 990
  • 991
  • 992
  • 993
  • 994
  • 995
  • 996
  • 997
  • 998
  • 999
  • 1000
  • 1001
  • 1002
  • 1003
  • 1004
  • 1005
  • 1006
  • 1007
  • 1008
  • 1009
  • 1010
  • 1011
  • 1012
  • 1013
  • 1014
  • 1015
  • 1016
  • 1017
  • 1018
  • 1019
  • 1020
  • 1021
  • 1022
  • 1023
  • 1024
  • 1025
  • 1026
  • 1027

下面是将上面的代码作为一个公共组件使用,通过props传入可进行编辑操作

<template>
  <div>
    <span class="staff-title">{{ activeTitle }}</span>
    <process-edit
      :data="processInfo"
      :label-type="labelType"
      @update="handleSave"
    />
  </div>
</template>

<script>
//import { getRegisterTestProcess, postRegisterTestProcess } from '@/api/integration_test';
import { deepCopy } from '../../utils/util';
import ProcessEdit from './components/ProcessEdit.vue';

export default {
  name: 'IntegrationTestProcess',
  components: {
    ProcessEdit,
  },

  data: () => ({
    init: false,
    realId: null,
    processInfo: {
      name: '',
      projectId: null,
      description: '',
      icon: 'el-icon-user',
      iconColor: 'blue',
      tpl: [],
      flow_chart: {
        nodes: [],
        edges: [],
        workflow: {},
      },
    },
    activeTitle: '',
    processId: -1,
    labelType: 1,
  }),
  watch: {
    processInfo: {
      handler(val) {
        if (this.init) {
          return;
        }

        const data = deepCopy(val);
        const statusList = [];
        const transformList = [];
        const statusIDList = [];
        const transformIDList = [];
        // eslint-disable-next-line no-restricted-syntax
        for (const arrayValue of data.nodes) {
          if (statusIDList.indexOf(arrayValue.valueData.id) === -1) {
            statusIDList.push(arrayValue.valueData.id);
          } else {
            delete arrayValue.valueData.id;
          }
          arrayValue.valueData.tmpId = arrayValue.id;
          statusList.push(arrayValue.valueData);
          arrayValue.label = arrayValue.valueData.name;
        }
        // eslint-disable-next-line no-restricted-syntax
        for (const transformValue of data.edges) {
          if (transformIDList.indexOf(transformValue.valueData.id) === -1) {
            transformIDList.push(transformValue.valueData.id);
          } else {
            delete transformValue.valueData.id;
          }
          transformValue.valueData.tmpId = transformValue.id;
          transformList.push(transformValue.valueData);
        }
        const workflowValue = Object.assign({}, data.workflow);
        workflowValue.flowchart = data;
        // const jsonData = {
        //   workflow: workflowValue,
        //   status: statusList,
        //   transform: transformList,
        // };
      },
    },
  },
  created() {
    this.processId = this.$route.params.process_id;
    if (Number(this.processId) !== -1 && this.processId) {
      this.init = true;
      this.activeTitle = '编辑流程';
      this.realId = this.processId;
      this.labelType = 2;
      getRegisterTestProcess(this.processId).then((res) => {
        this.processInfo = res;
        this.$nextTick(() => {
          this.init = false;
        });
      }, (err) => {
        this.$message({
          type: 'error',
          message: err.errmsg,
        });
        console.error(err);
      });
    } else {
      this.activeTitle = '新建流程';
    }
  },
  methods: {
    handleSave(val) {
      const data = deepCopy(val);
      const statusList = [];
      const transformList = [];
      const statusIDList = [];
      const transformIDList = [];
      // eslint-disable-next-line no-restricted-syntax
      for (const arrayValue of data.nodes) {
        if (statusIDList.indexOf(arrayValue.valueData.id) === -1) {
          statusIDList.push(arrayValue.valueData.id);
        } else {
          delete arrayValue.valueData.id;
        }
        arrayValue.valueData.tmpId = arrayValue.id;
        statusList.push(arrayValue.valueData);
        arrayValue.label = arrayValue.valueData.name;
      }
      // eslint-disable-next-line no-restricted-syntax
      for (const transformValue of data.edges) {
        if (transformIDList.indexOf(transformValue.valueData.id) === -1) {
          transformIDList.push(transformValue.valueData.id);
        } else {
          delete transformValue.valueData.id;
        }
        transformValue.valueData.tmpId = transformValue.id;
        transformList.push(transformValue.valueData);
      }
      const workflowValue = Object.assign({}, data.workflow);
      workflowValue.flowchart = data;
      const jsonData = {
        workflow: workflowValue,
        status: statusList,
        transform: transformList,
      };
      const flows = [];
      jsonData.transform.forEach((item) => {
        let obj = {};
        jsonData.status.forEach((key) => {
          if (key.tmpId === item.sourceStatus) {
            obj = {
              from: key.name,
            };
          }
        });
        jsonData.status.forEach((key) => {
          if (item.destinationStatus === key.tmpId) {
            obj.to = key.name;
          }
        });
        flows.push(obj);
      });
      const nodesList = jsonData.status.map((item) => {
        const importParam = {};
        item.paramList.forEach((key) => {
          if (key.param === 0 || key.param === 1) {
            importParam[key.name] = {
              type: key.param,
              value: key.defaultValue,
              description: key.description,
            };
          } else if (key.param === 2) {
            const nodeObj = jsonData.status.find(item => item.tmpId === key.nodeName);
            importParam[key.name] = {
              type: key.param,
              value: nodeObj && nodeObj.name ? `${nodeObj.name}.${key.export}` : '',
              description: key.description,
            };
          } else if (key.param === 3) {
            importParam[key.name] = {
              type: key.param,
              value: key.defaultValue,
              description: key.description,
            };
          }
        });
        const obj = {
          name: item.name,
          description: item.description,
          type: item.type,
          component_id: item.component_id,
          import_param: importParam,
          export_param: item.exportParam,
        };
        return obj;
      });
      const nodeList = nodesList.filter(item => item.name !== '开始' && item.name !== '结束');
      const flowData = {
        name: jsonData.workflow.name,
        description: jsonData.workflow.description,
        product_line: jsonData.workflow.product_line,
        created_by: jsonData.workflow.created_by,
      };
      const resultData = {
        ...flowData,
        nodes: nodeList,
        flows,
        flow_chart: jsonData.workflow.flowchart,
      };
      if (this.realId === null) {
        postRegisterTestProcess(resultData).then((res) => {
          if (res) {
            this.$router.push({ name: 'IntegrationTestJobList' });
            this.$message.success('流程新建成功!');
          }
        }, (err) => {
          this.$message({
            type: 'error',
            message: err.errmsg,
          });
          console.error(err);
        });
      } else {
        const jsonData = {
          process_id: this.realId,
          ...resultData,
        };
        postRegisterTestProcess(jsonData).then((res) => {
          if (res) {
            this.$router.push({ name: 'IntegrationTestJobList' });
            this.$message.success('流程修改成功!');
          }
        }, (err) => {
          this.$message({
            type: 'error',
            message: err.errmsg,
          });
          console.error(err);
        });
      }
    },
  },
};
</script>

<style scoped>
.staff-title {
  display: block;
  width: 100%;
  height: 50px;
  padding: 13px 0 5px 30px;
  font-size: 16px;
  margin-top: 20px;
  border-bottom: 1px solid #ccc;
  margin-bottom: 30px;
  background-color: skyblue;
}
</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257

在这里插入图片描述
在这里插入图片描述

// 深拷贝
export function deepCopy(obj, cache = []) {
  // just return if obj is immutable value
  if (obj === null || typeof obj !== 'object') {
    return obj
  }

  // if obj is hit, it is in circular structure
  const hit = find(cache, (c) => c.original === obj)
  if (hit) {
    return hit.copy
  }

  const copy = Array.isArray(obj) ? [] : {}
  // put the copy into cache at first
  // because we want to refer it in recursive deepCopy
  cache.push({
    original: obj,
    copy
  })

  Object.keys(obj).forEach((key) => {
    copy[key] = deepCopy(obj[key], cache)
  })

  return copy
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/816661
推荐阅读
相关标签
  

闽ICP备14008679号