"use client"; import { useEffect, useState } from "react"; import type { OptimizedArticle } from "../lib/domain/types"; interface OptimizedPreviewProps { article: OptimizedArticle | null; draftArticle?: OptimizedArticle | null; jobId: string | null; isStreaming?: boolean; activityText?: string; } const exportFiles = ["optimized.md", "optimized.docx", "qa_report.json"]; const streamWords = ["事实", "标题", "结构", "语气", "检索", "改写", "终稿"]; export function OptimizedPreview({ article, draftArticle = null, jobId, isStreaming = false, activityText = "", }: OptimizedPreviewProps) { const [streamTick, setStreamTick] = useState(0); const visibleArticle = article ?? draftArticle; const visibleWordCount = isStreaming ? Math.min(streamTick, 6) : 0; const visibleWords = Array.from({ length: visibleWordCount }, (_, offset) => { const index = streamTick - visibleWordCount + offset; return streamWords[index % streamWords.length]; }); useEffect(() => { if (!isStreaming) return; const timer = window.setInterval(() => { setStreamTick((tick) => tick + 1); }, 850); return () => window.clearInterval(timer); }, [isStreaming]); if (!visibleArticle && !isStreaming) { return (
优化结果
); } return (
优化结果 {isStreaming && ( )}
{visibleArticle ? (

{visibleArticle.title}

{visibleArticle.summary}

{visibleArticle.body_markdown}
) : (
)} {isStreaming && visibleWords.length > 0 && ( )} {visibleArticle && ( <>

图片建议

{visibleArticle.image_suggestions.length > 0 ? (
    {visibleArticle.image_suggestions.map((item) => (
  • {item.source}: {item.suggestion}
  • ))}
) : (

暂无图片建议。

)}

修改位置

{visibleArticle.changed_sections.map((section) => ( {section} ))}
{visibleArticle.requires_user_confirmation.length > 0 && (

需要人工确认

    {visibleArticle.requires_user_confirmation.map((item) => (
  • {item}
  • ))}
)} )} {article && (
{exportFiles.map((fileName) => jobId ? ( {fileName} ) : ( ), )}
)}
); }