"use client"; import { CheckCircle2, X } from "lucide-react"; import { useEffect } from "react"; import { ThinkingIndicator } from "@/components/ThinkingIndicator"; import { Button } from "@/components/ui/Button"; import { Badge } from "@/components/ui/Badge"; import { useRefine } from "@/lib/style/useRefine"; interface RefineViewProps { projectId: string; chapterNo: number; // 选中漂移段的原文(从终稿按段切出;空则提示先编辑终稿)。 segment: string; // 采纳:把 refined 合入终稿(经审稿页 finalText → 既有 draft 自动保存路径)。 onAdopt: (original: string, refined: string) => void; onClose: () => void; } // 回炉 diff(UX §8.3):POST .../refine → 展示原段/重写段对比 → 采纳合入正文。 // 不另写库(不变量#3);采纳经既有 draft 自动保存合入。 export function RefineView({ projectId, chapterNo, segment, onAdopt, onClose, }: RefineViewProps) { const refiner = useRefine(); const { refine, abort } = refiner; // 进入即触发回炉(段非空);清理时取消在途请求,避免旧段迟到响应覆盖新段(CR-H12)。 useEffect(() => { if (segment.trim().length > 0) { void refine(projectId, chapterNo, segment); } return () => { abort(); }; }, [segment, projectId, chapterNo, refine, abort]); return (

回炉对比

{segment.trim().length === 0 ? ( 该段在终稿中为空,请先在终稿中保留该段正文。 ) : (
{refiner.status === "refining" ? (

) : refiner.status === "error" ? (

回炉失败,请稍后重试。

) : refiner.result ? ( 回炉完成,可对比后采纳。 ) : null}
)} {segment.trim().length > 0 && refiner.result ? (

原段

{refiner.result.original}

重写段

{refiner.result.refined}

) : null}
); }