UNPKG

w-vue-middle

Version:

统一公共服务组件

2,208 lines 72.3 kB
/*
 * @Author: Jason Liu
 * @Date: 2022-06-06 10:52:09
 * @Desc: 流程配置服务
 */

const { Graph, Shape, Addon, Registry } = require('@antv/x6');
import jsonView from 'vue-json-views';
import jsonEditor from 'vue-json-editor';

/**
 * @Author: Jason Liu
 * @description: 流程配置
 */
const { lineoption } = require('./config');
/**
 * @Author: Jason Liu
 * @description: 数据源接口
 */
const $dataIntegration = require('w-vue-middle/api/dataIntegration');

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

/**
 * @Author: Jason Liu
 * @description: 设置多表的join关系
 */
const setTableJoin = require('./package/setTableJoin.vue').default;
/**
 * @Author: Jason Liu
 * @description: 设置多表输出
 */
const setTablesOuts = require('./package/setTablesOuts.vue').default;

/**
 * @Author: Jason Liu
 * @description: 输出字段
 */
const outColumns = require('./package/outColumns.vue').default;

export default {
  name: 'designertackle',
  components: {
    jsonView,
    jsonEditor,
    processDesigner: () => import('w-vue-middle/views/dataintegration/processdesign/designer'),
    setTableJoin,
    setTablesOuts,
    outColumns,
  },
  props: {
    processId: {
      //流程ID
      type: [String, Number],
      default: undefined,
    },
    jobType: {
      type: String,
    },
  },
  provide() {
    return {
      /**
       * @Author: Jason Liu
       * @description: 获取选择的对象
       */
      getNode: () => {
        return Object.assign({}, this.activeNode);
      },
      /**
       * @Author: Jason Liu
       * @description: 设置更新对象
       */
      setNodeData: (data) => {
        this.activeNode.data = data;
        this.updataNode();
      },

      getChangeJoinTablesColumns: (node) => {
        return this.getChangeJoinTablesColumns(node);
      },
      /**
       * @Author: Jason Liu
       * @description: 设置输出列
       */
      setDataColumns: (data) => {
        this.setDataColumns();
      },
    };
  },
  data() {
    return {
      isSet: false, //是否显示设置
      activeKey: '1',
      tool: '1',
      designerContainer: undefined, //设计器实体
      graph: undefined,
      dnd: undefined,
      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: [],
        },
      },
      metadatas: {
        dataSource: [], //数据源
        schema: [], //schema列表
        dataTables: [], //数据表
        dwsAndads: {
          dbInfo: {
            schema: undefined,
            dbName: undefined,
          },
          dws: [],
          ads: [],
          showData: [],
        },
      },
      setOutTables: {
        //输出参数设置
        setMap: false, //设置映射
        str: undefined,
        overlay: false,
      },
      setPerlConfig: {
        //Per参数设置
        show: false,
        config: {},
      },
      setSubJobConfig: {
        //子作业参数设置
        setSubJobConfig: false, //搜索信息
        subEdit: false,
        jobs: [], //作业列表
        transforms: [],
      },
      setTableJoinConfig: {
        //设置表不关联配置
        setJoin: false, //设置关联方式
        setColumns: false, //设置显示字段
      },
      waitRemovedList: {}, //等待删除列表
      executorTaskList: [], //调度任务列表
      executorList: [], //调度执行器列表
      controlsList: [], //控件列表
    };
  },

  mounted() {
    this.init();
  },
  methods: {
    /**
     * @Author: Jason Liu
     * @description: 初始化设计器
     */
    init() {
      this.$nextTick(() => {
        if (this.$refs.designer_container && !this.graph) {
          this.getDbsDatas();
          //初始化网格
          const graphOpetion = this.getGraphOpetion();
          this.graph = new Graph(graphOpetion);

          //  初始化 stencil
          const stencilOpetion = this.getStencilOpetion();
          const stencil = new Addon.Stencil(stencilOpetion);
          this.$refs.stencil_container.appendChild(stencil.container);

          /**
           * @Author: Jason Liu
           * @description: 开始节点
           */
          const start = this.graph.createNode({
            shape: 'custom-rect',
            label: $t('开始'),
            type: 'start',
            data: {
              id: undefined,
              name: $t('开始'),
              code: undefined,
              type: 'start',
              description: undefined,
            },
          });

          /**
           * @Author: Jason Liu
           * @description: 结束节点
           */
          const end = this.graph.createNode({
            shape: 'custom-rect',
            label: $t('结束'),
            type: 'end',
            data: {
              id: undefined,
              name: $t('结束'),
              code: undefined,
              type: 'end',
              description: undefined,
            },
          });

          /**
           * @Author: Jason Liu
           * @description: 库表输入
           */
          const tableentry = this.graph.createNode({
            shape: 'custom-input',
            label: $t('库表输入'),
            data: {
              id: undefined,
              name: $t('库表输入'),
              code: undefined,
              type: 'TableInput', //TableInput:表库输出 TableJoin表合并关联
              dbId: undefined, //链接数据库ID
              dbName: undefined, //链接数据库名称
              dbType: undefined, //链接数据库类型
              schema: undefined, //目标schema,映射schemaCode
              schemaId: undefined,
              tableId: undefined, //选择的数据表ID
              tableName: undefined, //选择的数据表名称
              tableCode: undefined, //选择的数据表名称
              tableColumns: [], //数据源字段信息
              columns: [], //输出字段信息
              lookUp: false, //是否维表
              eventTimeColumn: undefined, //事件执行字段,必须时间格式,且必须出现在columns中
              description: undefined,
            },
          });

          /**
           * @Author: Jason Liu
           * @description: 库表输入
           */
          const TableOutputSql = this.graph.createNode({
            shape: 'custom-input',
            label: $t('SQL输入'),
            data: {
              id: undefined,
              name: $t('SQL输入'),
              code: undefined,
              type: 'TableOutputSql',
              dbId: undefined, //链接数据库ID
              dbName: undefined, //链接数据库名称
              dbType: undefined, //链接数据库类型
              modelType: 'dws', //模式类型
              schema: undefined, //目标schema,映射schemaCode
              schemaId: undefined,
              tableId: undefined, //选择的数据表ID
              tableName: undefined, //选择的数据表名称
              tableCode: undefined, //选择的数据表名称
              columns: [], //输出字段信息
              lookUp: false, //是否维表
              eventTimeColumn: undefined, //事件执行字段,必须时间格式,且必须出现在columns中
              description: undefined,
            },
          });

          const perlConfig = this.graph.createNode({
            shape: 'custom-input',
            label: $t('perl配置'),
            data: {
              id: undefined,
              name: $t('perl配置'),
              type: 'PerlConfig', //TableInput:表库输出 TableJoin表合并关联
              config: {}, //配置json
              description: undefined,
            },
          });
          /**
           * @Author: Jason Liu
           * @description: 库表输出
           */
          const tableoutput = this.graph.createNode({
            shape: 'custom-input',
            label: $t('库表输出'),
            data: {
              id: undefined,
              name: $t('库表输出'),
              code: undefined,
              type: 'TableOutput',
              dbId: undefined, //链接数据库ID
              dbName: undefined, //链接数据库名称
              dbType: undefined, //链接数据库类型
              tableId: undefined, //选择的数据表ID
              tableName: undefined, //选择的数据表名称
              tableCode: undefined, //选择的数据表名称
              tableColumns: [], //数据源字段信息
              columns: [], //输出字段信息
              schema: undefined, //目标schema,映射schemaCode
              schemaId: undefined,
              lookUp: false, //是否维表
              eventTimeColumn: undefined, //事件执行字段,必须时间格式,且必须出现在columns中
              mapping: [], //映射字段
              inputTable: {
                //输入表格
                tableId: undefined, //选择的数据表ID
                tableName: undefined, //选择的数据表名称
                tableCode: undefined, //选择的数据表名称
                columns: [], //输出字段
              },
              description: undefined,
            },
          });

          const subJob = this.graph.createNode({
            shape: 'custom-input',
            label: $t('作业'),
            data: {
              id: undefined,
              name: $t('作业'),
              code: undefined,
              type: 'SubJob', //组件类型
              jobId: undefined, //子任务ID
              jobNmae: undefined, //子任务名称
              steps: [], //子任务相关节点概览信息
              hops: [], //子任务连线概览
              schema: 'public',
              lookUp: false,
              description: undefined,
            },
          });

          const subTransform = this.graph.createNode({
            shape: 'custom-input',
            label: $t('转换'),
            data: {
              id: undefined,
              name: $t('转换'),
              code: undefined,
              type: 'SubTransform', //组件类型
              jobId: undefined, //子任务ID
              jobNmae: undefined, //子任务名称
              steps: [], //子任务相关节点概览信息
              hops: [], //子任务连线概览
              schema: 'public',
              lookUp: false,
              description: undefined,
            },
          });

          /**
           * @Author: Jason Liu
           * @description: 库表合并
           */
          const join = this.graph.createNode({
            shape: 'custom-input',
            label: $t('合并'),
            data: {
              id: undefined,
              name: $t('库表合并'),
              code: undefined,
              type: 'TableJoin',
              tableId: undefined,
              tableName: undefined,
              tableCode: undefined,
              columns: [], // formerName:med_insti_no,//物理字段名  columnName: "eeed", //别名
              tables: [], //关联的表信息  { tableid, tableName,tableCode,  asName: "a", columns, isMain }, //isMain是否主表
              joins: [], //绑定的关系信息
              /*
              {
                  joinType: "join", //关联方式
                  right: {
                      //关联表
                      tableid, tablenameB,
                  },
                  condition: [
                      //关联字段
                      {
                          type: "def", //通过关系的方式关联
                          left: { tableid, tablenameA, columnA },
                          relation: "=",
                          right: { tableid, tablenameB, columnA ,
                              condition:[]
                          },
                      },
                      {
                          type: "def", //通过关系的方式关联
                          left: { tableid, tablenameA, columnB },
                          relation: "=",
                          right: { tableid, tablenameB, columnC },
                      },
                      {
                          type: "sql", //通过sql语句输入的方式关联,暂时不实现
                          sql: "a.biz_role_id=b.biz_role_id",
                      },
                  ],
              },
              */
              lookUp: false,
              description: undefined,
            },
          });

          stencil.load([start, end], 'basic');
          stencil.load([tableentry, TableOutputSql, perlConfig], 'inputcomponent');
          stencil.load([tableoutput, join], 'outputcomponent');
          stencil.load([subJob, subTransform], 'conversioncomponent');
          stencil.load(
            [
              {
                shape: 'custom-input',
                label: $t('调度任务'),
                data: {
                  id: undefined,
                  name: $t('调度任务'),
                  code: undefined,
                  type: 'WinningJob', //组件类型
                  scheduleType: 'CRON', //scheduleType枚举类型 CRON:周期任务 REALTIME:实时任务 MANUAL:手动任务
                  groupId: undefined, //
                  winningJobId: undefined, //2.2中的id
                  winningJobName: undefined, //2.2中的jobDesc
                  description: undefined,
                },
              },
            ],
            'flowcomponent',
          );

          this.bindEvent();
          this.createDnd();
          this.getControlsList();
        }
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 获取动态控件列表
     */
    getControlsList() {
      switch (this.jobType) {
        case 'flow': //任务调度设计
          this.controlsList = [
            {
              id: 'CRON',
              name: $t('周期任务'),
              scheduleType: 'CRON',
              isGroup: true,
              hasChild: true,
            },
            {
              id: 'REALTIME',
              name: $t('实时任务'),
              scheduleType: 'REALTIME',
              isGroup: true,
              hasChild: true,
            },
            {
              id: 'MANUAL',
              name: $t('手动任务'),
              scheduleType: 'MANUAL',
              isGroup: true,
              hasChild: true,
            },
          ];
          break;
        case 'job':
          this.controlsList = [
            {
              id: 'job',
              name: $t('作业列表'),
              isGroup: true,
              hasChild: true,
            },
            {
              id: 'transform',
              name: $t('转换列表'),
              isGroup: true,
              hasChild: true,
            },
          ];
          break;
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 创建拖动事件
     */
    createDnd() {
      if (!this.dnd) {
        this.dnd = new Addon.Dnd({
          target: this.graph,
          scaled: false,
          animation: true,
        });
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 加载子数据内容
     */
    loadToolChildrenMethod({ row }) {
      return new Promise((resolve) => {
        switch (this.jobType) {
          case 'flow': //加载流程任务
            $dispatchcenter
              .getScheduleTaskList(
                {
                  pageNum: 1,
                  pageSize: 100000,
                },
                row.id,
              )
              .then((req) => {
                const childs = req.data.map((item) => {
                  item.name = item.jobDesc;
                  item.type = 'WinningJob';
                  return item;
                });
                if (childs.length == 0) {
                  row.hasChild = false;
                }
                resolve(childs);
              });
            break;
          case 'job':
            $dataIntegration
              .getJobList({
                pageNum: 1,
                pageSize: 1000000,
                queryParams: { F_isDel_eq: 0, F_jobType_eq: row.id },
              })
              .then((req) => {
                const childs = req.data.map((item) => {
                  item.name = item.jobName;
                  item.type = row.id == 'job' ? 'SubJob' : 'SubTransform';
                  return item;
                });
                if (childs.length == 0) {
                  row.hasChild = false;
                }
                resolve(childs);
              });
            break;
        }
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 开始拖动事件
     */
    startDrag(e) {
      let target = e.toElement.dataset;
      let info = undefined;
      this.controlsList.forEach((schedule) => {
        schedule.children.forEach((item) => {
          if (item.id == target.id) {
            info = item;
          }
        });
      });
      if (info) {
        switch (target.type) {
          case 'WinningJob':
            this.dnd.start(
              this.graph.createNode({
                shape: 'custom-input',
                label: info.jobDesc,
                data: {
                  id: undefined,
                  name: info.jobDesc,
                  code: undefined,
                  type: 'WinningJob', //组件类型
                  scheduleType: info.scheduleType, //scheduleType枚举类型 CRON:周期任务 REALTIME:实时任务 MANUAL:手动任务
                  groupId: info.jobGroup, //
                  groupName: info.jobGroupName, //
                  winningJobId: info.id, //2.2中的id
                  winningJobName: info.jobDesc, //2.2中的jobDesc
                  description: undefined,
                },
              }),
              e,
            );
            break;
          case 'SubJob':
          case 'SubTransform':
            this.dnd.start(
              this.graph.createNode({
                shape: 'custom-input',
                label: info.name,
                data: {
                  id: undefined,
                  name: info.name,
                  code: undefined,
                  type: info.type, //组件类型
                  jobId: info.id, //子任务ID
                  jobNmae: info.name, //子任务名称
                  steps: [], //子任务相关节点概览信息
                  hops: [], //子任务连线概览
                  schema: 'public',
                  lookUp: false,
                  description: undefined,
                },
              }),
              e,
            );

            break;
        }
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 获取菜单设置
     */
    getStencilOpetion() {
      return {
        target: this.graph,
        stencilGraphWidth: 180, //模板宽度
        stencilGraphHeight: 50, //模板高度
        collapsable: false,
        collapsed: false,
        groups: [
          {
            title: $t('基础组件'),
            name: 'basic',
            graphHeight: 50,
            type: ['job', 'flow'],
            layoutOptions: {
              columns: 2,
              columnWidth: 80,
            },
          },
          {
            title: $t('输入组件'),
            graphHeight: 130,
            type: ['transform'],
            name: 'inputcomponent',
          },
          {
            title: $t('输出组件'),
            name: 'outputcomponent',
            graphHeight: 90,
            type: ['transform'],
            collapsed: false,
          },
          {
            title: $t('转换组件'),
            name: 'conversioncomponent',
            graphHeight: 90,
            type: ['job'],
            collapsed: false,
          },
          {
            title: $t('流程配置'),
            name: 'flowcomponent',
            graphHeight: 90,
            type: ['flow'],
            collapsed: false,
          },
        ].filter((item) => {
          return item.type.indexOf(this.jobType) > -1;
        }),
        layoutOptions: {
          //布局方式
          columns: 1,
          columnWidth: 160,
          rowHeight: 40,
        },
      };
    },
    /**
     * @Author: Jason Liu
     * @description: 获取网格配置
     */
    getGraphOpetion() {
      return {
        container: this.$refs.designer_container, //容器对象
        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: 绑定事件
     */
    bindEvent() {
      this.graph.on('blank:click', ({ e, x, y }) => {
        //("blank:click", e);
        this.isSet = false;
      });
      this.bindNodeEvent();
      this.bindCallEvent();
      this.bindDocumentEvent();
      this.bindEdgeEvent();
    },
    /**
     * @Author: Jason Liu
     * @description: 绑定Call事件
     */
    bindCallEvent() {
      this.graph.on('cell:mouseenter', ({ cell }) => {
        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: 10, y: 10 } },
            },
          ]);
          cell.addTools(
            ['vertices', 'source-arrowhead', 'target-arrowhead'].map((name) => {
              return {
                name: name,
                args: { attrs: { fill: '#FF8C00' } },
              };
            }),
          );
        }
      });

      this.graph.on('cell:mouseleave', ({ cell }) => {
        cell.removeTools();
      });

      this.graph.on('cell:click', ({ e, x, y, cell, view }) => {
        cell.removeTools();
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 绑定节点事件
     */
    bindNodeEvent() {
      this.graph.on('node:click', ({ e, x, y, node, view }) => {
        this.isSet = true;
        let tempNode = node.toJSON();
        switch (tempNode.data.type) {
          case 'TableOutputSql':
            tempNode.data.columns = tempNode.data.columns || []; //数据安全处理
            break;
        }
        this.activeNode = tempNode;
        //获取选中控件的选择数据
        this.getSelectData();
      });

      // 控制连接桩显示/隐藏
      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.designer_container;
        const ports = container.querySelectorAll('.x6-port-body');
        showPorts(ports, true);
      });
      this.graph.on('node:mouseleave', () => {
        const container = this.$refs.designer_container;
        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 }) => {
        //节点被删除
        if (this.waitRemovedList[node.id]) {
          //存在删除处理事件队列
          switch (node.data.type) {
            case 'TableOutput': //输出控件特殊处理
            case 'TableInput':
            case 'TableJoin':
              this.waitRemovedList[node.id].forEach((next) => {
                const nextData = next.toJSON();
                let isChange = false;
                switch (nextData.data.type) {
                  case 'TableOutput':
                    nextData.data.inputTable = {
                      columns: [],
                      tableId: undefined,
                      tableName: undefined,
                      tableCode: undefined,
                    };
                    nextData.data.mapping.forEach((row) => {
                      if (row.source) {
                        row.source = {
                          pk: false,
                          select: undefined,
                          columnName: undefined,
                          columnType: undefined,
                          description: undefined,
                          columnTypeFlink: undefined,
                        };
                      }
                    });
                    next.updateData({
                      ...nextData.data,
                    });
                    isChange = true;
                    break;
                  case 'TableJoin':
                    this.removeTableJoinNode(
                      {
                        source: node,
                        target: nextData,
                      },
                      {
                        target: next,
                      },
                    );
                    isChange = true;
                    break;
                }
                if (isChange) {
                  if (next.id == this.activeNode.id) {
                    this.activeNode.data = nextData.data;
                  }
                }
              });
              this.waitRemovedList[node.id] = undefined; //清除缓存数据
              break;
          }
        }
      });
      this.graph.on('node:added', ({ node, index, options }) => {
        //创建
        let now = new Date();
        //更新数据的name
        node.updateData({
          id: node.id,
          code: `${node.data.type}_${$storage.userInfo.userName}_${now.toJSON()}`,
        });
        this.isSet = true;
        this.activeNode = node.toJSON();
        this.getSelectData();
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 绑定页面事件
     */
    bindDocumentEvent() {
      // 快捷键与事件
      // 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'], () => {
        const zoom = this.graph.zoom();
        if (zoom < 1.5) {
          this.graph.zoom(0.1);
        }
      });
      this.graph.bindKey(['ctrl+2', 'meta+2'], () => {
        const zoom = this.graph.zoom();
        if (zoom > 0.5) {
          this.graph.zoom(-0.1);
        }
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 绑定连线事件
     */
    bindEdgeEvent() {
      const connected = (edge) => {
        let line = edge.toJSON();
        if (line.source.cell == line.target.cell) {
          this.$message.error($t('同一个组件不能及时连线的开始组件又是结束组件,连线将被移除。'));
          edge.remove();
        } else {
          let changeNodes = {
            source: this.graph.getCellById(line.source.cell), //来源的数据
            target: this.graph.getCellById(line.target.cell), //目标的数据
          };
          //TODO:添加同一个节点,不能链接另一个已经链接了的节点
          //修改节点的内容
          let changeNodesData = {
            source: changeNodes.source.toJSON(),
            target: changeNodes.target.toJSON(),
          };

          //内置关联绑定
          edge.updateData({
            source: { code: changeNodesData.source.data.code },
            target: { code: changeNodesData.target.data.code },
          });
          this.changeNodesDssociate(changeNodesData, changeNodes);
        }
      };

      this.graph.on('edge:removed', ({ isNew, edge }) => {
        //删除线条事件
        let line = edge.toJSON();
        let changeNodes = {
          source: this.graph.getCellById(line.source.cell), //来源的数据
          target: this.graph.getCellById(line.target.cell), //目标的数据
        };
        if (changeNodes.source && changeNodes.target) {
          //修改节点的内容
          let changeNodesData = {
            source: changeNodes.source.toJSON(),
            target: changeNodes.target.toJSON(),
          };
          this.removeNodesDssociate(changeNodesData, changeNodes);
        } else {
          if (!this.waitRemovedList[line.source.cell]) {
            this.waitRemovedList[line.source.cell] = new Array();
          }
          this.waitRemovedList[line.source.cell].push(changeNodes.target);
        }
      });
      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.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(),
            };
            this.removeNodesDssociate(changeNodesData, changeNodes);
          }
          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(),
              };
              this.removeNodesDssociate(changeNodesData, changeNodes);
            }
            edge.updateData({
              source: line.source,
            });
          }
          edge.updateData({
            target: line.target,
          });
        }
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 更新选中的节点
     */
    updataNode(isAll) {
      if (this.activeNode.id) {
        const node = this.graph.getCellById(this.activeNode.id);
        if (isAll) {
          node.setProp({
            ...this.activeNode,
          });
        }
        node.updateData({
          ...this.activeNode.data,
        });
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 修改TableJoin的表编码
     */
    changeTableJoinCode() {
      let keyValue = '';

      let val = this.activeNode.data.tableCode;
      for (let i = 0; i < val.length; i++) {
        if (val.charCodeAt(i) > 0 && val.charCodeAt(i) < 255) {
          keyValue += val[i];
        }
      }
      this.activeNode.data.tableCode = keyValue;
      this.updataNode();
    },
    /**
     * @Author: Jason Liu
     * @description: 修改node的关联数据
     */
    changeNodesDssociate(node, changeNodes) {
      switch (
        node.source.data.type //遍历开始控件
      ) {
        case 'TableInput': //表输入控件
        case 'TableOutput': //表输出
        case 'TableJoin': //表关联
          switch (
            node.target.data.type //遍历目标控件
          ) {
            case 'TableOutput':
              //从输出指向输入
              node.target.data.inputTable = {
                dbId: node.source.data.dbId,
                schema: node.source.data.schema,
                columns: node.source.data.columns,
                tableId: node.source.data.tableId || node.source.data.tableCode,
                tableName: node.source.data.tableName,
                tableCode: node.source.data.tableCode,
              };

              node.target.data.mapping.forEach((row) => {
                if (row.source) {
                  row.source = {
                    pk: false,
                    columnName: undefined,
                    select: undefined,
                    columnType: undefined,
                    description: undefined,
                    columnTypeFlink: undefined,
                  };
                }
              });

              changeNodes.target.updateData({
                ...node.target.data,
              });
              if (node.target.id == this.activeNode.id) {
                this.activeNode.data.inputTable = node.target.data.inputTable;
              }
              break;
            case 'TableJoin':
              node.target.data.tables.push({
                columns: node.source.data.columns.map((row) => {
                  return {
                    asName: row.columnName,
                    checked: true,
                    ...row,
                  };
                }),
                dbId: node.source.data.dbId,
                schema: node.source.data.schema,
                tableId: node.source.data.tableId,
                tableName: node.source.data.tableName,
                tableCode: node.source.data.tableCode,
                asName: node.source.data.tableCode,
                isMain: node.target.data.tables.length == 0,
                sourceCode: node.source.data.code, //来源的编码,来源更新表时,需要用到更新
              });
              node.target.data.columns = this.getChangeJoinTablesColumns(node.target.data);
              changeNodes.target.updateData({
                ...node.target.data,
              });

              if (node.target.id == this.activeNode.id) {
                this.activeNode.data.tables = node.target.data.tables;
              }
              break;
          }
          break;
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 删除TableJoin的关联节点
     */
    removeTableJoinNode(node, changeNodes) {
      /*
          1、移除来源的table(完成)
          2、设置主表字段(完成)
          3、移除关联字段(完成)
          4、更新输出字段(完成)
      */
      let isMain = false; //判断移除的表是否是主表
      let sourceTableCode = node.source.data.tableCode;
      let index = node.target.data.tables.findIndex((table) => {
        if (table.tableCode == sourceTableCode) {
          isMain = table.isMain;
          return true;
        } else {
          return false;
        }
      });
      node.target.data.tables.splice(index, 1); //删除了原来的表信息
      if (isMain && node.target.data.tables.length > 0) {
        //设置主表字段
        node.target.data.tables[0].isMain = true;
      }

      let newJoins = node.target.data.joins.filter((join) => {
        let carry = true; //是否继承
        if (join.right.tableCode == sourceTableCode) {
          //检查关联表是否有用到移除的表
          carry = false;
        } else {
          join.conditions.forEach((condition) => {
            //检查关联字段是否有用到移除的字段
            if (
              condition.left.tableCode == sourceTableCode ||
              condition.right.tableCode == sourceTableCode
            ) {
              carry = false;
            }
          });
        }
        return carry;
      });

      node.target.data.joins = newJoins;
      //更新输出字段
      node.target.data.columns = this.getChangeJoinTablesColumns(node.target.data);
      changeNodes.target.updateData({
        ...node.target.data,
      });

      if (node.target.id == this.activeNode.id) {
        this.activeNode.data = node.target.data;
      }

      //this.$message.success({ content: `请注意,${node.target.data.name}的配置发生变化。`, key: 'removeNodesDssociate' });
    },
    /**
     * @Author: Jason Liu
     * @description: 修改node的数据关系
     */
    removeNodesDssociate(node, changeNodes) {
      switch (
        node.source.data.type //遍历开始控件
      ) {
        case 'TableInput': //表输入控件
        case 'TableOutput':
        case 'TableJoin':
          switch (
            node.target.data.type //遍历目标控件
          ) {
            case 'TableOutput':
              node.target.data.inputTable = {
                columns: [],
                tableId: undefined,
                tableName: undefined,
                tableCode: undefined,
              };
              changeNodes.target.updateData({
                ...node.target.data,
              });
              this.$message.success({
                content: $t('请注意,{slot1}的配置发生变化。', { slot1: node.target.data.name }),
                key: 'removeNodesDssociate',
              });
              if (node.target.id == this.activeNode.id) {
                this.activeNode.data.inputTable = node.target.data.inputTable;
              }
              break;
            case 'TableJoin':
              this.removeTableJoinNode(node, changeNodes);
              break;
          }
          break;
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 获取选中控件的数据内容
     */
    getSelectData() {
      switch (
        this.activeNode.data.type //遍历控件类型
      ) {
        case 'TableInput':
        case 'TableOutput':
          if (this.activeNode.data.dbId) {
            //选中了数据源的情况下
            this.getSchema(true); //获取getSchema
          }
          break;
        case 'TableOutputSql':
          this.getDwsAndAdsTables();
          break;
        case 'SubJob': //子任务,获取任务列表
        case 'SubTransform':
          this.getJobList();
          break;
        case 'WinningJob':
          this.getExecutorList();
          break;
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 获取WinningJob执行器列表
     */
    getExecutorList() {
      $dispatchcenter
        .getExecutorList({
          pageNum: 1,
          pageSize: 10000,
        })
        .then((req) => {
          this.executorList = req.data.map((item) => {
            return {
              value: item.id,
              label: item.title,
              ...item,
            };
          });
          this.getWinningJobList();
        });
    },
    /**
     * @Author: Jason Liu
     * @description: 获取WinningJob的列表信息
     */
    getWinningJobList() {
      if (this.activeNode.data.groupId) {
        $dispatchcenter
          .getExecutorTaskList({
            groupId: this.activeNode.data.groupId,
            scheduleType: this.activeNode.data.scheduleType,
          })
          .then((req) => {
            this.executorTaskList = req.data.map((item) => {
              return {
                value: item.id,
                label: item.jobDesc,
                ...item,
              };
            });
          });
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 修改调度任务主数据
     */
    changeWinningJobMain() {
      this.activeNode.data.winningJobId = undefined;
      this.updataNode(false);
      this.getWinningJobList();
    },
    /**
     * @Author: Jason Liu
     * @description: 修改WinningJobList事件
     */
    changeWinningJobList() {
      let tesk = this.executorTaskList.find((item) => {
        return item.id == this.activeNode.data.winningJobId;
      });
      this.activeNode.data.winningJobName = tesk.jobDesc;
      this.$set(this.activeNode, 'data.winningJobId', this.activeNode.data.winningJobId);
      this.updataNode(false);
    },
    /**
     * @Author: Jason Liu
     * @description: 修改数据源事件
     */
    changeDbsDatas() {
      let selDb = this.metadatas.dataSource.find((item) => {
        return item.dbId == this.activeNode.data.dbId;
      });
      this.activeNode.data = {
        ...this.activeNode.data,
        ...{
          dbId: selDb.dbId,
          dbName: selDb.dbName,
          dbType: selDb.dbType,
          schema: undefined,
          schemaId: undefined,
        },
      };

      this.getSchema();
      this.updataNode();
    },
    /**
     * @Author: Jason Liu
     * @description: 获取数据源下的Schema信息
     */
    getSchema(noset) {
      $dataIntegration
        .getDbsSchema(this.activeNode.data)
        .then((req) => {
          this.metadatas.schema = req.data;
          if (noset) {
            this.getDataTables(noset);
          } else {
            if (this.metadatas.schema.length > 0) {
              this.activeNode.data.schemaId = req.data[0].schemaId;
              this.changeSchema();
            }
          }
        })
        .finally();
    },
    /**
     * @Author: Jason Liu
     * @description: 修改Schema
     */
    changeSchema() {
      let schema = this.metadatas.schema.find((item) => {
        return item.schemaId == this.activeNode.data.schemaId;
      });
      this.activeNode.data.schema = schema.schemaCode;
      this.updataNode();
      this.getDataTables();
    },

    /**
     * @Author: Jason Liu
     * @description: 修改数据表信息
     */
    chaneDataTables(isReload) {
      let table = this.metadatas.dataTables.find((item) => {
        return item.tableCode == this.activeNode.data.tableCode;
      });
      if (table) {
        this.activeNode.data = { ...this.activeNode.data, ...table };
        this.updataNode();
        this.getDataColumns(table, isReload);
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 修改事件执行字段事件
     */
    changeEventTimeColumn() {
      //强制选中选中的字段
      //该字段不可以被取消
      this.activeNode.data.tableColumns.forEach((item) => {
        if (item.columnName == this.activeNode.data.eventTimeColumn) {
          item.checked = true;
          //this.$refs.outTable.setCheckboxRow([item], true)
        }
      });
      this.setDataColumns();
    },
    /**
     * @Author: Jason Liu
     * @description: 获取表格变更后的输出列
     */
    getChangeJoinTablesColumns(node) {
      let columns = [];
      if (node.tables.length > 0) {
        let queue = {};
        node.tables.forEach((table) => {
          table.columns.forEach((column) => {
            if (column.checked) {
              column.asName = column.asName || `${column.columnName}`;
              if (queue[column.asName]) {
                column.asName = `${column.asName}_${queue[column.asName]}`;
                queue[column.asName]++;
              } else {
                queue[column.asName] = 1;
              }
              columns.push({
                tableId: table.tableId,
                tableName: table.tableName,
                tableCode: table.tableCode,
                asName: table.asName,
                ...column,
              });
            }
          });
        });
      }
      return columns;
    },
    /**
     * @Author: Jason Liu
     * @description: 设置输出内容
     */
    setDataColumns() {
      this.activeNode.data.columns = this.activeNode.data.tableColumns.filter((item) => {
        return item.checked;
      });
      /**
       * @Author: Jason Liu
       * @description: 更新自己本身的数据
       */
      const updateThis = () => {
        switch (this.activeNode.data.type) {
          case 'TableOutput': //输出控件特殊处理
            let mapping = [...this.activeNode.data.mapping]; //记录原来的数据
            this.activeNode.data.mapping = this.activeNode.data.columns.map((item) => {
              let original = mapping.find((chen) => {
                if (chen.target.columnName) {
                  return (
                    chen.target.columnName.toLocaleLowerCase() ==
                    item.columnName.toLocaleLowerCase()
                  );
                } else {
                  return false;
                }
              });
              if (original) {
                return original;
              } else {
                return {
                  target: { ...item },
                  source: {
                    pk: false,
                    columnName: undefined,
                    select: undefined,
                    type: 'field',
                    columnType: undefined,
                    description: undefined,
                    columnTypeFlink: undefined,
                  },
                };
              }
            });
            break;
        }
      };
      updateThis();
      this.updateNext(this.activeNode);
      this.updataNode();
    },
    /**
     * @Author: Jason Liu
     * @description: 更新下一个节点的数据,这是一个链式的函数
     */
    updateNext(node) {
      const nextNodes = this.getNextNodes(node);
      if (nextNodes.length > 0) {
        switch (node.data.type) {
          case 'TableOutput': //输出控件特殊处理
          case 'TableInput':
          case 'TableJoin':
            nextNodes.forEach((next) => {
              const nextData = next.toJSON();
              const updateThis = () => {
                this.updateNext(nextData);
                next.updateData({
                  ...nextData.data,
                });
              };
              switch (nextData.data.type) {
                case 'TableOutput':
                  nextData.data.inputTable = {
                    columns: node.data.columns,
                    tableId: node.data.tableId,
                    tableName: node.data.tableName,
                    tableCode: node.data.tableCode,
                  };
                  nextData.data.mapping.forEach((row) => {
                    if (row.source) {
                      let map = node.data.columns.find((col) => {
                        return col.columnName == row.source.columnName;
                      });
                      if (!map) {
                        //找不到来源映射
                        row.source = {
                          pk: false,
                          columnName: undefined,
                          select: undefined,
                          columnType: undefined,
                          description: undefined,
                          columnTypeFlink: undefined,
                        };
                      }
                    }
                  });
                  updateThis();
                  break;
                case 'TableJoin':
                  nextData.data.tables.forEach((table, i) => {
                    if (table.sourceCode == node.data.code) {
                      //找到映射的数据源
                      /*
                          1、判断是否切换了数据源
                          2、若没切换,则修:
                              2.1、更新输出的表字段(完成)
                              2.2、检查join配置是否有被移除的字段(完成)
                          3、若切换了,则修改:
                              3.1、移除原表字段(完成)
                              3.2、移除原本的join配置(完成)
                              3.3、移除原本的输出字段(完成)
                              3.4、添加新表的输出字段(完成)
                      */
                      if (table.tableCode == node.data.tableCode) {
                        let columnsNames = table.columns.map((col) => {
                          return col.columnName;
                        });
                        table.columns = node.data.columns
                          .filter((row) => {
                            return row.checked;
                          })
                          .map((row) => {
                            //更新输出的表字段
                            let index = columnsNames.findIndex((old) => {
                              return old == row.columnName;
                            });
                            if (index > -1) {
                              return row;
                            } else {
                              //只对新数据做调整
                              return {
                                formerName: row.columnName,
                                checked: true,
                                ...row,
                              };
                            }
                          });
                        let newJoins = nextData.data.joins.filter((join) => {
                          let carry = true; //是否继承

                          join.conditions.forEach((condition) => {
                            //检查关联字段是否有用到移除的字段
                            if (condition.left.tableCode == table.tableCode) {
                              carry =
                                table.columns.findIndex((row) => {
                                  return row.columnName == condition.left.column.columnName;
                                }) > -1;
                            } else if (condition.right.tableCode == table.tableCode) {
                              carry =
                                table.columns.findIndex((row) => {
                                  return row.columnName == condition.right.column.columnName;
                                }) > -1;
                            }
                          });
                          return carry;
                        });

                        nextData.data.joins = newJoins;
                      } else {
                        //切换了数据源
                        debugger;
                        let newJoins = nextData.data.joins.filter((join) => {
                          let carry = true; //是否继承
                          if (join.right.tableCode == table.tableCode) {
                            //检查关联表是否有用到移除的表
                            carry = false;
                          } else {
                            join.conditions.forEach((condition) => {
                              //检查关联字段是否有用到移除的字段
                              if (
                                condition.left.tableCode == table.tableCode ||
                                condition.right.tableCode == table.tableCode
                              ) {
                                carry = false;
                              }
                            });
                          }
                          return carry;
                        });

                        nextData.data.joins = newJoins;
                        nextData.data.tables[i] = {
                          columns: node.data.columns.map((row) => {
                            return {
                              formerName: row.columnName,
                              checked: true,
                              ...row,
                            };
                          }),
                          tableId: node.data.tableId,
                          tableName: node.data.tableName,
                          tableCode: node.data.tableCode,
                          asName: node.data.tableCode,
                          isMain: table.isMain,
                          sourceCode: node.data.code, //来源的编码,来源更新表时,需要用到更新
                        };
                      }
                    }
                  });
                  nextData.data.columns = this.getChangeJoinTablesColumns(nextData.data);
                  updateThis();
                  break;
              }
            });
            break;
        }
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 获取下一层节点
     */
    getNextNodes({ id }) {
      let nextNodes = [];
      this.graph.getEdges().forEach((edge) => {
        let line = edge.toJSON();
        if (line.source.cell == id) {
          nextNodes.push(this.graph.getCellById(line.target.cell));
        }
      });
      return nextNodes;
    },
    /**
     * @Author: Jason Liu
     * @description: 输出映射自动填充
     */
    outTablesSmartFill() {
      this.activeNode.data.mapping = this.activeNode.data.mapping.map((item) => {
        let original = this.activeNode.data.inputTable.columns.find((chen) => {
          return chen.columnName.toLocaleLowerCase() == item.target.columnName.toLocaleLowerCase();
        });
        if (original) {
          item.source = original;
          if (original.tableAsName) {
            item.source.select = `${original.tableAsName}.${original.columnName}`;
          } else {
            item.source.select = original.columnName;
          }
        }
        return item;
      });
      this.updataNode();
    },
    /**
     * @Author: Jason Liu
     * @description: 获取job列表
     */
    getJobList() {
      $dataIntegration
        .getJobList({ pageNum: 1, pageSize: 1000000, queryParams: { F_isDel_eq: 0 } })
        .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: 获取数据源列表信息
     */
    getDbsDatas() {
      $dataIntegration
        .getDbsData()
        .then((req) => {
          this.metadatas.dataSource = req.data;
        })
        .finally(() => {});
    },
    /**
     * @Author: Jason Liu
     * @description: 获取DWS和ADS下的表格信息
     */
    getDwsAndAdsTables() {
      if (this.metadatas.dwsAndads.dbInfo.dbId) {
        if (!this.activeNode.data.dbId) {
          //初始化数据源数据
          let temp = this.metadatas.dwsAndads.dbInfo;
          this.activeNode.data = {
            ...this.activeNode.data,
            dbId: temp.dbId,
            dbName: temp.dbName,
            dbType: temp.dbType,
            schema: temp.schema,
          };
          this.updataNode();
        }
      } else {
        $dataIntegration
          .getDwsAndAdsTables()
          .then((req) => {
            debugger;
            this.metadatas.dwsAndads = req.data;
            this.getDwsAndAdsTables();
          })
          .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.jobNmae = req.data.jobNmae;
            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: 修改dws和ads模式事件
     */
    changeDwsAndAdsModelType() {
      this.activeNode.data = {
        ...this.activeNode.data,
        tableCode: undefined,
        tableId: undefined,
        tableName: undefined,
        eventTimeColumn: undefined,
        columns: [],
      };
      this.updataNode();
    },
    /**
     * @Author: Jason Liu
     * @description: 修改dws和ads的选择表格事件
     */
    changeDwsAndAdsTables() {
      this.activeNode.data.tableName = this.activeNode.data.tableCode;
      $dataIntegration.getDbsInfoColumns(this.activeNode.data).then((req) => {
        this.activeNode.data.columns = req.data || [];
        this.updataNode();
      });
    },
    /**
     * @Author: Jason Liu
     * @description: 获取选择的数据表信息
     */
    getDataTables(noset) {
      this.metadatas.dataTables = []; //清空原来的数据表信息
      $dataIntegration
        .getDataTableByDbs({
          dbId: this.activeNode.data.dbId,
          schemaCode: this.activeNode.data.schema,
        })
        .then((req) => {
          this.metadatas.dataTables = req.data; //数据表
        })
        .finally();
    },
    /**
     * @Author: Jason Liu
     * @description: 获取数据表列信息
     */
    getDataColumns(table, isReload) {
      $dataIntegration
        .getDataColumnsByTableId(table)
        .then((req) => {
          this.$set(
            this.activeNode.data,
            'tableColumns',
            req.data
              .sort((o, l) => {
                if (o.pk != l.pk) {
                  return o.pk ? -1 : 1;
                } else {
                  return o.columnName.localeCompare(l.columnName);
                }
              })
              .map((item) => {
                item.checked = true;
                item.asName = item.columnName;
                item.createAt = undefined;
                item.createBy = undefined;
                return item;
              }),
          );

          this.setDataColumns();
        })
        .finally();

      //var join = {
      //  name:undefined,
      //  tableId:undefined,
      //  tableName:undefined,//用户编辑->默认与name同步,当tableName修改后,则不在于name同步
      //  tableCode:undefined,//用户编辑
      //  columns:[
      //     {
      //         tableid:undefined,
      //         tableCode:undefined,
      //         asName:med_insti_no,//别名
      //         autoincrement: false
      //         columnAccuracy: 64
      //         columnName: "eeed", //物理字段名
      //         columnSize: 64
      //         columnType: "varchar"
      //         columnTypeFlink: "STRING"
      //         createAt: "2022-06-09 16:18:04"
      //         createBy: "超级管理员"
      //         description: "医疗机构代码"
      //         notNull: false
      //         pk: false
      //         releaseVersion: "V5"
      //     }
      // ],
      //   tables: [
      //     //关联表数组
      //     { tableid, tablenameA,  asName: "a", columns, isMain }, //isMain是否主表
      //     { tableid, tablenameB,  asName: "b", columns },
      //     { tableid, tablenameC,  asName: "c", columns },
      //   ],
      //   joins: [
      //     //join组
      //     {
      //       joinType: "join", //关联方式
      //       right: {
      //         //关联表
      //         tableid,
      //         tablenameB,
      //
      //       },
      //       condition: [
      //         //关联字段
      //         {
      //           type: "def", //通过关系的方式关联
      //           left: { tableid, tablenameA, columnA },
      //           relation: "=",
      //           right: { tableid, tablenameB, columnA },
      //         },
      //         {
      //           type: "def", //通过关系的方式关联
      //           left: { tableid, tablenameA, columnB },
      //           relation: "=",
      //           right: { tableid, tablenameB, columnC },
      //         },
      //         {
      //           type: "sql", //通过sql语句输入的方式关联,暂时不实现
      //           sql: "a.biz_role_id=b.biz_role_id",
      //         },
      //       ],
      //     },
      //     {
      //       joinType: "join",
      //       right: {
      //         tableid,
      //         tablenameC,
      //         asName: "",
      //       },
      //       condition: [
      //         {
      //           type: "def",
      //           left: { tableid, tablenameA, column },
      //           right: { tableid, tablenameC, column },
      //           relation: "=",
      //         },
      //         {
      //           type: "sql",
      //           sql: "a.biz_role_id=b.biz_role_id left",
      //         },
      //       ],
      //     },
      //   ],
      // };
    },
    setRowDataClass({ row, rowIndex }) {
      if (row.columnName) {
        if (row.columnName == this.activeNode.data.eventTimeColumn) {
          return 'row_warning';
        }
      } else if (row.source.columnName) {
        //设置了映射列的情况下
        if (row.source.columnType != row.target.columnType) {
          return 'row_warning';
        }
      }
      return '';
    },
    /**
     * @Author: Jason Liu
     * @description: 设置表输出映射字段
     */
    setTableOutMapping(row) {
      if (row.source.type == 'fun') {
        row.source = {
          type: row.source.type,
          select: undefined,
          columnName: row.source.columnName,
          tableAsName: undefined,
          description: undefined,
          asName: undefined,
          columnType: 'varchar',
        };
      } else if (row.source.select) {
        this.activeNode.data.inputTable.columns.forEach((item) => {
          if (`${item.tableAsName}.${item.columnName}` == row.source.select) {
            row.source = {
              select: row.source.select,
              ...item,
            };
          } else if (item.columnName == row.source.select) {
            row.source = {
              select: row.source.select,
              ...item,
            };
          }
        });
      } else {
        row.source = {
          type: row.source.type,
          select: undefined,
          columnName: undefined,
          tableAsName: undefined,
          description: undefined,
          asName: undefined,
          columnType: undefined,
        };
      }
      this.updataNode();
    },
    filterOption(input, option) {
      return (
        option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
      );
    },
    searchOutPutList() {
      const xTable = this.$refs.outputtable;

      const column = xTable.getColumnByField('target.columnName');
      // 修改第二个选项为勾选状态
      const option = column.filters[0];
      option.data = this.setOutTables.str;
      option.checked = !!this.setOutTables.str;

      const isNoll = xTable.getColumnByField('source.columnName').filters[0];
      isNoll.data = this.setOutTables.overlay;
      isNoll.checked = this.setOutTables.overlay;

      // 修改条件之后,需要手动调用 updateData 处理表格数据
      xTable.updateData();
    },
    /**
     * @Author: Jason Liu
     * @description: 查询设置
     */
    filterOutTableName({ option, row }) {
      return row.target.columnName.indexOf(option.data) > -1;
    },
    filterOutTableSource({ option, row }) {
      if (option.data) {
        return !row.source.columnName;
      } else {
        return true;
      }
    },
    /**
     * @Author: Jason Liu
     * @description: 获取配置的数据
     */
    getData() {
      return {
        //节点内容
        steps: this.graph.getNodes().map((node) => {
          let info = node.toJSON();
          info.component = undefined;
          info.ports.groups = undefined;
          return info;
        }),
        //连线关系
        hops: this.graph.getEdges().map((edge) => {
          let info = edge.toJSON();
          return info;
        }),
      };
    },
    /**
     * @Author: Jason Liu
     * @description: 设置配置数据
     */
    setData(
      data = {
        steps: [],
        hops: [],
      },
    ) {
      this.$nextTick(() => {
        const cells = [];

        data.steps.forEach((node) => {
          if (
            ['TableInput', 'TableOutput', 'PerlConfig', 'TableOutputSql'].indexOf(node.data.type) >
            -1
          ) {
            //兼容代码,将老数据的内容处理
            node.attrs = undefined;
          }
          node.component = undefined;
          let cell = {
            label: node.data.name,
            ...node,
          };
          cells.push(this.graph.createNode(cell));
        });
        data.hops.forEach((edge) => {
          cells.push(
            this.graph.createEdge({
              ...lineoption,
              ...edge,
            }),
          );
        });

        this.graph.resetCells(cells);
      });
    },
  },
  watch: {
    /**
     * @Author: Jason Liu
     * @description: 配置perl的参数
     */
    'setPerlConfig.show'(val) {
      if (val) {
        this.tool = '1';
        this.setPerlConfig.config = { ...this.activeNode.data.config };
      }
    },
  },
};