import { notFound } from "next/navigation"; import { Workbench } from "@/components/workbench/Workbench"; import { fetchDraft, fetchOutline, fetchProject } from "@/lib/api/server"; import type { ProjectResponse } from "@/lib/api/types"; import { parseChapterParam, type ChapterEntry } from "@/lib/workbench/chapter"; interface PageProps { params: Promise<{ id: string }>; searchParams: Promise<{ chapter?: string | string[] }>; } // 写作工作台页(UX §6.3)。Server Component 取项目 + 该章已存草稿(GET .../draft, // 404→null=空编辑器),把正文作为编辑器初值种入,重访时重载已写章节;Workbench // 负责编辑/流式/保存(流式照常覆盖初值)。章号由 `?chapter=N` 指定(缺省=第 1 章), // 支持写下一章。 export default async function WritePage({ params, searchParams }: PageProps) { const { id } = await params; const { chapter } = await searchParams; const chapterNo = parseChapterParam(chapter); // 仅当项目确实取不到时才判 404;草稿/瞬时错误不应把整页变成「找不到页面」。 let project: ProjectResponse; try { project = await fetchProject(id); } catch { notFound(); } // 草稿读取失败(后端瞬时错误 / 新章尚无草稿)→ 空编辑器初值,绝不 404。 let initialText = ""; try { const draft = await fetchDraft(id, chapterNo); initialText = draft?.content ?? ""; } catch { initialText = ""; } // 大纲章节作目录(fetchOutline 已对空/错误降级为 []);首个节拍当短标题。 const chapters: ChapterEntry[] = (await fetchOutline(id)).map((c) => ({ no: c.no, title: c.beats?.[0], })); return ( // key=章号:客户端切章(?chapter=N 变化)时强制重挂载,用新章草稿刷新编辑器状态, // 避免 Workbench 内 useState(initialText)/autosave 基线沿用上一章而显示旧内容。 ); }