import { useRef, useState } from "react"; import { Play, Download, FileText } from "lucide-react"; import { generateReport, streamTokens, streamExec, reportDownloadUrl, type Identity, type ExecEvent } from "../lib/api"; import { ExecTrace } from "../components/ExecTrace"; import { Button, Input, Field, Panel, Dot, EmptyState, useToast } from "../ui"; type Phase = "idle" | "running" | "done" | "error"; // 报告生成:输入主题(+可选知识库) → 触发后端专用编排 // (规划大纲 → 各章并行检索+撰写 → 渲染 Word),实时看进度与正文,完成后下载 .docx。 export function ReportView({ identity }: { identity: Identity }) { const toast = useToast(); const [topic, setTopic] = useState(""); const [kb, setKb] = useState(""); const [phase, setPhase] = useState("idle"); const [out, setOut] = useState(""); const [exec, setExec] = useState([]); const [taskId, setTaskId] = useState(""); const closeRef = useRef<(() => void) | null>(null); const execCloseRef = useRef<(() => void) | null>(null); const running = phase === "running"; const onGenerate = async () => { if (!topic.trim() || running) return; closeRef.current?.(); execCloseRef.current?.(); setPhase("running"); setOut(""); setExec([]); setTaskId(""); try { const id = await generateReport(identity, topic.trim(), kb.trim() || undefined); setTaskId(id); execCloseRef.current = streamExec( id, (ev) => setExec((xs) => [...xs, ev]), () => {}, () => {}, ); closeRef.current = streamTokens( id, (tok) => setOut((o) => o + tok), () => { setPhase("done"); toast.push("success", "报告已生成,可下载 Word"); }, () => { setPhase("error"); toast.push("error", "报告流连接中断"); }, ); } catch (e) { setPhase("error"); toast.push("error", (e as Error).message); } }; const tracePhase = running ? "streaming" : phase === "done" ? "done" : phase === "error" ? "error" : "idle"; return (

报告生成

规划大纲 → 各章并行(知识库检索 + LLM 撰写)→ 汇聚 → 渲染真实 Word(.docx)。依赖已配置对话模型;挂知识库则引用其资料。

setTopic(e.target.value)} onKeyDown={(e) => e.key === "Enter" && onGenerate()} placeholder="如:2026 年国产大模型产业现状与趋势分析" /> setKb(e.target.value)} placeholder="如 docs,留空则不挂检索" /> {phase === "done" && taskId ? ( 下载 Word ) : ( )}
报告正文 · {taskId || "未开始"} } > {out ? (
{out}
) : ( )}
); }