From 1e413c592d0bf1d65c1516ab9dba54724c010d74 Mon Sep 17 00:00:00 2001 From: python395118 Date: Fri, 17 Apr 2026 16:56:36 +0800 Subject: [PATCH 1/3] =?UTF-8?q?-=20ui:=20TensionChart=20ResizeObserver=20?= =?UTF-8?q?=E5=88=B7=E7=BA=BFBUG=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/autopilot/TensionChart.vue | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/frontend/src/components/autopilot/TensionChart.vue b/frontend/src/components/autopilot/TensionChart.vue index 582c2c226..2bad3d126 100644 --- a/frontend/src/components/autopilot/TensionChart.vue +++ b/frontend/src/components/autopilot/TensionChart.vue @@ -80,6 +80,7 @@ const loading = ref(false) const error = ref(null) let chartInstance: ECharts | null = null +let resizeObserver: ResizeObserver | null = null // 张力警戒线 const tensionThreshold = computed(() => props.threshold ?? 5.0) @@ -152,6 +153,13 @@ function renderChart() { if (!chartInstance) { chartInstance = init(chartRef.value) + // 在 chartRef 确保存在后才初始化 ResizeObserver(解决 onMounted 时 chartRef 为 null 的问题) + if (!resizeObserver) { + resizeObserver = new ResizeObserver(() => { + chartInstance?.resize() + }) + resizeObserver.observe(chartRef.value) + } } const chapterNumbers = tensionData.value.map((d) => d.chapter_number) @@ -319,6 +327,12 @@ onMounted(() => { onUnmounted(() => { window.removeEventListener('resize', handleResize) if (resizeTimer) clearTimeout(resizeTimer) + // 清理 ResizeObserver + if (resizeObserver) { + resizeObserver.disconnect() + resizeObserver = null + } + // 显式 dispose 旧实例(Vue+ECharts 组件刷新必需) chartInstance?.dispose() chartInstance = null }) From 61084925f30fb135acf6f98a20f065a7bac1e3c1 Mon Sep 17 00:00:00 2001 From: python395118 Date: Fri, 17 Apr 2026 18:04:51 +0800 Subject: [PATCH 2/3] =?UTF-8?q?Revert=20"-=20ui:=20TensionChart=20ResizeOb?= =?UTF-8?q?server=20=E5=88=B7=E7=BA=BFBUG=E4=BF=AE=E5=A4=8D"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 1e413c592d0bf1d65c1516ab9dba54724c010d74. --- frontend/src/components/autopilot/TensionChart.vue | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/frontend/src/components/autopilot/TensionChart.vue b/frontend/src/components/autopilot/TensionChart.vue index 2bad3d126..582c2c226 100644 --- a/frontend/src/components/autopilot/TensionChart.vue +++ b/frontend/src/components/autopilot/TensionChart.vue @@ -80,7 +80,6 @@ const loading = ref(false) const error = ref(null) let chartInstance: ECharts | null = null -let resizeObserver: ResizeObserver | null = null // 张力警戒线 const tensionThreshold = computed(() => props.threshold ?? 5.0) @@ -153,13 +152,6 @@ function renderChart() { if (!chartInstance) { chartInstance = init(chartRef.value) - // 在 chartRef 确保存在后才初始化 ResizeObserver(解决 onMounted 时 chartRef 为 null 的问题) - if (!resizeObserver) { - resizeObserver = new ResizeObserver(() => { - chartInstance?.resize() - }) - resizeObserver.observe(chartRef.value) - } } const chapterNumbers = tensionData.value.map((d) => d.chapter_number) @@ -327,12 +319,6 @@ onMounted(() => { onUnmounted(() => { window.removeEventListener('resize', handleResize) if (resizeTimer) clearTimeout(resizeTimer) - // 清理 ResizeObserver - if (resizeObserver) { - resizeObserver.disconnect() - resizeObserver = null - } - // 显式 dispose 旧实例(Vue+ECharts 组件刷新必需) chartInstance?.dispose() chartInstance = null }) From 7b5cd1dfd065e76d87c85c5c8df93536c1501479 Mon Sep 17 00:00:00 2001 From: python395118 Date: Fri, 17 Apr 2026 19:46:35 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat(ui):=20=E5=B7=A5=E4=BD=9C=E5=8F=B0?= =?UTF-8?q?=E9=9D=A2=E6=9D=BF=E6=8B=96=E6=8B=BD=E6=8A=98=E5=8F=A0=E4=B8=8E?= =?UTF-8?q?=E9=9D=A2=E6=9D=BF=E6=A0=87=E9=A2=98=E5=B8=83=E5=B1=80=E7=BB=9F?= =?UTF-8?q?=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 工作台左右面板支持拖拽调整宽度与折叠/展开 - 中间内容区滚动条默认隐藏,悬停时显示 - 故事结构树窄屏时隐藏节点后缀 - 统一各面板标题行布局(标题+标签+按钮同行) - 监控网格张力图表与实时日志高度一致 - 张力心电图刷新后重新初始化,新增 ResizeObserver 自适应 - 关系图工具栏按钮防换行布局 - 修复 Naive UI 按钮属性冲突(dashed/secondary) --- .../src/components/StoryStructureTree.vue | 117 ++++++-- .../autopilot/AutopilotDashboard.vue | 27 +- .../components/autopilot/AutopilotPanel.vue | 3 +- .../autopilot/RealtimeLogStream.vue | 17 +- .../src/components/autopilot/TensionChart.vue | 56 +++- .../components/graphs/CastGraphCompact.vue | 8 +- .../graphs/LocationGraphCompact.vue | 8 +- .../components/knowledge/KnowledgePanel.vue | 47 +++- frontend/src/components/panels/BiblePanel.vue | 140 +++++----- .../workbench/ForeshadowLedgerPanel.vue | 39 ++- .../workbench/HolographicChroniclesPanel.vue | 32 ++- .../src/components/workbench/WorkArea.vue | 53 +++- frontend/src/views/Workbench.vue | 257 ++++++++++++++---- 13 files changed, 572 insertions(+), 232 deletions(-) diff --git a/frontend/src/components/StoryStructureTree.vue b/frontend/src/components/StoryStructureTree.vue index 4eac2d124..804fb3b88 100644 --- a/frontend/src/components/StoryStructureTree.vue +++ b/frontend/src/components/StoryStructureTree.vue @@ -80,7 +80,7 @@ @@ -484,17 +549,25 @@ defineExpose({ loadTree }) .node-label { display: flex; align-items: center; - gap: 8px; + gap: 6px; } -.node-icon { font-size: 16px; } -.node-title { font-size: 13px; } +.node-icon { font-size: 16px; width: 18px; text-align: center; } +.node-title { font-size: 14px; } .node-range { - font-size: 12px; + font-size: 11px; color: #999; - margin-left: 8px; + margin-left: 6px; } .node-level-1 { font-weight: 600; } .node-level-2 { font-weight: 500; } .node-level-3 { font-weight: normal; } .node-level-4 { font-weight: normal; font-size: 13px; } + +/* 紧凑布局 */ +:deep(.n-tree-node-content) { + padding: 2px 0; +} +:deep(.n-tree-node-wrapper) { + padding: 1px 0; +} diff --git a/frontend/src/components/autopilot/AutopilotDashboard.vue b/frontend/src/components/autopilot/AutopilotDashboard.vue index fdc57a93c..ffc8d7f2f 100644 --- a/frontend/src/components/autopilot/AutopilotDashboard.vue +++ b/frontend/src/components/autopilot/AutopilotDashboard.vue @@ -1,10 +1,5 @@