vue 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-buttonstyle="float: right; margin-top: -70px; margin-right: 180px"size="mini"type="primary"@click="saveFlow">保存</el-button><el-buttonstyle="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-selectv-model="workflow.productLine"clearablefilterableplaceholder="请选择产品线"size="mini"style="width: 100%":disabled="disables"@change="getJobName"><el-optionv-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"><imgdata-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"><imgdraggable="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"><imgdraggable="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"><imgdraggable="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"><imgdraggable="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"><imgdraggable="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-drawertitle="节点配置信息":visible.sync="drawer":direction="direction"><!--            <template #header>--><!--              <div class="card-header">--><!--                <span>配置信息</span>--><!--              </div>--><!--            </template>--><el-formv-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-selectv-model.number="node.type"filterableplaceholder="请选择处理人类型"size="mini"style="width: 100%"disabled@change="getJobName"><el-optionv-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-selectv-model.number="node.component_id"filterableplaceholder="请选择job"size="mini"style="width: 100%"@change="getJobParam"><el-optionv-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-selectv-model="item.param"filterableplaceholder="请选择"size="mini"style="width: 30%;"@change="selectData"><el-optionv-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-inputv-if="item.param === 0 || item.param === 3":value="String(item.defaultValue)"size="mini"style="width: 40%"disabled/><el-inputv-if="item.param === 1"v-model="item.defaultValue"size="mini"style="width: 40%"/><!--                  28%--><el-selectv-if="item.param === 2"v-model="item.nodeName"filterableplaceholder="请选择"size="mini"style="width: 32%"@change="selectJobName"><el-optionv-for="key in node.nodeViewList":key="key.id":label="key.name":value="key.id"/></el-select>&nbsp;<el-selectv-if="item.param === 2"v-model="item.export"filterableplaceholder="请选择"size="mini"style="width: 32%"><el-optionv-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-formv-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-bitwiseconst hex = ((r << 16) | (g << 8) | b).toString(16);return `#${new Array(Math.abs(hex.length - 7)).join('0')}${hex}`;};// hex to rgbconst hexToRgb = (hex) => {const rgb = [];for (let i = 1; i < 7; i += 2) {// eslint-disable-next-line radixrgb.push(parseInt(`0x${hex.slice(i, i + 2)}`));}return rgb;};// 计算渐变过渡色const gradient = (startColor, endColor, step) => {// 将 hex 转换为rgbconst 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 radixparseInt(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>

下面是将上面的代码作为一个公共组件使用,通过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-syntaxfor (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-syntaxfor (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-syntaxfor (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-syntaxfor (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>

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

// 深拷贝
export function deepCopy(obj, cache = []) {// just return if obj is immutable valueif (obj === null || typeof obj !== 'object') {return obj}// if obj is hit, it is in circular structureconst 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 deepCopycache.push({original: obj,copy})Object.keys(obj).forEach((key) => {copy[key] = deepCopy(obj[key], cache)})return copy
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部