修复: 删除2D连线+spawn确认parent_task_id已正确+WBS算法重写(递归前缀)
This commit is contained in:
@ -17,9 +17,6 @@
|
|||||||
:style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"
|
:style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"
|
||||||
>
|
>
|
||||||
<view class="canvas-inner">
|
<view class="canvas-inner">
|
||||||
<!-- 连线层 -->
|
|
||||||
<view v-for="line in treeLines" :key="line.key" class="canvas-line" :style="lineStyle(line)"></view>
|
|
||||||
|
|
||||||
<!-- 节点卡片层 -->
|
<!-- 节点卡片层 -->
|
||||||
<view v-for="node in treeNodes" :key="node.id"
|
<view v-for="node in treeNodes" :key="node.id"
|
||||||
class="canvas-node" :class="statusColor(node.status)"
|
class="canvas-node" :class="statusColor(node.status)"
|
||||||
@ -62,7 +59,6 @@ export default {
|
|||||||
|
|
||||||
const CARD_W = 320, CARD_H = 460, GAP_X = 80, GAP_Y = 120;
|
const CARD_W = 320, CARD_H = 460, GAP_X = 80, GAP_Y = 120;
|
||||||
const nodes = [];
|
const nodes = [];
|
||||||
nodes._lines = [];
|
|
||||||
|
|
||||||
// 按行组织:每行是一个 { y, tasks: [...] }
|
// 按行组织:每行是一个 { y, tasks: [...] }
|
||||||
const rows = [];
|
const rows = [];
|
||||||
@ -80,18 +76,6 @@ export default {
|
|||||||
const node = { ...t, x, y: 0, _rowIdx: rowIdx, _xEnd: x + CARD_W };
|
const node = { ...t, x, y: 0, _rowIdx: rowIdx, _xEnd: x + CARD_W };
|
||||||
row.tasks.push(node);
|
row.tasks.push(node);
|
||||||
nodes.push(node);
|
nodes.push(node);
|
||||||
|
|
||||||
// 连线到父节点
|
|
||||||
if (t.parent_task_id) {
|
|
||||||
const parent = nodes.find(n => n.id === t.parent_task_id);
|
|
||||||
if (parent) {
|
|
||||||
nodes._lines.push({
|
|
||||||
key: parent.id + '-' + t.id,
|
|
||||||
x1: parent.x + CARD_W / 2, y1: parent.y + CARD_H,
|
|
||||||
x2: node.x + CARD_W / 2, y2: node.y,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 递归子任务
|
// 递归子任务
|
||||||
@ -122,7 +106,6 @@ export default {
|
|||||||
if (this.product) walk(this.product.task_tree);
|
if (this.product) walk(this.product.task_tree);
|
||||||
return map;
|
return map;
|
||||||
},
|
},
|
||||||
treeLines() { return this.treeNodes._lines || []; },
|
|
||||||
canvasWidth() { if (!this.treeNodes.length) return 400; return Math.max(800, Math.max(...this.treeNodes.map(n => n.x)) + 300); },
|
canvasWidth() { if (!this.treeNodes.length) return 400; return Math.max(800, Math.max(...this.treeNodes.map(n => n.x)) + 300); },
|
||||||
canvasHeight() { if (!this.treeNodes.length) return 400; return Math.max(800, Math.max(...this.treeNodes.map(n => n.y)) + 300); }
|
canvasHeight() { if (!this.treeNodes.length) return 400; return Math.max(800, Math.max(...this.treeNodes.map(n => n.y)) + 300); }
|
||||||
},
|
},
|
||||||
|
|||||||
@ -130,17 +130,20 @@ export default {
|
|||||||
lockedTask() { return this.focusTasks.find(t => t.id === this.lockedTaskId) || null; },
|
lockedTask() { return this.focusTasks.find(t => t.id === this.lockedTaskId) || null; },
|
||||||
branchLabelsMap() {
|
branchLabelsMap() {
|
||||||
const map = {};
|
const map = {};
|
||||||
const walk = (tasks, prefix, idx) => {
|
if (!this.product || !this.product.task_tree) return map;
|
||||||
|
const traverse = (tasks, prefix) => {
|
||||||
if (!tasks) return;
|
if (!tasks) return;
|
||||||
tasks.forEach((t, i) => {
|
tasks.forEach((t, i) => {
|
||||||
const label = prefix === '' ? '主分支' : `${prefix}${i + 1}`;
|
if (prefix === '') {
|
||||||
map[t.id] = label;
|
map[t.id] = '主分支';
|
||||||
if (t.child_tasks && t.child_tasks.length) {
|
} else {
|
||||||
walk(t.child_tasks, prefix === '' ? '' : `${label}.`, i);
|
map[t.id] = `分支 ${prefix}${i + 1}`;
|
||||||
}
|
}
|
||||||
|
const nextPrefix = prefix === '' ? `${i + 1}.` : `${prefix}${i + 1}.`;
|
||||||
|
traverse(t.child_tasks, nextPrefix);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
if (this.product) walk(this.product.task_tree, '', 0);
|
traverse(this.product.task_tree, '');
|
||||||
return map;
|
return map;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user