Files
auto-solution/modeler/src/views/decision/communication/relation.ts
2026-03-27 00:08:48 +08:00

135 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* This file is part of the kernelstudio package.
*
* (c) 2014-2026 zlin <admin@kernelstudio.com>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/
import { Edge, Graph, Node } from '@antv/x6';
import type { PlatformRelation } from './types';
import type { Platform, PlatformComponent } from '../types';
import type { GraphTaskElement } from '../graph';
/**
* 解析节点端口连接关系(去重版)
* @param graph X6 画布实例
* @returns 去重后的端口连接关系列表
*/
export function resolveConnectionRelation(graph: Graph): PlatformRelation[] {
const edges: Edge[] = graph.getEdges();
const items: PlatformRelation[] = [];
const existsKeys: Set<string> = new Set(); // 改用 Set 提升查询性能
const tempEdgeIds: Set<string> = new Set(); // 存储临时边 ID
// 过滤无效/临时边
const validEdges = edges.filter(edge => {
// 过滤临时边X6 拖拽连线时生成的未完成边)
const isTempEdge = edge?.attr('line/stroke') === 'transparent' || edge.id.includes('temp');
if (isTempEdge) {
tempEdgeIds.add(edge.id);
return false;
}
// 过滤未正确关联节点的边
const sourceCell = edge.getSourceCell();
const targetCell = edge.getTargetCell();
if (!sourceCell || !targetCell || !(sourceCell instanceof Node) || !(targetCell instanceof Node)) {
return false;
}
// 过滤端口 ID 为空的边
const sourcePortId = edge.getSourcePortId();
const targetPortId = edge.getTargetPortId();
if (!sourcePortId || !targetPortId) {
return false;
}
return true;
});
validEdges.forEach(edge => {
try {
const sourceCell = edge.getSourceCell() as Node;
const targetCell = edge.getTargetCell() as Node;
const sourcePortId = edge.getSourcePortId()!;
const targetPortId = edge.getTargetPortId()!;
// 1. 获取端口 DOM 元素和数据
const sourceView = graph.findViewByCell(sourceCell);
const targetView = graph.findViewByCell(targetCell);
if (!sourceView || !targetView) return;
const sourcePortEl = sourceView.container.querySelector(`[data-port="${sourcePortId}"]`);
const targetPortEl = targetView.container.querySelector(`[data-port="${targetPortId}"]`);
if (!sourcePortEl || !targetPortEl) return;
// 2. 解析端口数据
let sourcePortData: PlatformComponent | null = null;
let targetPortData: PlatformComponent | null = null;
try {
const sourceDataAttr = sourcePortEl.getAttribute('data-item');
sourcePortData = sourceDataAttr ? JSON.parse(sourceDataAttr) : null;
} catch (e) {
console.warn(`解析源节点 ${sourceCell.id} 端口 ${sourcePortId} 数据失败`, e);
return; // 数据解析失败直接跳过
}
try {
const targetDataAttr = targetPortEl.getAttribute('data-item');
targetPortData = targetDataAttr ? JSON.parse(targetDataAttr) : null;
} catch (e) {
console.warn(`解析目标节点 ${targetCell.id} 端口 ${targetPortId} 数据失败`, e);
return; // 数据解析失败直接跳过
}
// 过滤端口数据为空的情况
if (!sourcePortData || !targetPortData) return;
// 解析节点平台数据
const sourceData = sourceCell.getData() as GraphTaskElement;
const targetData = targetCell.getData() as GraphTaskElement;
// 过滤平台数据不完整的节点
if (!sourceData.platformId || !targetData.platformId) return;
const sourcePlatform: Platform = {
id: sourceData.platformId as number,
key: sourceData.key,
name: sourceData.name,
description: sourceData.description,
scenarioId: sourceData.scenarioId as number,
};
const targetPlatform: Platform = {
id: targetData.platformId as number,
key: targetData.key,
name: targetData.name,
description: targetData.description,
scenarioId: targetData.scenarioId as number,
};
// 生成唯一标识(支持单向/双向去重
const uniqueKey = `${sourceCell.id}@${sourcePortId}->${targetCell.id}@${targetPortId}`;
if (!existsKeys.has(uniqueKey)) {
existsKeys.add(uniqueKey);
items.push({
sourceId: sourceCell.id,
sourcePort: sourcePortId,
sourcePlatform: sourcePlatform,
sourceComponent: sourcePortData,
targetId: targetCell.id,
targetPort: targetPortId,
targetPlatform: targetPlatform,
targetComponent: targetPortData,
edgeId: edge.id,
});
}
} catch (error) {
console.error(`解析边 ${edge.id} 连接关系失败`, error);
}
});
return items;
}