w-vue-middle
Version:
统一公共服务组件
1,649 lines (1,604 loc) • 72.3 kB
JavaScript
/*
* @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('@/api/dataIntegration');
/**
* @Author: Jason Liu
* @description: 调度服务接口
*/
const $dispatchcenter = require('@/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('@/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) {
//找到映射的数据源