UNPKG

w-vue-middle

Version:

统一公共服务组件

1,793 lines (1,740 loc) 70.1 kB
/* * @Author: Jason Liu * @Date: 2022-08-03 13:13:03 * @Desc: */ const { Graph, Shape, Addon, Registry } = require('@antv/x6'); const { lineoption, controlsList } = require('@/components/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 LakeOutputOptoin = require('./components/LakeOutputOptoin').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 kafaInputsOptoin = require('./components/kafaInputsOptoin').default; let runTestTime; export default { name: 'jobDesigner', components: { esOutputOptoin, sqlInputOptoin, tableInputOptoin, messagesOptoin, tableOutputOptoin, tableMigrateOptoin, tableJoinOptoin, kafaInputOptoin, kafaInputsOptoin, LakeOutputOptoin, }, 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: [], //集群列表 debugClusters: [], //测试集群列表 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 mouseType: 'active', //鼠标类型 }; }, created() { // this.getGroupList(); // this.geiClustersList(); // if (this.jobType == 'flow') { // this.getFlowGroups(); // } else { // this.getParentList(); // } }, 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设置 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; }); 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(); }); // 控制连接桩显示/隐藏 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:click', ({ e, x, y, node, view }) => { const container = this.$refs[_this.id][0]; const ports = container.querySelectorAll('.x6-port-body'); showPorts(ports, true); if (this.loading && this.mouseType != 'active') { 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 }) => { 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(); }); _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: false, //缩放节点 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, }); if (job.jsonDetailBak) { this.hasSqlInput = true; } else { this.hasSqlInput = false; } 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, clusterType: item.clusterType, }; }); }); }, changeClusterType(val) { if (!val) { this.debugClusters = this.clusters; } else { this.debugClusters = this.clusters.filter((item) => { return item.clusterType == this.debuggerProcess.clusterType; }); } this.debuggerProcess.clusterId = this.debugClusters.length > 0 ? this.debugClusters[0].value : undefined; }, /** * @Author: Jason Liu * @description: 启动流程调试 */ runProcessTest() { //this.logList = []; let clusterId = undefined; let clusterType = undefined; this.$refs.setBody.$el.style.height = 'calc(100% - 220px)'; if (this.clusters.length > 0) { clusterType = 1; this.debugClusters = this.clusters.filter((item) => { return item.clusterType == 1; }); clusterId = this.debugClusters.length > 0 ? this.debugClusters[0].value : undefined; } this.debuggerProcess = { //流程调试 show: true, putaway: false, limit: 100, clusterType: clusterType, 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; 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]}`, }); } } } }); 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.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 && 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, j