diff --git a/track-uniapp/src/pages/scan/components/TreeCanvas.vue b/track-uniapp/src/pages/scan/components/TreeCanvas.vue index 1e370c7..71e3f04 100644 --- a/track-uniapp/src/pages/scan/components/TreeCanvas.vue +++ b/track-uniapp/src/pages/scan/components/TreeCanvas.vue @@ -121,22 +121,22 @@ export default { allTasks.forEach(t => { if (isMainFn(t)) mains.push(t); }); mains.sort((a, b) => new Date(a.created_at) - new Date(b.created_at)); - // 🚀 预计算每个节点的子树总高度(兄弟累加,用于防重叠占位) + // 🚀 预计算每个节点的子树高度(兄弟累加取 max,首子与父平齐) const calcSubtreeHeight = (nodeId) => { const children = childMap[nodeId] || []; if (children.length === 0) return CARD_H + VERTICAL_GAP; const totalChildrenHeight = children.reduce((sum, c) => sum + calcSubtreeHeight(c.id), 0); - return CARD_H + VERTICAL_GAP + totalChildrenHeight; + return Math.max(CARD_H + VERTICAL_GAP, totalChildrenHeight); }; const nodes = []; - // 🚀 递归放置算法:childNode.y = parentNode.y + CARD_H + VERTICAL_GAP + // 🚀 递归放置算法:首个子节点与父节点水平平齐 // 同级子节点按 index 错开 Y 轴,各占其子树高度防止重叠 const placeChildren = (parentNode, currentSide) => { const children = childMap[parentNode.id] || []; - // 🚀 首个子节点 Y 起始:parent.y 正下方 - let startY = parentNode.y + CARD_H + VERTICAL_GAP; + // 🚀 首个子节点 Y 起始:与父节点水平平齐 + let startY = parentNode.y; children.forEach((child, index) => { const subtreeH = calcSubtreeHeight(child.id); @@ -152,7 +152,7 @@ export default { ? parentNode.x + CARD_W + GAP_X : parentNode.x - CARD_W - GAP_X; - // 🚀 Y 轴:严格基于父节点向下延伸,同级按 index 错开 + // 🚀 Y 轴:首子与父平齐,后续兄弟向下累加 const childY = startY; const childNode = { @@ -168,8 +168,8 @@ export default { // 递归放置孙子节点(沿相同方向) placeChildren(childNode, side); - // 🚀 下一个兄弟节点跳到当前子树高度之后,严禁 Y 坐标重叠 - startY += subtreeH + VERTICAL_GAP; + // 🚀 下一个兄弟节点跳到当前子树高度之后(calcSubtreeHeight 已含 GAP) + startY += subtreeH; }); }; @@ -194,7 +194,7 @@ export default { // ============================================================ // 🚀 连线计算:中央 → 分支 // ============================================================ - // 🔧 连线:卡片边缘到边缘,杜绝穿模 + // 🔧 连线:卡片边缘到边缘,动态追踪 Y 坐标,杜绝箭头悬空 lines() { const result = []; const flatMap = {}; @@ -206,10 +206,13 @@ export default { if (!parent) return; const isLeft = n.x < parent.x; const startX = isLeft ? n.x + 160 : parent.x + 160; - const endX = isLeft ? parent.x : n.x; + const endX = isLeft ? parent.x : n.x; + // 🚀 动态计算真实的 Y 坐标对接点 + const startY = isLeft ? n.y + 40 : parent.y + 40; + const endY = isLeft ? parent.y + 40 : n.y + 40; result.push({ - x1: startX, y1: parent.y + 40, - x2: endX, y2: parent.y + 40, + x1: startX, y1: startY, + x2: endX, y2: endY, dashed: parent.status === 'COMPLETED' || parent.status === 'ARCHIVED', }); });