From 5f228357d5a9b63d7d731918cfb99037bd3f4bb1 Mon Sep 17 00:00:00 2001 From: 666ghj <670939375@qq.com> Date: Tue, 16 Dec 2025 15:44:39 +0800 Subject: [PATCH] Refactor Step4Report component for enhanced workflow display and loading states - Removed section number display for a cleaner layout and improved user interaction. - Updated loading icon colors for better visibility and consistency. - Introduced a computed property for the active step to enhance workflow tracking. - Added utility functions to manage main section indexing and subsection identification. - Enhanced content rendering by removing redundant headings and improving markdown processing. - Updated agent log handling to ensure accurate section indexing and loading state management. - Improved panel header styling with status-based variants for better visual feedback. --- frontend/src/components/Step4Report.vue | 165 +++++++++++++++++++----- 1 file changed, 136 insertions(+), 29 deletions(-) diff --git a/frontend/src/components/Step4Report.vue b/frontend/src/components/Step4Report.vue index 24fcb89..b5d3c90 100644 --- a/frontend/src/components/Step4Report.vue +++ b/frontend/src/components/Step4Report.vue @@ -29,7 +29,6 @@ }" >
$2')
+ let html = processedContent.replace(/```(\w*)\n([\s\S]*?)```/g, '$2')
// 处理行内代码
html = html.replace(/`([^`]+)`/g, '$1')
@@ -1451,31 +1479,45 @@ const fetchAgentLog = async () => {
}
if (log.action === 'section_start') {
- currentSectionIndex.value = log.section_index
+ // 无论是主章节还是子章节开始,都映射到主章节索引
+ // 后端编号:主章节 1,2,3... 子章节 101,102(第1章子章节1,2)
+ const mainIndex = getMainSectionIndex(log.section_index)
+ currentSectionIndex.value = mainIndex
}
// section_content / subsection_content - 表示内容生成完成(但整个章节可能还没完成)
// 这里不更新 generatedSections,只记录进度
if (log.action === 'section_content' || log.action === 'subsection_content') {
- // 可以用于显示进度,但不更新左侧面板的内容
+ // 子章节内容生成时,保持主章节的 loading 状态
// 因为完整内容会在 section_complete 时一次性提供
}
// section_complete - 表示完整章节(含所有子章节)生成完成
// details.content 包含合并后的完整内容
+ // 注意:只有主章节 complete 时才更新内容,子章节 complete 不处理
if (log.action === 'section_complete') {
- if (log.details?.content) {
- generatedSections.value[log.section_index] = log.details.content
+ const mainIndex = getMainSectionIndex(log.section_index)
+ // 只有主章节完成时(section_index < 100)才更新内容和清除 loading
+ if (!isSubsection(log.section_index) && log.details?.content) {
+ generatedSections.value[mainIndex] = log.details.content
// 自动展开刚生成的章节
- expandedContent.value.add(log.section_index - 1)
+ expandedContent.value.add(mainIndex - 1)
+ currentSectionIndex.value = null
}
- currentSectionIndex.value = null
+ // 子章节完成时不清除 currentSectionIndex,继续显示 loading
}
if (log.action === 'report_complete') {
isComplete.value = true
+ currentSectionIndex.value = null // 确保清除 loading 状态
emit('update-status', 'completed')
stopPolling()
+ // 任务完成后,滚动右侧面板到顶部
+ nextTick(() => {
+ if (rightPanel.value) {
+ rightPanel.value.scrollTop = 0
+ }
+ })
}
if (log.action === 'report_start') {
@@ -1655,17 +1697,82 @@ watch(() => props.reportId, (newId) => {
z-index: 10;
}
-.panel-header svg {
- color: #6366F1;
+.header-dot {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background: #1F2937;
+ box-shadow: 0 0 0 3px rgba(31, 41, 55, 0.15);
+ margin-right: 10px;
+ flex-shrink: 0;
+ animation: pulse-dot 1.5s ease-in-out infinite;
}
-.log-count {
+@keyframes pulse-dot {
+ 0%, 100% {
+ box-shadow: 0 0 0 3px rgba(31, 41, 55, 0.15);
+ }
+ 50% {
+ box-shadow: 0 0 0 5px rgba(31, 41, 55, 0.1);
+ }
+}
+
+.header-index {
+ font-size: 12px;
+ font-weight: 600;
+ color: #9CA3AF;
+ margin-right: 10px;
+ flex-shrink: 0;
+}
+
+.header-title {
+ font-size: 13px;
+ font-weight: 600;
+ color: #374151;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ text-transform: none;
+ letter-spacing: 0;
+}
+
+.header-meta {
margin-left: auto;
- background: #EEF2FF;
- color: #4F46E5;
- padding: 2px 8px;
- border-radius: 10px;
- font-size: 11px;
+ font-size: 10px;
+ font-weight: 600;
+ color: #6B7280;
+ flex-shrink: 0;
+}
+
+/* Panel header status variants */
+.panel-header--active {
+ background: #FAFAFA;
+ border-color: #1F2937;
+}
+
+.panel-header--active .header-index {
+ color: #1F2937;
+}
+
+.panel-header--active .header-title {
+ color: #1F2937;
+}
+
+.panel-header--active .header-meta {
+ color: #1F2937;
+}
+
+.panel-header--done {
+ background: #F9FAFB;
+}
+
+.panel-header--done .header-index {
+ color: #10B981;
+}
+
+.panel-header--todo .header-index,
+.panel-header--todo .header-title {
+ color: #9CA3AF;
}
/* Left Panel - Report Style */
@@ -2033,10 +2140,10 @@ watch(() => props.reportId, (newId) => {
--wf-border: #E5E7EB;
--wf-divider: #F3F4F6;
- --wf-active-bg: #EFF6FF;
- --wf-active-border: #BFDBFE;
- --wf-active-dot: #3B82F6;
- --wf-active-text: #1D4ED8;
+ --wf-active-bg: #FAFAFA;
+ --wf-active-border: #1F2937;
+ --wf-active-dot: #1F2937;
+ --wf-active-text: #1F2937;
--wf-done-bg: #F9FAFB;
--wf-done-border: #E5E7EB;