|
|
@@ -1091,13 +1091,26 @@ function transformData(data) {
|
|
|
}
|
|
|
|
|
|
function FlowContent() {
|
|
|
+ // 画布使用简化数据
|
|
|
const { nodes: initialNodes, edges: initialEdges } = useMemo(() => {
|
|
|
- console.log('🔍 Transforming data...');
|
|
|
+ console.log('🔍 Transforming data for canvas...');
|
|
|
const result = transformData(data);
|
|
|
- console.log('✅ Transformed:', result.nodes.length, 'nodes,', result.edges.length, 'edges');
|
|
|
+ console.log('✅ Canvas data:', result.nodes.length, 'nodes,', result.edges.length, 'edges');
|
|
|
return result;
|
|
|
}, []);
|
|
|
|
|
|
+ // 目录使用完整数据(如果存在)
|
|
|
+ const { nodes: fullNodes, edges: fullEdges } = useMemo(() => {
|
|
|
+ if (data.fullData) {
|
|
|
+ console.log('🔍 Transforming full data for tree directory...');
|
|
|
+ const result = transformData(data.fullData);
|
|
|
+ console.log('✅ Directory data:', result.nodes.length, 'nodes,', result.edges.length, 'edges');
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ // 如果没有 fullData,使用简化数据
|
|
|
+ return { nodes: initialNodes, edges: initialEdges };
|
|
|
+ }, [initialNodes, initialEdges]);
|
|
|
+
|
|
|
// 初始化:找出所有有子节点的节点,默认折叠(画布节点)
|
|
|
const initialCollapsedNodes = useMemo(() => {
|
|
|
const nodesWithChildren = new Set();
|
|
|
@@ -1328,9 +1341,11 @@ function FlowContent() {
|
|
|
}, [initialNodes, initialEdges, collapsedNodes, hiddenNodes, focusMode, focusedNodeId, getDescendants, toggleNodeCollapse, selectedNodeId]);
|
|
|
|
|
|
// 构建树形结构 - 允许一个节点有多个父节点
|
|
|
+ // 为目录构建树(使用完整数据)
|
|
|
const buildTree = useCallback(() => {
|
|
|
+ // 使用完整数据构建目录树
|
|
|
const nodeMap = new Map();
|
|
|
- initialNodes.forEach(node => {
|
|
|
+ fullNodes.forEach(node => {
|
|
|
nodeMap.set(node.id, node);
|
|
|
});
|
|
|
|
|
|
@@ -1350,7 +1365,7 @@ function FlowContent() {
|
|
|
const parentToChildren = new Map();
|
|
|
const childToParents = new Map();
|
|
|
|
|
|
- initialEdges.forEach(edge => {
|
|
|
+ fullEdges.forEach(edge => {
|
|
|
// 记录父->子关系(去重:同一个父节点到同一个子节点只记录一次)
|
|
|
if (!parentToChildren.has(edge.source)) {
|
|
|
parentToChildren.set(edge.source, []);
|
|
|
@@ -1393,12 +1408,12 @@ function FlowContent() {
|
|
|
|
|
|
// 找出所有根节点(没有入边的节点)
|
|
|
const hasParent = new Set();
|
|
|
- initialEdges.forEach(edge => {
|
|
|
+ fullEdges.forEach(edge => {
|
|
|
hasParent.add(edge.target);
|
|
|
});
|
|
|
|
|
|
const roots = [];
|
|
|
- initialNodes.forEach((node, index) => {
|
|
|
+ fullNodes.forEach((node, index) => {
|
|
|
if (!hasParent.has(node.id)) {
|
|
|
const treeNode = buildSubtree(node.id, 'root-' + node.id + '-' + index, new Set());
|
|
|
if (treeNode) roots.push(treeNode);
|
|
|
@@ -1406,11 +1421,11 @@ function FlowContent() {
|
|
|
});
|
|
|
|
|
|
return roots;
|
|
|
- }, [initialNodes, initialEdges]);
|
|
|
+ }, [fullNodes, fullEdges]);
|
|
|
|
|
|
const treeRoots = useMemo(() => buildTree(), [buildTree]);
|
|
|
|
|
|
- // 生成树形文本结构
|
|
|
+ // 生成树形文本结构(使用完整数据)
|
|
|
const generateTreeText = useCallback(() => {
|
|
|
const lines = [];
|
|
|
|
|
|
@@ -1418,7 +1433,7 @@ function FlowContent() {
|
|
|
const traverse = (nodes, prefix = '', isLast = true, depth = 0) => {
|
|
|
nodes.forEach((node, index) => {
|
|
|
const isLastNode = index === nodes.length - 1;
|
|
|
- const nodeData = initialNodes.find(n => n.id === node.id)?.data || {};
|
|
|
+ const nodeData = fullNodes.find(n => n.id === node.id)?.data || {};
|
|
|
const nodeType = nodeData.nodeType || node.data?.nodeType || 'unknown';
|
|
|
const title = nodeData.title || node.data?.title || node.id;
|
|
|
|
|
|
@@ -1457,7 +1472,7 @@ function FlowContent() {
|
|
|
};
|
|
|
|
|
|
// 添加标题
|
|
|
- const rootNode = initialNodes.find(n => n.data?.level === 0);
|
|
|
+ const rootNode = fullNodes.find(n => n.data?.level === 0);
|
|
|
if (rootNode) {
|
|
|
lines.push(\`📊 查询扩展树形结构\`);
|
|
|
lines.push(\`原始问题: \${rootNode.data.title || rootNode.data.query}\`);
|
|
|
@@ -1467,7 +1482,7 @@ function FlowContent() {
|
|
|
traverse(treeRoots);
|
|
|
|
|
|
return lines.join('\\n');
|
|
|
- }, [treeRoots, initialNodes]);
|
|
|
+ }, [treeRoots, fullNodes]);
|
|
|
|
|
|
// 复制树形结构到剪贴板
|
|
|
const copyTreeToClipboard = useCallback(async () => {
|
|
|
@@ -1501,6 +1516,44 @@ function FlowContent() {
|
|
|
setCollapsedTreeNodes(getAllTreeKeys(treeRoots));
|
|
|
}, [treeRoots]);
|
|
|
|
|
|
+ // 映射完整节点ID到画布简化节点ID
|
|
|
+ const mapTreeNodeToCanvasNode = useCallback((treeNodeId) => {
|
|
|
+ // 如果是简化模式,需要映射
|
|
|
+ if (data.fullData) {
|
|
|
+ // 从完整数据中找到节点
|
|
|
+ const fullNode = fullNodes.find(n => n.id === treeNodeId);
|
|
|
+ if (!fullNode) return treeNodeId;
|
|
|
+
|
|
|
+ // 根据节点类型和文本找到画布上的简化节点
|
|
|
+ const nodeText = fullNode.data.title || fullNode.data.query;
|
|
|
+ const nodeType = fullNode.data.nodeType || fullNode.type;
|
|
|
+
|
|
|
+ // Query类节点:找 query_xxx
|
|
|
+ if (['q', 'seg', 'sug', 'add_word', 'query'].includes(nodeType)) {
|
|
|
+ const canvasNode = initialNodes.find(n =>
|
|
|
+ (n.data.title === nodeText || n.data.query === nodeText) &&
|
|
|
+ ['query'].includes(n.type)
|
|
|
+ );
|
|
|
+ return canvasNode ? canvasNode.id : treeNodeId;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Post节点:按note_id查找
|
|
|
+ if (nodeType === 'post' || nodeType === 'note') {
|
|
|
+ const noteId = fullNode.data.note_id;
|
|
|
+ if (noteId) {
|
|
|
+ const canvasNode = initialNodes.find(n => n.data.note_id === noteId);
|
|
|
+ return canvasNode ? canvasNode.id : treeNodeId;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 其他节点类型(Round/Step等):直接返回
|
|
|
+ return treeNodeId;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 非简化模式,直接返回
|
|
|
+ return treeNodeId;
|
|
|
+ }, [data.fullData, fullNodes, initialNodes]);
|
|
|
+
|
|
|
const renderTree = useCallback((treeNodes, level = 0) => {
|
|
|
return treeNodes.map(node => {
|
|
|
// 使用 treeKey 来区分树中的不同实例
|
|
|
@@ -1526,7 +1579,18 @@ function FlowContent() {
|
|
|
});
|
|
|
}}
|
|
|
onSelect={() => {
|
|
|
- const nodeId = node.id;
|
|
|
+ // 将目录节点ID映射到画布节点ID
|
|
|
+ const treeNodeId = node.id;
|
|
|
+ const canvasNodeId = mapTreeNodeToCanvasNode(treeNodeId);
|
|
|
+
|
|
|
+ // 检查画布上是否存在这个节点
|
|
|
+ const canvasNodeExists = initialNodes.some(n => n.id === canvasNodeId);
|
|
|
+ if (!canvasNodeExists) {
|
|
|
+ console.warn(\`节点 \${canvasNodeId} 在画布上不存在(可能被简化了)\`);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const nodeId = canvasNodeId;
|
|
|
|
|
|
// 展开所有祖先节点
|
|
|
const ancestorIds = [nodeId];
|
|
|
@@ -1582,7 +1646,7 @@ function FlowContent() {
|
|
|
</TreeNode>
|
|
|
);
|
|
|
});
|
|
|
- }, [collapsedTreeNodes, selectedNodeId, nodes, setCenter, initialEdges, setCollapsedNodes, fitView]);
|
|
|
+ }, [collapsedTreeNodes, selectedNodeId, nodes, setCenter, initialEdges, setCollapsedNodes, fitView, mapTreeNodeToCanvasNode, initialNodes, setHiddenNodes]);
|
|
|
|
|
|
console.log('📊 Rendering with', nodes.length, 'visible nodes and', edges.length, 'visible edges');
|
|
|
|