diff --git a/frontend/src/components/ChapterAnalysis.tsx b/frontend/src/components/ChapterAnalysis.tsx index 4cee0a5..37faa60 100644 --- a/frontend/src/components/ChapterAnalysis.tsx +++ b/frontend/src/components/ChapterAnalysis.tsx @@ -1,5 +1,5 @@ import { useState, useEffect } from 'react'; -import { Modal, Progress, Spin, Alert, Tabs, Card, Tag, List, Empty, Statistic, Row, Col, Button } from 'antd'; +import { Modal, Spin, Alert, Tabs, Card, Tag, List, Empty, Statistic, Row, Col, Button } from 'antd'; import { ThunderboltOutlined, BulbOutlined, @@ -192,28 +192,112 @@ export default function ChapterAnalysis({ chapterId, visible, onClose }: Chapter if (!task || task.status === 'completed') return null; return ( -
-
+
+ {/* 标题和图标 */} +
{renderStatusIcon()} - +
{task.status === 'pending' && '等待分析...'} {task.status === 'running' && 'AI正在分析中...'} {task.status === 'failed' && '分析失败'} - +
- + + {/* 进度条 */} +
+
+
0 && task.status !== 'failed' + ? '0 0 10px rgba(24, 144, 255, 0.3)' + : 'none' + }} /> +
+ + {/* 进度百分比 */} +
+ {task.progress}% +
+
+ + {/* 状态消息 */} +
+ {task.status === 'pending' && '分析任务已创建,正在队列中...'} + {task.status === 'running' && '正在提取关键信息和记忆片段...'} +
+ + {/* 错误信息 */} {task.status === 'failed' && task.error_message && ( - )} + + {/* 提示文字 */} + {task.status !== 'failed' && ( +
+ 分析过程需要一定时间,请耐心等待 +
+ )}
); }; @@ -646,9 +730,28 @@ export default function ChapterAnalysis({ chapterId, visible, onClose }: Chapter originalContent={chapterInfo.content} newContent={newGeneratedContent} wordCount={newContentWordCount} - onApply={() => { - // 应用新内容后刷新章节信息 - fetchAnalysisStatus(); + onApply={async () => { + // 应用新内容后刷新章节信息和分析 + setChapterInfo(null); + setAnalysis(null); + + // 重新加载章节内容 + try { + const chapterResponse = await fetch(`/api/chapters/${chapterId}`); + if (chapterResponse.ok) { + const chapterData = await chapterResponse.json(); + setChapterInfo({ + title: chapterData.title, + chapter_number: chapterData.chapter_number, + content: chapterData.content || '' + }); + } + } catch (error) { + console.error('重新加载章节失败:', error); + } + + // 刷新分析状态 + await fetchAnalysisStatus(); }} onDiscard={() => { // 放弃新内容,清空状态 diff --git a/frontend/src/components/ChapterContentComparison.tsx b/frontend/src/components/ChapterContentComparison.tsx index e043053..501ebaa 100644 --- a/frontend/src/components/ChapterContentComparison.tsx +++ b/frontend/src/components/ChapterContentComparison.tsx @@ -50,28 +50,32 @@ const ChapterContentComparison: React.FC = ({ throw new Error('应用新内容失败'); } - message.success('新内容已应用!正在触发章节分析...'); + message.success('新内容已应用!'); - // 触发章节分析 - try { - const analysisResponse = await fetch(`/api/chapters/${chapterId}/analyze`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - } - }); + // 先调用 onApply 通知父组件刷新 + onApply(); + + // 延迟触发章节分析,给父组件时间刷新 + setTimeout(async () => { + try { + const analysisResponse = await fetch(`/api/chapters/${chapterId}/analyze`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + } + }); - if (analysisResponse.ok) { - message.success('章节分析已开始,请稍后查看结果'); - } else { + if (analysisResponse.ok) { + message.success('章节分析已开始,请稍后查看结果'); + } else { + message.warning('章节分析触发失败,您可以手动触发分析'); + } + } catch (analysisError) { + console.error('触发分析失败:', analysisError); message.warning('章节分析触发失败,您可以手动触发分析'); } - } catch (analysisError) { - console.error('触发分析失败:', analysisError); - message.warning('章节分析触发失败,您可以手动触发分析'); - } + }, 500); - onApply(); onClose(); } catch (error: any) { message.error(error.message || '应用失败'); diff --git a/frontend/src/pages/Chapters.tsx b/frontend/src/pages/Chapters.tsx index dcc74e8..676749d 100644 --- a/frontend/src/pages/Chapters.tsx +++ b/frontend/src/pages/Chapters.tsx @@ -1358,6 +1358,20 @@ export default function Chapters() { onClose={() => { setAnalysisVisible(false); + // 刷新章节列表以显示最新内容 + refreshChapters(); + + // 刷新项目信息以更新字数统计 + if (currentProject) { + projectApi.getProject(currentProject.id) + .then(updatedProject => { + setCurrentProject(updatedProject); + }) + .catch(error => { + console.error('刷新项目信息失败:', error); + }); + } + // 延迟500ms后刷新该章节的分析状态,给后端足够时间完成数据库写入 if (analysisChapterId) { const chapterIdToRefresh = analysisChapterId;