UNPKG

w-vue-middle

Version:

统一公共服务组件

2,113 lines 63 kB
/*
 * @Author: Jason Liu
 * @Date: 2022-08-03 13:13:03
 * @Desc:
 */

const { Graph, Shape, Addon, Registry } = require('@antv/x6');
const { lineoption, controlsList } = require('../designertackle/config');

/**
 * @Author: Jason Liu
 * @description: 调度服务接口
 */
const $dispatchcenter = require('../../api/dispatchcenter');

/**
 * @Author: Jason Liu
 * @description: 数据集成服务
 */
const $dataIntegration = require('../../api/dataIntegration');

const config = require('./components/config');

//设置区域
const esOutputOptoin = require('./components/esOutputOptoin').default;
const sqlInputOptoin = require('./components/sqlInputOptoin').default;
const tableInputOptoin = require('./components/tableInputOptoin').default;
const messagesOptoin = require('./components/messagesOptoin').default;
const tableOutputOptoin = require('./components/tableOutputOptoin').default;
const tableMigrateOptoin = require('./components/tableMigrateOptoin').default;
const tableJoinOptoin = require('./components/tableJoinOptoin').default;
const kafaInputOptoin = require('./components/kafaInputOptoin').default;

const viewSqlConvert = require('./components/viewSqlConvert').default;

let runTestTime;
export default {
  name: 'jobDesigner',
  inject: ['$t'], // 暂时处理元数据引用无法识别$t问题
  components: {
    esOutputOptoin,
    sqlInputOptoin,
    tableInputOptoin,
    messagesOptoin,
    tableOutputOptoin,
    tableMigrateOptoin,
    tableJoinOptoin,
    kafaInputOptoin,
    viewSqlConvert,
  },
  props: {
    value: {
      type: Boolean,
      default: false,
    },
    processId: {
      //流程ID
      type: [String, Number],
    },
    jobType: {
      type: String,
    },
    jobGroupId: {
      type: String,
    },
  },
  data() {
    return {
      loading: false,
      allLoading: false,
      activeKey: '1',
      show: this.value,
      groupList: [], //作业分组
      parentList: [], //父作业列表
      flowGroups: [], //流程组
      setBase: true, //设置基础信息
      putawayNode: true, //收起node设置
      logList: [],
      logkeys: { log: {}, sql: {} }, //日志缓存记录
      running: false,
      clusters: [], //集群列表
      sqlFunEditor: {
        show: false,
        text: undefined,
        tables: {},
        row: {},
      },
      debugs: {
        testId: undefined,
        jobLog: [],
        jobSqls: [],
        executionIds: [],
        failedIds: [],
        finishedIds: [],
        status: undefined,
      }, //调试信息
      debuggerProcess: {
        //流程调试
        show: false,
        putaway: true,
        limit: 100,
        jobDetail: {
          steps: [],
          hops: [],
        },
      },
      activeJob: {
        id: undefined,
        data: {
          id: undefined,
          jobType: undefined,
          jobGroupId: undefined,
        },
      },
      jobExtraList: {},
      activeNode: {
        //选中的node节点
        id: undefined,
        size: { height: undefined, width: undefined },
        position: { x: undefined, y: undefined },
        shape: 'custom-input',
        data: {
          name: undefined,
          type: undefined,
          tableName: undefined,
          tableColumns: [],
          columns: [],
        },
      },
      jobs: [],
      rules: {
        jobName: [{ required: true, message: $t('请输入流程名称'), trigger: 'blur' }],
        jobGroupId: [{ required: true, message: $t('请输入选择作业组'), trigger: 'change' }],
      },
      control_str: undefined, //控件查询列表
      lastType: undefined,
      //作业的控件组
      controlsJobList: [],
      waitRemovedList: {}, //等待删除列表
      setSubJobConfig: {
        //子作业参数设置
        setSubJobConfig: false, //搜索信息
        subEdit: false,
        jobs: [], //作业列表
        transforms: [],
      },
      collectiondatas: {
        //采集数据源
        sourceLoading: false,
        dataSource: [], //数据源
        schemaLoading: false,
        schema: [], //schema列表
        dataTables: [], //数据表
        showTables: [], //显示的表格信息
        tableLoading: false,
        columnLoading: false,
        dwsAndads: {
          dbInfo: {
            schema: undefined,
            dbName: undefined,
          },
          dws: [],
          ads: [],
          showData: [],
        },
      },
      metadatas: {
        //元数据平台数据源
        sourceLoading: false,
        dataSource: [], //数据源
        schemaLoading: false,
        schema: [], //schema列表
        tableLoading: false,
        showTables: [], //显示的表格信息
        dataTables: [], //数据表
        columnLoading: false,
        dwds: {
          dws: [],
          dbInfo: {
            schema: undefined,
            dbName: undefined,
          },
          data: [],
        },
        dwsAndads: {
          dbInfo: {
            schema: undefined,
            dbName: undefined,
          },
          dws: [],
          ads: [],
          showData: [],
        },
      },
      setOutTables: {
        //输出参数设置
        setMap: false, //设置映射
        str: undefined,
        outstr: undefined,
        overlay: false,
      },
      setPerlConfig: {
        //Per参数设置
        show: false,
        config: {},
      },
      setTableJoinConfig: {
        //设置表不关联配置
        setJoin: false, //设置关联方式
        setColumns: false, //设置显示字段
      },
      zoom: undefined, //缩放比例
      integrationJobList: [], //基础作业列表
      metadataCollectEnabled: '0', //元数据平台采集开关
      sourceColumn: {
        show: false,
        tables: { columns: [] },
        column: {},
      },
      debugSummarys: [], //调试结果

      hasSqlInput: false, //是否有sql
      showSqlConvert: false, //查看sql转换
    };
  },
  created() {
    // this.getGroupList();
    // this.geiClustersList();
    // if (this.jobType == 'flow') {
    //     this.getFlowGroups();
    // } else {
    //     this.getParentList();
    // }
    this.init();
  },
  methods: {
    /**
     * @Author: Jason Liu
     * @description: 设置画布数据
     */
    setCanvas(data = { steps: [], hops: [] }, job) {
      console.log(data);
      const cells = [];
      data.steps.forEach((node) => {
        node.attrs = undefined;
        if (node.data.type == 'SqlInput') {
          this.hasSqlInput = true;
        }
        if (['TableInput', 'TableOutput'].indexOf(node.data.type) > -1) {
          //兼容代码,将老数据的内容处理
          node.data.whereString = node.data.whereString || undefined;
          node.data.sourceType = node.data.sourceType || 0;
          node.data.clusterId = node.data.clusterId || undefined;
          node.data.dictColumn = node.data.dictColumn || undefined;
          node.data.asName = node.data.asName || node.data.tableCode || 'temp';
          node.data.schemaId = node.data.schemaId || node.data.schema;
          node.data.data = undefined; //冗余数据清空
          //TODO:mapping的兼容处理
        } else if (['SubTransform'].indexOf(node.data.type) > -1) {
          node.data.sourceType = node.data.sourceType || 0;
        } else if (['TableJoin'].indexOf(node.data.type) > -1) {
          node.data.tableCode = node.data.tableCode || 'temp';
        }
        node.component = undefined;
        let cell = {
          label: node.data.name,
          ...node,
        };
        cells.push(job.graph.createNode(cell));
      });

      data.hops.forEach((edge) => {
        cells.push(
          job.graph.createEdge({
            ...lineoption,
            ...edge,
          }),
        );
      });

      job.graph.resetCells(cells);
    },
    /**
     * @Author: Jason Liu
     * @description: 初始化画布
     */
    initCanvas(
      param = {
        setBase: true,
        putawayNode: true,
      },
    ) {
      this.$nextTick(() => {
        this.jobs = this.jobs.map((job) => {
          if (!job.graph && this.$refs[job.id]) {
            //未初始化

            this.controlsJobList = []; //重置控件列表
            const graphOpetion = this.getGraphOpetion(job.id);
            job.graph = new Graph(graphOpetion);
            this.bindEvent(job);
            job.dnd = new Addon.Dnd({
              target: job.graph,
              scaled: false,
              animation: true,
            });

            if (job.data.jsonDetail) {
              try {
                let cells = JSON.parse(job.data.jsonDetail);
                this.setCanvas(cells, job);
              } catch (e) {}
            }
          }

          if (job.id == this.activeJob.id) {
            let jobs = this.jobs;
            this.activeJob = {
              id: this.activeJob.id,
              graph: job.graph,
              dnd: job.dnd,
              loading: job.loading,
              change: job.change,
              data: job.data,
              sourceStep: job.sourceStep,
            };

            this.jobExtraList = job.data.jobExtra ? JSON.parse(job.data.jobExtra) : {};
            this.setBase = param.setBase; //设置基础信息
            this.putawayNode = param.putawayNode; //收起node设置
            if (this.activeJob.graph) {
              this.zoom = this.activeJob.graph.zoom();
            }

            //对比控件栏位是否要切换
            this.lastType = `${this.activeJob.data.jobType}`;

            this.controlsJobList = controlsList.filter((item) => {
              return item.maps.indexOf(this.activeJob.data.jobType) > -1;
            });
            if (this.$refs.controlsJobList) {
              this.$refs.controlsJobList.clearTreeExpand();
            }
            this.setAllTreeExpand();
          }
          return job;
        });
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 还原设计状态
     */
    reduction() {
      this.setBase = true;
      this.putawayNode = true;
    },
    /**
     * @Author: Jason Liu
     * @description: 对内容发生修改
     */
    changeEndJob() {
      this.jobs = this.jobs.map((job) => {
        if (job.id == this.activeJob.id) {
          job.change = true;
        }
        return job;
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 绑定事件
     */
    bindEvent(_this) {
      _this.graph.on('blank:click', ({ e, x, y }) => {
        //("blank:click", e);
        this.reduction();
      });

      _this.graph.on('cell:click', ({ e, x, y, cell, view }) => {
        this.reduction();
        cell.removeTools();
      });

      _this.graph.on('node:click', ({ e, x, y, node, view }) => {
        if (this.loading) {
          return false;
        }
        this.putawayNode = false;
        let tempNode = node.toJSON();
        this.activeNode = tempNode;
        //获取选中控件的选择数据
        //TODO:废除
        this.getSelectData();
      });
      _this.graph.on('node:dblclick', ({ e, x, y, node, view }) => {
        console.log('node:dblclick');
        if (this.loading) {
          return false;
        }
        let tempNode = node.toJSON();
        this.activeNode = tempNode;
        // 双击展开

        if (tempNode.data.type == 'SubJob' || tempNode.data.type == 'SubTransform') {
          if (tempNode.data.jobId) {
            //存在ID进入编辑状态
            this.setSubJob(tempNode.data.jobId, node);
          } else {
            //没有ID,进入新增状态
            this.getJobDetail(undefined, tempNode.data.type.toLocaleLowerCase(), node);
          }
        }
        // 关闭调试窗口
        this.clearProcessTest();
      });

      // 控制连接桩显示/隐藏
      const showPorts = (ports, show) => {
        for (let i = 0, len = ports.length; i < len; i = i + 1) {
          ports[i].style.visibility = show ? 'visible' : 'hidden';
        }
      };
      _this.graph.on('node:mouseenter', () => {
        const container = this.$refs[_this.id][0];
        const ports = container.querySelectorAll('.x6-port-body');
        showPorts(ports, true);
      });
      _this.graph.on('node:mouseleave', () => {
        const container = this.$refs[_this.id][0];
        const ports = container.querySelectorAll('.x6-port-body');
        showPorts(ports, false);
      });

      _this.graph.on('node:moved', ({ node, index, options }) => {
        //节点发生变化
        if (node.id == this.activeNode.id) {
          this.activeNode = node.toJSON();
        }
      });
      _this.graph.on('node:resized', ({ node, index, options }) => {
        //节点发生变化
        if (node.id == this.activeNode.id) {
          this.activeNode = node.toJSON();
        }
      });

      _this.graph.on('node:removed', ({ node, index, options }) => {
        //节点被删除
        this.changeEndJob();
        this.reduction();
      });

      _this.graph.on('node:added', ({ node, index, options }) => {
        //创建
        this.changeEndJob();
        let now = new Date();
        //更新数据的name
        node.updateData({
          id: node.id,
          code: `${node.data.type}_${$storage.userInfo.userId}_${now.toJSON()}`,
        });
        this.setBase = true;
        this.putawayNode = false;
        this.activeNode = node.toJSON();
        if (node.data.type == 'SqlInput') {
          this.hasSqlInput = true;
        }
        this.getSelectData();
        //this.reduction();
      });

      _this.graph.on('cell:mouseenter', ({ cell }) => {
        let allCell = _this.graph.getCells();
        allCell.forEach((_cell) => {
          _cell.removeTools();
        });
        if (cell.isNode()) {
          cell.addTools([
            {
              name: 'button-remove',
              args: { x: 0, y: 0, offset: { x: 8, y: 8 } },
            },
          ]);
        } else {
          cell.addTools([
            {
              name: 'button-remove',
              args: {
                x: 0,
                y: 0,
                offset: { x: 2, y: 2 },
              },
            },
          ]);
          cell.addTools(
            ['vertices', 'source-arrowhead', 'target-arrowhead'].map((name) => {
              return {
                name: name,
                args: { attrs: { fill: '#FF8C00' } },
              };
            }),
          );
        }
      });

      _this.graph.on('cell:mouseleave', ({ cell }) => {
        // if (cell.isNode()) {
        //     cell.removeTools();
        // } else {
        //     setTimeout(() => {
        //         cell.removeTools();
        //     }, 3000);
        // }
      });
      _this.graph.on('node:change:data', ({ node }) => {
        const edges = _this.graph.getIncomingEdges(node);
        const { status } = node.getData();
        if (edges) {
          edges.forEach((edge) => {
            if (status === 'running') {
              edge.attr('line/strokeDasharray', 5);
              edge.attr('line/style/animation', 'running-line 30s infinite linear');
            } else {
              edge.attr('line/strokeDasharray', '');
              edge.attr('line/style/animation', '');
            }
          });
        }
      });

      this.bindDocumentEvent(_this);
      this.bindEdgeEvent(_this);
    },

    /**
     * @Author: Jason Liu
     * @description: 绑定页面事件
     */
    bindDocumentEvent(_this) {
      // 快捷键与事件
      // copy cut paste
      _this.graph.bindKey(['meta+c', 'ctrl+c'], () => {
        const cells = _this.graph.getSelectedCells();
        if (cells.length) {
          _this.graph.copy(cells);
        }
        return false;
      });
      _this.graph.bindKey(['meta+x', 'ctrl+x'], () => {
        const cells = _this.graph.getSelectedCells();
        if (cells.length) {
          _this.graph.cut(cells);
        }
        return false;
      });
      _this.graph.bindKey(['meta+v', 'ctrl+v'], () => {
        if (!_this.graph.isClipboardEmpty()) {
          const cells = _this.graph.paste({ offset: 32 });
          _this.graph.cleanSelection();
          _this.graph.select(cells);
        }
        return false;
      });

      //undo redo
      _this.graph.bindKey(['meta+z', 'ctrl+z'], () => {
        if (_this.graph.history.canUndo()) {
          _this.graph.history.undo();
        }
        return false;
      });
      _this.graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => {
        if (_this.graph.history.canRedo()) {
          _this.graph.history.redo();
        }
        return false;
      });

      // select all
      _this.graph.bindKey(['meta+a', 'ctrl+a'], () => {
        const nodes = _this.graph.getNodes();
        if (nodes) {
          _this.graph.select(nodes);
        }
      });

      //delete
      _this.graph.bindKey('backspace', () => {
        const cells = _this.graph.getSelectedCells();
        if (cells.length) {
          _this.graph.removeCells(cells);
        }
      });

      // zoom
      _this.graph.bindKey(['ctrl+1', 'meta+1'], () => {
        this.zoom = _this.graph.zoom();
        if (this.zoom < 1.5) {
          _this.graph.zoom(0.1);
        }
      });
      _this.graph.bindKey(['ctrl+2', 'meta+2'], () => {
        this.zoom = _this.graph.zoom();
        if (this.zoom > 0.5) {
          _this.graph.zoom(-0.1);
        }
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 绑定连线事件
     */
    bindEdgeEvent(_this) {
      const connected = (edge) => {
        let line = edge.toJSON();
        if (line.source.cell == line.target.cell) {
          this.$message.error($t('同一个组件不能及时连线的开始组件又是结束组件,连线将被移除。'));
          edge.remove();
        } else {
        }
      };

      _this.graph.on('edge:removed', ({ isNew, edge }) => {
        //删除线条事件
        let line = edge.toJSON();
        this.isSet = false;
        this.changeEndJob();
        this.reduction();
      });
      _this.graph.on('edge:click', ({ e, x, y, edge, view }) => {
        //console.log("edge:click", e);
        this.isSet = false;
      });

      _this.graph.on('edge:connected', ({ isNew, edge }) => {
        // 线条链接完成
        connected(edge);
      });

      _this.graph.on('edge:change:source', ({ edge, previous, options }) => {
        if (previous.cell) {
          edge.updateData({
            source: previous,
          });
        }
        let line = edge.toJSON();
        if (options.propertyPath == 'source') {
          //数据被还原了
          connected(edge);
        } else if (line.data && line.data.source && line.data.source.cell != line.source.cell) {
          let changeNodes = {
            source: _this.graph.getCellById(line.data.source.cell), //来源的数据
            target: _this.graph.getCellById(line.target.cell), //目标的数据
          };
          if (changeNodes.source) {
            //修改节点的内容
            let changeNodesData = {
              source: changeNodes.source.toJSON(),
              target: changeNodes.target.toJSON(),
            };
          }
          edge.updateData({
            source: line.source,
          });
        }
      });
      _this.graph.on('edge:change:target', ({ edge, previous, options }) => {
        if (previous.cell) {
          edge.updateData({
            target: previous,
          });
        }
        let line = edge.toJSON();
        if (
          line.data &&
          line.data.target.cell != line.source.cell &&
          line.data.target.cell != line.target.cell
        ) {
          if (options.propertyPath == 'target') {
            //数据被还原了
            connected(edge);
          } else if (line.data && line.data.source.cell != line.source.cell) {
            let changeNodes = {
              source: _this.graph.getCellById(line.source.cell), //来源的数据
              target: _this.graph.getCellById(line.data.target.cell), //目标的数据
            };
            if (changeNodes.source) {
              //修改节点的内容
              let changeNodesData = {
                source: changeNodes.source.toJSON(),
                target: changeNodes.target.toJSON(),
              };
            }
            edge.updateData({
              source: line.source,
            });
          }
          edge.updateData({
            target: line.target,
          });
        }
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 更新选中的节点
     */
    updataNode(isAll) {
      if (this.activeNode.id) {
        const node = this.activeJob.graph.getCellById(this.activeNode.id);
        if (isAll) {
          node.setProp({
            ...this.activeNode,
          });
        }
        if (node) {
          node.updateData({
            ...this.activeNode.data,
          });
        }
      }
    },

    /**
     * @Author: Jason Liu
     * @description: 获取选中控件的数据内容
     */
    getSelectData() {
      switch (
        this.activeNode.data.type //遍历控件类型
      ) {
        case 'SubJob': //子任务,获取任务列表
        case 'SubTransform':
          this.getJobList();
          break;
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 修改作业列表
     */
    // changeSubJobList(jobId) {
    //   if (jobId) {
    //     this.getJobList();
    //     this.activeNode.data.jobId = jobId;
    //   }
    //   if (this.activeNode.data.jobId) {
    //     $dataIntegration
    //       .getJobDetail({ id: this.activeNode.data.jobId })
    //       .then((req) => {
    //         this.activeNode.data.jobName = req.data.jobName;
    //         this.activeNode.data.jobType = req.data.jobType;
    //         let jobConfig = JSON.parse(req.data.jsonDetail);
    //         this.activeNode.data.steps = jobConfig.steps.map((item) => {
    //           return {
    //             data: {
    //               type: item.data.type,
    //               name: item.data.type,
    //             },
    //           };
    //         });
    //       })
    //       .finally(() => {
    //         this.updataNode();
    //       });
    //   }
    // },
    /**
     * @Author: Jason Liu
     * @description: 修改作业列表
     */
    // changeSubJobList() {
    //   if (this.activeNode.data.jobId) {
    //     $dataIntegration
    //       .getJobDetail({ id: this.activeNode.data.jobId })
    //       .then((req) => {
    //         if (req.data) {
    //           this.activeNode.data.jobName = req.data.jobName;
    //           this.activeNode.data.jobType = req.data.jobType;
    //           let jobConfig = JSON.parse(req.data.jsonDetail);
    //           this.activeNode.data.steps = jobConfig.steps.map((item) => {
    //             return {
    //               data: {
    //                 type: item.data.type,
    //                 name: item.data.name,
    //               },
    //             };
    //           });
    //         } else {
    //           this.$message.error($t('该设计已被删除'));
    //         }
    //       })
    //       .finally(() => {
    //         this.updataNode();
    //       });
    //   }
    // },
    filterOption(input, option) {
      return (
        option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
      );
    },
    /**
     * @Author: Jason Liu
     * @description: 添加流程
     */
    addProcess(e) {
      this.getJobDetail(undefined, e.key);
    },
    getGraphOpetion(id) {
      return {
        container: this.$refs[id][0], //容器对象
        grid: true, //
        autoResize: true, //是否允许更新容器大小
        history: true,
        height: '100%',
        width: '100%',
        panning: {
          //支持水平平移
          enabled: true,
          eventTypes: ['leftMouseDown', 'rightMouseDown', 'mouseWheel'],
        },
        mousewheel: {
          //允许缩放
          enabled: true, //启动
          zoomAtMousePosition: true,
          modifiers: 'ctrl',
          minScale: 0.5,
          maxScale: 3,
          /*
                                公开API
                                graph.zoom() // 获取缩放级别
                                graph.zoom(0.2) // 在原来缩放级别上增加 0.2
                                graph.zoom(-0.2) // 在原来缩放级别上减少 0.2
                              */
        },
        connecting: {
          //连线规则
          router: {
            name: 'manhattan',
            args: { padding: 1 },
          },
          connector: {
            name: 'rounded',
            args: { radius: 8 },
          },
          anchor: 'center',
          connectionPoint: 'anchor', //指定连接点
          allowBlank: false, //是否允许连接到画布空白位置的点
          snap: { radius: 20 }, //自动吸附
          createEdge() {
            //连接的过程中创建新的边
            return new Shape.Edge(lineoption);
          },
          validateConnection({ targetMagnet }) {
            //在移动边的时候判断连接是否有效
            return !!targetMagnet;
          },
        },
        highlighting: {
          //选项来指定触发某种交互时的高亮样式
          magnetAdsorbed: {
            //连线过程中,自动吸附到链接桩
            name: 'stroke',
            args: {
              attrs: {
                fill: '#5F95FF',
                stroke: '#5F95FF',
              },
            },
          },
        },
        resizing: true, //缩放节点
        rotating: false, //旋转节点
        selecting: {
          enabled: true,
          rubberband: true,
          showNodeSelectionBox: true,
        },
        minimap: {
          enabled: true,
        },
        snapline: true, //对齐线是移动节点排版的辅助工具
        keyboard: true, //键盘快捷键
        clipboard: true, //剪切板
      };
    },
    /**
     * @Author: Jason Liu
     * @description: 获取分组列表
     */
    getGroupList() {
      $dataIntegration
        .getJobGroupList({
          queryParams: {
            F_isDel_eq: 0,
            F_id_eq: this.jobGroupId,
          },
        })
        .then((req) => {
          this.groupList = req.data;
        })
        .finally(() => {});
    },
    getParentList() {
      $dataIntegration
        .getJobList({
          pageNum: 1,
          pageSize: 1000000,
          queryParams: {
            F_isDel_eq: 0,
            F_jobType_eq: 'job',
            F_parentId_isEmpty: null,
          },
        })
        .then((req) => {
          this.parentList = req.data.map((item) => {
            return {
              value: item.id,
              label: item.jobName,
            };
          });
        })
        .catch(() => {});
    },
    /**
     * @Author: Jason Liu
     * @description: 获取流程组信息
     */
    getFlowGroups() {
      $dispatchcenter
        .getCategoryList({
          pageNum: 1,
          pageSize: 10000,
          queryParams: {
            F_isDel_eq: 0,
          },
        })
        .then((req) => {
          this.flowGroups = req.data.map((row) => {
            return {
              value: row.id,
              label: row.flowGroupName,
            };
          });
        })
        .finally(() => {});
    },
    /**
     * @Author: Jason Liu
     * @description: 设置子任务
     */
    setSubJob(id, node) {
      let job = this.jobs.find((item) => {
        return item.id == id;
      });
      this.reduction();
      if (job) {
        this.activeJob.id = id;
        this.initCanvas();
      } else {
        this.getJobDetail(id, this.activeJob.data.jobType, node);
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 获取job详情
     */
    getJobDetail(processId, jobType, sourceStep) {
      if (processId) {
        this.loading = true;
        switch (jobType) {
          case 'flow':
            $dispatchcenter
              .getFlowInfo({ id: processId })
              .then((req) => {
                let job = {
                  createBy: undefined,
                  createTime: undefined,
                  id: req.data.id,
                  isDel: 0,
                  isEnable: 0,
                  jobType: jobType,
                  jobDesc: req.data.flowDesc,
                  jobGroupId: req.data.workflowGroup.id,
                  jobName: req.data.flowName,
                  jsonDetail: req.data.flowContent,
                  parentId: req.data.parentId,
                  remark: undefined,
                  updateBy: undefined,
                  updateTime: undefined,
                };
                if (job) {
                  this.activeJob.id = processId;
                  this.jobs.push({
                    id: processId,
                    graph: undefined, //画布
                    loading: false,
                    dnd: undefined, //插画
                    change: false,
                    data: job,
                  });
                  this.initCanvas();
                } else {
                  this.$message.error($t('该设计已被删除'));
                }
              })
              .finally(() => {
                this.loading = false;
              });
            break;
          default:
            $dataIntegration
              .getJobDetail({ id: processId })
              .then((req) => {
                let job = req.data;
                if (job) {
                  this.activeJob.id = processId;
                  this.jobs.push({
                    id: processId,
                    graph: undefined, //画布
                    loading: false,
                    dnd: undefined, //插画
                    change: false,
                    data: job,
                    sourceStep: sourceStep,
                  });
                  this.initCanvas();
                } else {
                  this.$message.error($t('该设计已被删除'));
                }
              })
              .finally(() => {
                this.loading = false;
              });
            break;
        }
      } else {
        let guid = `new_` + new Date().getTime();
        let type = jobType || 'job';
        let parentId = undefined;
        let jobGroupId = this.jobGroupId;
        switch (jobType) {
          case 'subtransform':
            type = 'transform';
            jobGroupId = this.activeJob.data.jobGroupId;
            parentId = this.activeJob.data.id;
            break;
          case 'subjob':
            type = 'job';
            parentId = this.activeJob.data.id;
            jobGroupId = this.activeJob.data.jobGroupId;
            break;
        }

        if (
          (jobType == 'subtransform' || jobType == 'subjob') &&
          parentId &&
          parentId.indexOf('new') > -1
        ) {
          //子数据无父级ID
          this.$message.warning({
            content: $t('请保存好主作业后再做添加操作'),
            key: 'subadd',
          });
        } else {
          let job = {
            createBy: undefined,
            createTime: undefined,
            id: guid,
            isDel: 0,
            isEnable: 0,
            jobType: type,
            parentId: parentId,
            jobDesc: undefined,
            jobGroupId: jobGroupId,
            jobName: undefined,
            jsonDetail: undefined,
            remark: undefined,
            updateBy: undefined,
            updateTime: undefined,
          };
          this.jobs.push({
            id: guid,
            graph: undefined, //画布
            loading: false,
            dnd: undefined, //插画
            change: true,
            data: job,
            sourceStep: sourceStep,
          });
          this.activeJob.id = guid;
          this.initCanvas();
        }
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 获取集群列表
     */
    geiClustersList() {
      $dataIntegration
        .getClusterManager({
          pageNum: 1,
          pageSize: 10000,
          queryParams: {
            F_isDel_eq: 0,
          },
        })
        .then((req) => {
          this.clusters = req.data.map((item) => {
            return {
              value: item.clusterId,
              label: item.name,
            };
          });
        });
    },
    /**
     * @Author: Jason Liu
     * @description: 启动流程调试
     */
    runProcessTest() {
      //this.logList = [];
      let clusterId = undefined;
      this.$refs.setBody.$el.style.height = 'calc(100% - 220px)';
      if (this.clusters.length > 0) {
        clusterId = this.clusters[0].value;
      }
      this.debuggerProcess = {
        //流程调试
        show: true,
        putaway: false,
        limit: 100,
        clusterId: clusterId,
        jobDetail: this.getConfigureData(this.activeJob),
      };
      this.debugSummarys = [];
      this.runTest();
    },
    /**
     * @Author: Jason Liu
     * @description: 关闭调试
     */
    clearProcessTest() {
      this.$refs.setBody.$el.style.height = '100%';
      this.debuggerProcess = {
        //流程调试
        show: false,
        putaway: true,
        limit: 100,
        jobDetail: this.getConfigureData(this.activeJob),
      };

      this.reductionTest();
    },

    /**
     * @Author: Jason Liu
     * @description: 启动测试执行
     */
    runLoading(level = 1) {
      let _this = this.activeJob;
      this.debuggerProcess.jobDetail.steps.forEach((node) => {
        let source = false;
        let target = false;
        this.debuggerProcess.jobDetail.hops.forEach((hop) => {
          if (hop.target.cell == node.id) {
            target = true;
          }
          if (hop.source.cell == node.id) {
            source = true;
          }
        });
        if (source && !target) {
          let coll = _this.graph.getCellById(node.id);
          if (coll.getData().status == 'default') {
            coll.updateData({
              ...node,
              status: 'running',
            });
          }
        }
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 还原测试数据
     */
    reductionTest() {
      this.running = false;
      clearTimeout(runTestTime);
      if (this.debuggerProcess.jobDetail && this.debuggerProcess.jobDetail.steps) {
        this.debuggerProcess.jobDetail.steps.forEach((node) => {
          node.data.status = 'default';
        });
        this.logList = [];
        this.debugSummarys = [];
        this.setCanvas(this.debuggerProcess.jobDetail, this.activeJob);
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 执行测试
     */
    runTest() {
      this.reductionTest();

      this.runLoading();

      this.logList.push({
        time: new Date(),
        message: $t('开始调试,发送调试请求'),
        type: 'start',
      });
      this.logkeys = { log: {}, sql: {} }; //重置历史记录
      let query = {
        id: this.activeJob.data.id,
        jobType: this.activeJob.data.jobType,
        jsonDetail: JSON.stringify(this.debuggerProcess.jobDetail),
        limit: this.debuggerProcess.limit,
        clusterId: this.debuggerProcess.clusterId,
      };
      this.running = true;
      $dataIntegration
        .runJobTest(query)
        .then((req) => {
          this.debugs = req.data;
          this.logList.push({
            time: new Date(),
            type: this.debugs.status,
            message: $t('系统已接受调试请求,监控状态中'),
          });

          this.getTestResult();
        })
        .catch((eorr) => {
          console.log(eorr);
          this.running = false;
          this.logList.push({
            time: new Date(),
            type: 'eorr',
            message: $t('系统异常,测试失败'),
          });
        });
    },
    /**
     * @Author: Jason Liu
     * @description: 获取测试的内容情况
     */
    getTestResult() {
      let _this = this.activeJob;
      if (this.debugs.jobSqls) {
        let log = this.debugs.jobSqls;
        for (let key in log) {
          if (log[key] && !this.logkeys.sql[key]) {
            this.logkeys.sql[key] = true;
            this.logList.push({
              time: new Date(),
              type: 'message',
              message: `${log[key]}`,
            });
          }
        }
      }
      this.debugs.jobLog.forEach((log) => {
        if (log) {
          for (let key in log) {
            if (log[key] && !this.logkeys.log[key]) {
              this.logkeys.log[key] = true;
              this.logList.push({
                time: new Date(),
                type: 'message',
                message: `${log[key]}`,
              });
            }
          }
        }
      });

      /**
       * @Author: Jason Liu
       * @description: 执行日志解析
       */
      if (this.debugs.delegate && this.debugs.delegate.jobLog2) {
        this.debugs.delegate.jobLog2.forEach((log) => {
          if (log) {
            for (let key in log) {
              if (log[key] && log[key].logMsg && !this.logkeys.log[key]) {
                this.logkeys.log[key] = true;
                this.logList.push({
                  time: new Date(),
                  type: log[key].error ? 'error' : 'message',
                  message: `${log[key].logMsg}`,
                });
              }
            }
          }
        });
      }

      /**
       * @Author: Jason Liu
       * @description: 执行日志解析
       */
      this.debugs.jobLog2.forEach((log) => {
        if (log) {
          for (let key in log) {
            if (log[key] && log[key].logMsg && !this.logkeys.log[key]) {
              this.logkeys.log[key] = true;
              this.logList.push({
                time: new Date(),
                type: log[key].error ? 'error' : 'message',
                message: `${log[key].logMsg}`,
              });
            }
          }
        }
      });

      this.debugs.executionIds.forEach((ele) => {
        //执行中
        let node = this.debuggerProcess.jobDetail.steps.find((item) => {
          return item.id == ele;
        });
        if (node) {
          let coll = _this.graph.getCellById(node.id);
          coll.updateData({
            ...node,
            status: 'running',
          });
          this.logList.push({
            time: new Date(),
            type: 'processing',
            item: node.data,
            message: $t('[{slot1}]执行调试中...', { slot1: node.data.name }),
          });
        }
      });

      this.debugs.finishedIds.forEach((ele) => {
        //已完成
        let node = this.debuggerProcess.jobDetail.steps.find((item) => {
          return item.id == ele;
        });
        if (node) {
          let coll = _this.graph.getCellById(node.id);
          coll.updateData({
            ...node,
            status: 'success',
          });
          this.logList.push({
            time: new Date(),
            type: 'processing',
            item: node.data,
            message: $t('[{slot1}]执行完成', { slot1: node.data.name }),
          });
        }
      });

      this.debugs.failedIds.forEach((ele) => {
        //执行失败
        let node = this.debuggerProcess.jobDetail.steps.find((item) => {
          return item.id == ele;
        });
        if (node) {
          let coll = _this.graph.getCellById(node.id);
          coll.updateData({
            ...node,
            status: 'failed',
          });
          this.logList.push({
            time: new Date(),
            type: 'processing',
            item: node,
            message: $t('[{slot1}]执行失败', { slot1: node.data.name }),
          });
        }
      });
      switch (this.debugs.status) {
        case 'RUNNING': //启动中
          if (this.debugs.jobLog.length == 0) {
            this.logList.push({
              time: new Date(),
              type: this.debugs.status,
              message: $t('执行中...'),
            });
          }
          runTestTime = setTimeout(() => {
            $dataIntegration.getJobTestResult(this.debugs).then((res) => {
              this.debugs = res.data;
              if (res.data.debugSummary) {
                this.debugSummarys = res.data.debugSummary.filter((item) => {
                  return !!item;
                });
              }
              this.runLoading(2);
              this.getTestResult();
            });
          }, 10000);
          break;
        case 'SUSPENDED':
          this.logList.push({
            time: new Date(),
            type: this.debugs.status,
            message: $t('当前配置未能启动'),
          });
          this.running = false;
          clearTimeout(runTestTime);
          break;
        default:
          this.running = false;
          this.debuggerProcess.jobDetail.steps.forEach((node) => {
            let coll = _this.graph.getCellById(node.id);
            if (coll.getData().status == 'running') {
              coll.updateData({
                ...node,
                status: 'default',
              });
            }
          });
          this.logList.push({
            time: new Date(),
            type: this.debugs.status,
            message: $t('调试完毕,最终给结果{slot1}', {
              slot1: this.debugs.status == 'FINISHED' ? $t('【成功】') : $t('【失败】'),
            }),
          });
          clearTimeout(runTestTime);
          break;
      }

      //this.setCanvas(this.debuggerProcess.jobDetail, this.activeJob);
    },
    /**
     * @Author: Jason Liu
     * @description: 获取配置的内容
     */
    getConfigureData(job) {
      if (job.graph) {
        return {
          ver: '2.01',
          //节点内容
          steps: job.graph.getNodes().map((node) => {
            let info = node.toJSON();
            info.component = undefined;
            info.ports.groups = undefined;
            return info;
          }),
          //连线关系
          hops: job.graph.getEdges().map((edge) => {
            let info = edge.toJSON();
            return info;
          }),
        };
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 获取选中的job对象
     */
    getActiveJob() {
      return this.jobs.find((job) => {
        return job.id == this.activeJob.id;
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 保存选中
     */
    saveThis() {
      this.$refs.baseForm.validate((valid) => {
        if (valid) {
          this.loading = true;
          this.reduction();
          this.submit(this.getActiveJob()).finally(() => {
            this.loading = false;
          });
        } else {
          this.setBase = false;
          this.putawayNode = true;
          return false;
        }
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 保存全部
     */
    saveAll() {
      let pass = true;
      let callId = undefined;
      const steps = this.jobs.map((job) => {
        if (!job.data.jobName || !job.data.jobGroupId) {
          pass = false;
          callId = `${job.id}`;
        }
        return () => {
          return this.submit(job);
        };
      });
      if (pass) {
        this.allLoading = true;
        this.reduction();
        Promise.all(
          steps.map((step) => {
            return step.call();
          }),
        )
          .then((req) => {})
          .finally(() => {
            this.allLoading = false;
          });
      } else {
        this.activeJob.id = callId;
        this.initCanvas({
          setBase: false,
          putawayNode: true,
        });
        setTimeout(() => {
          this.$refs.baseForm.validate();
        }, 300);
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 提交数据
     */
    submit(job) {
      let param = this.getConfigureData(job);
      job.change = true;
      job.loading = true;
      if (job.data.id.indexOf('new') > -1) {
        job.data.id = undefined;
      }

      if (job.data.jobType == 'flow') {
        let flow = {
          flowDesc: job.data.jobDesc,
          flowName: job.data.jobName,
          id: job.data.id,
          isDel: 0,
          isEnable: 0,
          workflowGroup: { id: job.data.jobGroupId },
          flowContent: JSON.stringify(param),
        };
        return $dispatchcenter
          .saveFlowInfo(flow)
          .then((req) => {
            this.$message.success({ content: $t('流程设置成功!'), key: 'save' });
            if (!job.data.id) {
              job.data.id = req.data.id;
            }
            return req;
          })
          .finally(() => {
            job.change = false;
            job.loading = false;
          });
      } else {
        job.data.jsonDetail = JSON.stringify(param);
        job.data.jobExtra = JSON.stringify(this.jobExtraList);
        return $dataIntegration
          .saveJob(job.data)
          .then((req) => {
            this.$message.success({
              content: $t('配置保存成功!'),
              key: 'save',
            });
            //this.show = false;

            if (!job.data.id) {
              job.data.id = req.data.id;
            }
            if (this.activeJob.sourceStep) {
              this.jobs.forEach((job) => {
                const sourceStep = job.graph.getCellById(this.activeJob.sourceStep.id);
                if (sourceStep) {
                  sourceStep.updateData({
                    jobId: req.data.id,
                    name: req.data.jobName,
                  });
                }
              });
            }

            return req;
            //this.$emit("update", req.data.id);
          })
          .finally(() => {
            job.change = false;
            job.loading = false;
          });
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 开始拖动事件
     */
    startDrag(e) {
      if (this.debuggerProcess.show) {
        this.$message.warning({
          content: $t('调试状态,不可添加组件'),
          key: 'startDrag',
        });
        return;
      }
      let job = this.activeJob;

      let target = e.target.dataset;
      let info = undefined;
      const getDrag = (list) => {
        list.forEach((item) => {
          if (item.children && item.children.length > 0) {
            getDrag(item.children);
          } else if (item.id == target.id) {
            info = item;
          }
        });
      };
      getDrag(this.controlsJobList);

      if (info) {
        let node = {};
        switch (target.type) {
          case 'SubJob':
          case 'SubTransform':
          case 'IntegrationJob':
            node = {
              shape: 'custom-input',
              label: info.name,
              data: {
                id: undefined,
                name: info.name,
                code: undefined,
                type: info.type, //组件类型
                jobId: info.id == target.type ? undefined : info.id, //子任务ID
                jobName: info.id == target.type ? undefined : info.name, //子任务名称
                clusterId: undefined, //集群ID
                timeout: 1, //超时时间
                timeoutUnit: 'h', //超时类型 秒:s 分:m 时:h
                steps: [], //子任务相关节点概览信息
                hops: [], //子任务连线概览
                schema: 'public',
                lookUp: false,
                sourceType: 0, //数据来源 0:子集  1:公共
                description: undefined,
              },
            };

            break;
          case 'Start':
          case 'End':
            node = {
              shape: 'custom-rect',
              label: info.name,
              data: {
                id: undefined,
                name: info.name,
                code: undefined,
                type: info.type, //组件类型
                description: undefined,
              },
            };
            break;
          default:
            node = {
              shape: 'custom-input',
              label: info.name,
              data: info,
            };
            break;
        }

        job.dnd.start(job.graph.createNode(node), e);
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 展开树
     */
    setAllTreeExpand() {
      setTimeout(() => {
        this.$nextTick(() => {
          //安全数据处理
          if (this.$refs.controlsJobList) {
            this.$refs.controlsJobList.setAllTreeExpand(true);
          }
        });
      }, 300);
    },
    /**
     * @Author: Jason Liu
     * @description: 加载子数据内容
     */
    loadToolChildrenMethod({ row }) {
      return new Promise((resolve) => {
        switch (row.key) {
          case 'basic':
            resolve(config.basic);
            break;
          case 'conversioncomponent':
            resolve(config.conversioncomponent);
            break;
          case 'inputcomponent':
            resolve(config.inputcomponent);
            break;
          case 'outputcomponent':
            resolve(config.outputcomponent);
            break;
          case 'flow':
            $dispatchcenter
              .getJobInfo({
                pageNum: 1,
                pageSize: 1000000,
                queryParams: {
                  F_isDel_eq: 0,
                  F_jobType_eq: 'transfer',
                  F_scheduleType_eq: 'CRON',
                },
              })
              .then((req) => {
                const childs = req.data.map((item) => {
                  item.id = item.jobInfoId;
                  item.name = item.jobDesc;
                  item.type = 'IntegrationJob';
                  return item;
                });
                // if (childs.length == 0) {
                //     row.hasChild = false;
                // }
                this.integrationJobList = childs;
                resolve(childs);
              });
            break;
          default:
            let parentId = this.activeJob.id;
            if (parentId.indexOf('new') > -1 || this.activeJob.data.jobType == 'flow') {
              parentId = undefined;
              resolve([]);
            } else {
              $dataIntegration
                .getJobList({
                  pageNum: 1,
                  pageSize: 1000000,
                  queryParams: {
                    F_isDel_eq: 0,
                    F_jobType_eq: row.id,
                    F_parentId_eq: parentId,
                  },
                })
                .then((req) => {
                  const childs = req.data.map((item) => {
                    item.name = item.jobName;
                    item.type = row.type == 'job' ? 'SubJob' : 'SubTransform';
                    return item;
                  });
                  // if (childs.length == 0) {
                  //     row.hasChild = false;
                  // }
                  resolve(childs);
                })
                .catch(() => {
                  //row.hasChild = false;
                  resolve([]);
                });
              break;
            }
        }
      }).finally(() => {
        this.setAllTreeExpand();
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 修改node的关联数据
     */
    changeNodesDssociate(node, changeNodes) {},
    /**
     * @Author: Jason Liu
     * @description: 删除TableJoin的关联节点
     */
    removeTableJoinNode(node, changeNodes) {},
    /**
     * @Author: Jason Liu
     * @description: 获取下一层节点
     */
    getNextNodes({ id }) {
      let nextNodes = [];
      this.activeJob.graph.getEdges().forEach((edge) => {
        let line = edge.toJSON();
        if (line.source.cell == id) {
          nextNodes.push(this.activeJob.graph.getCellById(line.target.cell));
        }
      });
      return nextNodes;
    },
    /**
     * @Author: Jason Liu
     * @description: 获取job列表
     */
    getJobList() {
      let parentId = this.activeJob.id;
      if (parentId.indexOf('new') > -1 || this.activeJob.data.jobType == 'flow') {
        parentId = undefined;
        this.setSubJobConfig = {
          //子作业参数设置
          setSubJobConfig: false, //搜索信息
          subEdit: false,
          jobs: [], //作业列表
          transforms: [],
        };
      } else {
        let params = {
          pageNum: 1,
          pageSize: 1000000,
          queryParams: { F_isDel_eq: 0, F_parentId_eq: parentId },
        };
        if (this.activeNode.data.sourceType == 1) {
          //公共转换,去除父级的查询,改为当前组的查询
          params.queryParams.F_parentId_eq = undefined;
          params.queryParams.F_jobGroupId_eq = this.activeJob.data.jobGroupId;
        }

        $dataIntegration
          .getJobList(params)
          .then((req) => {
            this.setSubJobConfig.jobs = req.data.filter((item) => {
              if (item.id != this.processId) {
                return item.jobType == 'job';
              } else {
                return false;
              }
            });
            this.setSubJobConfig.transforms = req.data.filter((item) => {
              if (item.id != this.processId) {
                return item.jobType == 'transform';
              } else {
                return false;
              }
            });
            this.changeSubJobList();
          })
          .finally(() => {});
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 修改作业列表
     */
    changeSubJobList(jobId) {
      if (jobId) {
        this.getJobList();
        this.activeNode.data.jobId = jobId;
      }
      if (this.activeNode.data.jobId) {
        $dataIntegration
          .getJobDetail({ id: this.activeNode.data.jobId })
          .then((req) => {
            this.activeNode.data.jobName = req.data.jobName;
            this.activeNode.data.jobType = req.data.jobType;
            let jobConfig = JSON.parse(req.data.jsonDetail);
            this.activeNode.data.steps = jobConfig.steps.map((item) => {
              return {
                data: {
                  type: item.data.type,
                  name: item.data.type,
                },
              };
            });
          })
          .finally(() => {
            this.updataNode();
          });
      }
    },

    /**
     * @Author: Jason Liu
     * @description: 查询控件列表
     */
    searchControlsList() {
      const xTable = this.$refs.controlsJobList;
      const column = xTable.getColumnByField('title');
      // 修改第二个选项为勾选状态
      const option = column.filters[0];
      option.data = this.control_str;
      option.checked = !!this.control_str;
      // 修改条件之后,需要手动调用 updateData 处理表格数据
      xTable.updateData();
    },
    /**
     * @Author: Jason Liu
     * @description: 查询设置
     */
    filterName({ option, row }) {
      return row.name.indexOf(option.data) > -1;
    },
    /**
     * @Author: Jason Liu
     * @description: 效果画布
     */
    disposeJobs(i) {
      let this_job = this.jobs[i];
      this_job.graph.dispose(); //销毁画布
      if (this_job.id == this.activeJob.id) {
        let job = this.jobs[i - 1];
        this.activeJob = {
          id: `${job.id}`,
          graph: job.graph,
          dnd: job.dnd,
          loading: job.loading,
          change: job.change,
          data: job.data,
        };
      }
      this.jobs.splice(i, 1);
      this.initCanvas();
    },
    /**
     * @Author: Jason Liu
     * @description: 退出设置
     */
    backSet() {
      let hasave = true; //是否都保存了
      this.jobs.forEach((item) => {
        if (item.change) {
          hasave = false;
        }
      });
      if (hasave) {
        this.show = false;
      } else {
        this.$confirm({
          title: $t('提示'),
          content: $t('有未保存的设计,确定要退出吗?'),
          okText: $t('是'),
          cancelText: $t('否'),
          onOk: () => {
            this.show = false;
          },
          onCancel() {},
        });
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 复制作业
     */
    copyJob() {
      let guid = `new_` + new Date().getTime();
      let job = {
        ...this.activeJob.data,
        jobName: $t('{slot1}_副本', { slot1: this.activeJob.data.jobName }),
        id: guid,
      };
      let map = JSON.parse(job.jsonDetail);

      map.steps = map.steps.map((step) => {
        step.id = `${step.id}_copy`;
        return step;
      });

      map.hops = map.hops.map((hop) => {
        hop.id = `${hop.id}_copy`;
        hop.source.cell = `${hop.source.cell}_copy`;
        hop.target.cell = `${hop.target.cell}_copy`;
        return hop;
      });

      job.jsonDetail = JSON.stringify(map);
      this.jobs.push({
        id: guid,
        graph: undefined, //画布
        loading: false,
        dnd: undefined, //插画
        change: true,
        data: job,
      });
      this.activeJob.id = guid;
      this.initCanvas();
    },
    /**
     * @Author: Jason Liu
     * @description: 删除作业
     */
    deleteJob() {
      let delIndex = this.jobs.findIndex((job) => {
        return job.id == this.activeJob.id;
      });
      if (delIndex > 0) {
        this.$confirm({
          title: $t('您确定要删除[{slot1}]吗?', { slot1: this.activeJob.data.jobName }),
          content: $t('删除后相关配置将失效'),
          okText: $t('确定'),
          okType: 'danger',
          cancelText: $t('取消'),
          onOk: () => {
            this.loading = true;
            $dataIntegration
              .deleteJob({ id: this.activeJob.id })
              .then((req) => {
                this.$message.success($t('删除操作成功'));
                if (this.activeJob.sourceStep) {
                  this.jobs.forEach((job) => {
                    const sourceStep = job.graph.getCellById(this.activeJob.sourceStep.id);
                    job.graph.removeCell(sourceStep);
                  });
                }
                this.activeJob.id = this.jobs[0].id;

                this.initCanvas();
                this.jobs.splice(delIndex, 1);
              })
              .finally(() => {
                this.loading = false;
              });
          },
          onCancel() {},
        });
      } else {
        this.$message.warning($t('主作业内容不可以在此页面做删除操作!'));
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 修改Es输出字段事件
     */
    changeEsOutput() {
      this.changeEndJob();
      this.updataNode();
    },
    /**
     * @Author: Jason Liu
     * @description: 修改Input字段事件
     */
    changeSqlInput() {
      this.changeEndJob();
      this.updataNode();
    },
    /**
     * @Author: Jason Liu
     * @description: 修改Input字段事件
     */
    changeOption() {
      this.changeEndJob();
      this.updataNode();
    },
    /**
     * @Author: Jason Liu
     * @description: 获取上层节点内容
     */
    getPreviouNodes({ id }) {
      let previoNodes = [];

      this.activeJob.graph.getEdges().forEach((edge) => {
        let line = edge.toJSON();
        if (line.target.cell == id) {
          let node = this.activeJob.graph.getCellById(line.source.cell);
          previoNodes.push(node.toJSON());
        }
      });
      return previoNodes;
    },
    /**
     * @Author: Jason Liu
     * @description: 获取来源节点
     */
    getSourceNode() {
      return this.getPreviouNodes(this.activeNode);
    },
    /**
     * @Author: Jason Liu
     * @description: 初始化内容
     */

    init() {
      if (this.show) {
        this.activeJobId = undefined; //选中的job
        this.jobs = []; //清空
        this.getJobDetail(this.processId, this.jobType);

        this.getGroupList();
        this.geiClustersList();
        if (this.jobType == 'flow') {
          this.getFlowGroups();
        } else {
          this.getParentList();
        }
      }
    },
  },
  watch: {
    value(val) {
      this.show = val;
      if (val) {
        this.init();
      } else {
        this.jobs.forEach((item, i) => {
          item.graph.dispose(); //销毁画布
        });
        this.clearProcessTest();
        this.$emit('update');
      }
    },
    show(val) {
      this.$emit('input', val);
    },
  },
};