--- belongs_to: - "[[INDEX · 铸渊·协作指令|GitHub ↔ Notion 桥接协议]]" --- # 📝 铸渊指令|AI写网文平台·Phase A · 码字台 · AI辅助写作编辑器 + 全程留痕 + AI使用报告(ZY-WRITING-EDITOR-2026-0325-002)· 霜砚签发 · 冰朔授权 --- ## 〇、指令总览 本指令要求铸渊在 `guanghulab.com/writing/editor/` 下构建 **「码字台」** —— 网文行业专用AI辅助写作编辑器,实现四大核心: 1. **富文本写作编辑器** — 基于 Slate.js 的网文专用编辑器(章节管理、字数统计、自动保存) 2. **AI辅助写作** — 选中文本调AI(扩写/续写/改写/灵感),侧边栏AI对话 3. **全程留痕系统** — 每一次AI介入都记录(时间、操作、原文→新文、采纳/拒绝) 4. **AI使用报告** — 自动生成ABCD级报告(A=原AI率≤10% → D=原AI率>50%) ### 核心设计理念 --- ## 一、技术选型 | **层级** | **技术** | **版本** | **用途** | | --- | --- | --- | --- | | 富文本编辑器 | Slate.js | 0.100+ | 核心写作编辑器(可插件、可定制、中文友好) | | 富文本工具栏 | Slate + 自定义插件 | - | 加粗/斜体/标题/分割线/章节跳转 | | 前端框架 | React 18 + TypeScript | 18.2+ | UI 组件化(与 Phase B 共用) | | 样式 | Tailwind CSS | 3.3+ | 响应式 + 专注模式暗色主题 | | AI调用 | OpenAI SDK + Anthropic SDK | latest | 辅助写作(扩写/续写/改写/灵感) | | 实时通信 | [Socket.io](http://Socket.io) | 4.x | AI流式输出 + 自动保存 | | 数据存储 | Notion API(主)+ IndexedDB(本地缓存) | - | 作品存储 + 离线缓存 | | 留痕存储 | Notion API + JSON | - | AI操作日志全量存储 | | 报告生成 | AI + 数据统计 | - | 自动生成ABCD级AI使用报告 | --- ## 二、仓库路径规划 在主仓库 `qinfendebingshuo/guanghulab` 的 `writing-platform/` 下扩展: ``` writing-platform/ ├── frontend/ │ └── src/ │ ├── pages/ │ │ ├── EditorPage.tsx ← 码字台主页面 │ │ ├── WorkListPage.tsx ← 作品列表页 │ │ └── AIReportPage.tsx ← AI使用报告查看页 │ ├── editor/ ← 码字台核心模块 │ │ ├── SlateEditor.tsx ← Slate.js 富文本编辑器主组件 │ │ ├── Toolbar.tsx ← 工具栏(格式化 + AI功能) │ │ ├── ChapterSidebar.tsx ← 左侧章节导航栏 │ │ ├── AIPanel.tsx ← 右侧AI助手面板 │ │ ├── AIFloatingMenu.tsx ← 选中文本后AI浮动菜单 │ │ ├── WordCounter.tsx ← 字数统计栏 │ │ ├── TraceLog.tsx ← 留痕日志面板 │ │ ├── AIReportCard.tsx ← AI使用报告卡片 │ │ ├── plugins/ │ │ │ ├── withChapters.ts ← 章节插件(自动章节检测、跳转) │ │ │ ├── withAutoSave.ts ← 自动保存插件(30s间隔 + 失焦保存) │ │ │ ├── withWordCount.ts ← 字数统计插件(实时统计) │ │ │ ├── withAITrace.ts ← AI留痕插件(每次AI操作自动记录) │ │ │ └── withMarkdownShortcuts.ts ← Markdown 快捷键 │ │ ├── elements/ │ │ │ ├── ChapterElement.tsx ← 章节标题元素 │ │ │ ├── ParagraphElement.tsx ← 段落元素 │ │ │ ├── AIHighlight.tsx ← AI修改高亮标记 │ │ │ └── DividerElement.tsx ← 场景分割线 │ │ └── utils/ │ │ ├── serializer.ts ← Slate → 纯文本 / HTML / Markdown │ │ ├── traceManager.ts ← 留痕数据管理 │ │ ├── reportGenerator.ts ← AI使用报告生成器 │ │ └── chapterDetector.ts ← 章节自动检测 │ ├── hooks/ │ │ ├── useEditor.ts ← 编辑器状态管理 │ │ ├── useAIAssist.ts ← AI辅助写作 Hook │ │ ├── useTrace.ts ← 留痕系统 Hook │ │ └── useAutoSave.ts ← 自动保存 Hook │ └── services/ │ ├── editorApi.ts ← 作品CRUD API │ ├── aiWritingApi.ts ← AI写作 API │ └── traceApi.ts ← 留痕数据 API │ └── backend/ └── src/ ├── routes/ │ ├── works.ts ← 作品管理(创建/列表/读取/更新) │ ├── chapters.ts ← 章节管理(CRUD + 排序) │ ├── aiWriting.ts ← AI写作接口(扩写/续写/改写/灵感) │ ├── traces.ts ← 留痕记录接口 │ └── reports.ts ← AI使用报告接口 └── services/ ├── workService.ts ← 作品数据服务 ├── aiWritingService.ts ← AI写作服务(多模型调度) ├── traceService.ts ← 留痕存储服务 └── reportService.ts ← 报告生成服务 ``` > ℹ️ **与现有码字台目录的关系**:仓库中已有 `writing-workspace/`(DEV-011 匈匈那年),该目录为早期独立模块。本次在 `writing-platform/` 下统一构建,将 `writing-workspace/` 中可复用的代码迁入。 > --- ## 三、Phase 0 · 富文本写作编辑器 ### 3.1 界面布局 ``` ┌────────────────────────────────────────────────────────────────────────────┐ │ 📝 《霸总的小娇妻》 字数: 45,230 今日: +2,180 [🤖 AI] [📊] [← 返回] │ ├──────────┬────────────────────────────────────────────┬─────────────────────┤ │ 章节导航 │ │ 🤖 AI助手 │ │ │ ┌──────────────────────────────────────┐ │ │ │ 第1章 相遇│ │ **工具栏** │ │ 笔灵: │ │ 1,850字 │ │ B I U | H1 H2 | — | 🤖 | ↺ ↻ │ │ 这段对话的节奏 │ │ 第2章 重逢│ └──────────────────────────────────────┘ │ 可以再快一点, │ │ 2,100字 │ │ 建议缩短为... │ │ 第3章 误解│ 「他抬起头,看到她站在门口。灯光打在 │ │ │ 1,900字 │ 她身上,像一层柔和的金粉。」 │ ─────────────── │ │ 第4章 真相│ │ 留痕记录 (12) │ │ 2,300字 │ 「你怎么在这儿?」他的声音有些嘲哑。 │ │ 21:05 扩写 +120字│ │ ▶ 第5章..│ │ │ 21:03 续写 +85字 │ │ 580字 │ 「我...」她欲言又止,“ ” │ │ 20:58 改写 38字 │ │ ✔︎已完结 │ │ │ │ │ [选中文本后弹出 AI 浮动菜单] │ ─────────────── │ │ + 新章节 │ ┌────────────────────────┐ │ AI报告概览 │ │ │ │ ✨扩写 | ✍️续写 | 🔄改写 │ │ 等级: **A** │ │ │ │ 💡灵感 | 📝摘要 | ❓问笔灵│ │ 原AI率: 8.2% │ │ │ └────────────────────────┘ │ AI操作: 12次 │ │ │ │ 采纳率: 75% │ ├──────────┴────────────────────────────────────────────┴─────────────────────┤ │ 上次保存: 21:08 | 自动保存: 开 | 专注模式: 关 | 快捷键: Ctrl+S 保存 Ctrl+/ 呼AI │ └────────────────────────────────────────────────────────────────────────────┘ ``` 布局说明: - **左侧 · 章节导航** — 显示所有章节 + 字数 + 当前编辑章节高亮,可拖拽排序 - **中间 · 编辑区** — 主写作区域,纯净无干扰,类似语雀/Word写作体验 - **右侧 · AI助手** — AI对话 + 留痕记录 + AI报告概览,可折叠 - **底部状态栏** — 保存状态 + 专注模式开关 + 快捷键提示 ### 3.2 Slate.js 编辑器核心配置 ```tsx // editor/SlateEditor.tsx import { createEditor, Descendant, Editor, Transforms } from 'slate'; import { Slate, Editable, withReact } from 'slate-react'; import { withHistory } from 'slate-history'; import { withChapters } from './plugins/withChapters'; import { withAutoSave } from './plugins/withAutoSave'; import { withWordCount } from './plugins/withWordCount'; import { withAITrace } from './plugins/withAITrace'; import { withMarkdownShortcuts } from './plugins/withMarkdownShortcuts'; // 自定义元素类型 type CustomElement = | { type: 'chapter-title'; level: number; children: CustomText[] } | { type: 'paragraph'; children: CustomText[] } | { type: 'scene-divider'; children: CustomText[] } | { type: 'ai-highlight'; aiAction: string; traceId: string; children: CustomText[] }; type CustomText = { text: string; bold?: boolean; italic?: boolean; underline?: boolean; aiGenerated?: boolean; // 标记AI生成的文本 aiTraceId?: string; // 关联留痕ID }; export function WritingEditor({ workId, chapterId }: Props) { const editor = useMemo(() => withMarkdownShortcuts( withAITrace( withWordCount( withAutoSave( withChapters( withHistory( withReact(createEditor()) ) ), { interval: 30000 } // 30秒自动保存 ) ) ) ), []); const [value, setValue] = useState(initialValue); // 加载章节内容 useEffect(() => { loadChapterContent(workId, chapterId).then(content => { setValue(content); }); }, [workId, chapterId]); return ( ); } ``` ### 3.3 章节管理系统 | **功能** | **实现** | **说明** | | --- | --- | --- | | 章节列表 | 左侧边栏 ChapterSidebar | 显示全部章节 + 字数 + 编辑状态 | | 新建章节 | 点击 + 新章节 | 自动编号(第N章),光标跳到标题 | | 章节跳转 | 点击左侧章节名 | 平滑滚动到对应章节 | | 章节拖拽排序 | Drag & Drop | 拖拽调整章节顺序,自动更新编号 | | 章节状态 | 图标标记 | ✅已完结 / ✍️编辑中 / 📝草稿 | | 字数统计 | 实时计算 | 每章字数 + 总字数 + 今日新增 | ### 3.4 专注模式 点击底部状态栏「专注模式」按钮后: - 隐藏左侧章节栏 + 右侧AI面板 - 编辑区全屏居中,更宽的写作区域 - 背景切换为暗色主题(护眼) - 快捷键 `Esc` 退出专注模式 --- ## 四、Phase 1 · AI辅助写作 ### 4.1 AI调用方式 作者有三种方式调用AI: **方式一:选中文本 → AI浮动菜单** 选中一段文字后,弹出浮动菜单: | **操作** | **图标** | **功能** | **System Prompt 核心** | | --- | --- | --- | --- | | 扩写 | ✨ | 将选中的文字扩展为更详细的描写 | 将以下内容扩写为更详细生动的描写,保持原文风格和人称视角。输出1.5-2倍字数。 | | 续写 | ✍️ | 从选中位置继续写下去 | 根据上文继续写作,保持情节连贯性和人物性格一致性。生成200-500字。 | | 改写 | 🔄 | 用不同表达重写选中内容 | 以更优美/更紧凑/更有张力的方式重写以下内容,保持原意不变。 | | 灵感 | 💡 | 基于当前内容给出后续情节建议 | 基于以下内容,给出3个不同方向的后续情节建议,每个50字内。 | | 摘要 | 📝 | 对选中内容生成摘要 | 用一句话概括以下内容的核心情节。 | | 问笔灵 | ❓ | 将选中内容发给AI伙伴讨论 | 跳转到右侧AI面板,携带选中内容作为上下文 | **方式二:快捷键 `Ctrl+/` 呼AI** 在光标位置按 `Ctrl+/`,弹出命令面板,输入自由指令: - 「帮我写一段雨景描写」 - 「这段对话太长,缩短一半」 - 「给女主加一句内心独白」 - 「检查这一章有没有前后矛盾」 **方式三:右侧AI助手面板** 与AI伙伴(笔灵)自由对话,讨论情节、人物、世界观等。对话内容可一键插入编辑器。 ### 4.2 AI响应流程 ``` 用户选中文本 + 点击「扩写」 ↓ 前端发送请求: { action: "expand", selectedText: "他抬起头,看到她站在门口。", context: { chapterContent: "... 前后500字上下文 ...", chapterTitle: "第5章 重逢", workTitle: "霸总的小娇妻", genre: "都市言情", wordCountTarget: 3000 } } ↓ 后端构建完整 prompt + 调AI ↓ 流式返回结果(SSE / WebSocket) ↓ 前端在编辑器下方显示AI建议区: ┌─────────────────────────────────────┐ │ 🤖 AI建议(扩写) │ │ │ │ 他抬起头,看到她站在门口。灯光打在 │ │ 她身上,像一层柔和的金粉,勾勒出她 │ │ 纤细的轮廓。她微微侧着头,发丝从肩 │ │ 头滑落,露出一截白皙的脖颈... │ │ │ │ [✅ 采纳] [❌ 拒绝] [🔄 重新生成] │ └─────────────────────────────────────┘ ↓ 用户点击 [✅ 采纳] ↓ AI文本插入编辑器,带 aiGenerated=true 标记 ↓ 同时写入留痕记录 ``` ### 4.3 AI写作 API ```tsx // POST /api/writing/ai/assist Body: { action: "expand" | "continue" | "rewrite" | "inspire" | "summarize" | "freeform", selectedText: string, // 选中的文本 freeformPrompt?: string, // 自由指令(action=freeform时) context: { chapterId: string, chapterContent: string, // 当前章节全文(或截取前吅500字) chapterTitle: string, workTitle: string, genre: string, // 作品类型 previousChapterSummary?: string // 前一章摘要 } } Response (SSE 流式): { type: "chunk" | "done", content: string, // 每次返回一块文本 traceId: string, // 留痕ID tokenUsage?: { // 完成时返回 prompt: number, completion: number } } ``` ### 4.4 后端 AI 写作服务 ```tsx // services/aiWritingService.ts const WRITING_PROMPTS: Record string> = { expand: (ctx) => `你是一位专业的${ctx.genre}小说写作助手。 作品:《${ctx.workTitle}》,当前章节:${ctx.chapterTitle}。 请将以下内容扩写为更详细生动的描写,保持原文风格和人称视角。 扩写到原文的1.5-2倍字数。只输出扩写后的文本,不要加任何解释。 上下文: ${ctx.chapterContent} 需要扩写的内容: ${ctx.selectedText}`, continue: (ctx) => `你是一位专业的${ctx.genre}小说写作助手。 作品:《${ctx.workTitle}》,当前章节:${ctx.chapterTitle}。 请根据以下内容继续写作,保持情节连贯性和人物性格一致性。 生成200-500字。只输出续写的文本。 当前内容: ${ctx.chapterContent} 从这里继续: ${ctx.selectedText}`, rewrite: (ctx) => `你是一位专业的${ctx.genre}小说写作助手。 作品:《${ctx.workTitle}》,当前章节:${ctx.chapterTitle}。 请以更优美的表达重写以下内容,保持原意不变,字数相近。 只输出重写后的文本。 原文: ${ctx.selectedText}`, inspire: (ctx) => `你是一位专业的${ctx.genre}小说写作助手。 作品:《${ctx.workTitle}》,当前章节:${ctx.chapterTitle}。 基于以下内容,给出3个不同方向的后续情节建议,每个50字内。 格式:1. … 2. … 3. … 当前内容: ${ctx.selectedText}`, summarize: (ctx) => `用一句话概括以下内容的核心情节: ${ctx.selectedText}`, freeform: (ctx) => `你是一位专业的${ctx.genre}小说写作助手。 作品:《${ctx.workTitle}》,当前章节:${ctx.chapterTitle}。 当前内容: ${ctx.chapterContent} 作者的指令: ${ctx.freeformPrompt} 相关内容: ${ctx.selectedText}` }; export async function* streamAIWriting(params: AIWritingParams) { const prompt = WRITING_PROMPTS[params.action](params.context); const stream = await openai.chat.completions.create({ model: 'gpt-4', messages: [ { role: 'system', content: prompt }, { role: 'user', content: params.selectedText || params.freeformPrompt } ], temperature: 0.8, // 创作类任务略高温度 max_tokens: 1500, stream: true }); let fullContent = ''; for await (const chunk of stream) { const content = chunk.choices[0]?.delta?.content || ''; fullContent += content; yield { type: 'chunk', content }; } yield { type: 'done', content: fullContent, tokenUsage: { prompt: 0, completion: 0 } // 从 stream 中提取 }; } ``` --- ## 五、Phase 2 · 全程留痕系统 ### 5.1 核心原则 ### 5.2 留痕数据结构 ```tsx interface AITrace { traceId: string; // 唯一ID workId: string; // 作品ID chapterId: string; // 章节ID userId: string; // 作者ID timestamp: string; // ISO时间戳 action: 'expand' | 'continue' | 'rewrite' | 'inspire' | 'summarize' | 'freeform'; input: { selectedText: string; // 原文(选中的文字) prompt?: string; // 自由指令(如有) }; output: { generatedText: string; // AI生成的文字 tokenUsage: { prompt: number; completion: number; }; }; decision: 'accepted' | 'rejected' | 'modified' | 'pending'; finalText?: string; // 如果作者修改了AI建议后采纳,记录最终文本 wordDelta: number; // 字数变化(+120 表示AI贡献了120字) } ``` ### 5.3 留痕时机 | **事件** | **记录内容** | **decision 状态** | | --- | --- | --- | | 用户调用AI | 记录 input + output | `pending` | | 用户点击 采纳 | 更新 decision | `accepted` | | 用户点击 拒绝 | 更新 decision | `rejected` | | 用户修改后采纳 | 更新 decision + finalText | `modified` | | 用户关闭建议区(未操作) | 更新 decision | `rejected` | ### 5.4 留痕显示 右侧AI面板的「留痕记录」区域,按时间倒序显示: ``` 留痕记录 (12) │ 21:05 ✨扩写 +120字 ✅采纳 │ 21:03 ✍️续写 +85字 ✅采纳 │ 20:58 🔄改写 38字 ❌拒绝 │ 20:55 💡灵感 3条 ✅采纳#2 │ 20:50 ✨扩写 +200字 ✏️修改后采纳 │ ... ``` 点击每条记录可展开查看详情(原文 → AI生成 → 最终采纳)。 ### 5.5 API ```tsx // 记录留痕 POST /api/writing/traces Body: { ...AITrace } // 获取章节留痕列表 GET /api/writing/traces?workId=xxx&chapterId=xxx Response: { traces: AITrace[] } // 更新留痕状态(采纳/拒绝) PATCH /api/writing/traces/:traceId Body: { decision: "accepted" | "rejected" | "modified", finalText?: string } ``` ### 5.6 Notion 数据库 — AI留痕表 | **字段名** | **类型** | **说明** | | --- | --- | --- | | 留痕ID | title | 唯一标识 | | 作品ID | text | 关联作品 | | 章节ID | text | 关联章节 | | 作者ID | text | 关联用户 | | AI操作类型 | select | expand / continue / rewrite / inspire / summarize / freeform | | 原文 | text | 选中的文字 | | AI生成文本 | text | AI输出 | | 最终文本 | text | 作者修改后的文本(如有) | | 决策 | select | accepted / rejected / modified / pending | | 字数变化 | number | AI贡献的字数变化 | | Token消耗 | number | prompt + completion tokens | | 操作时间 | date | 时间戳 | --- ## 六、Phase 3 · AI使用报告(ABCD级) ### 6.1 报告等级定义 | **等级** | **原AI率** | **含义** | **标签颜色** | **说明** | | --- | --- | --- | --- | --- | | **A** | ≤10% | 几乎全部原创 | 🟢 绿色 | AI仅提供少量灵感或微调,创意完全归作者 | | **B** | 10%-30% | AI辅助创作 | 🟡 黄色 | AI提供了部分扩写或辅助,但核心创意和架构归作者 | | **C** | 30%-50% | AI深度参与 | 🟠 橙色 | AI参与了大量写作,但作者进行了实质性修改和编辑 | | **D** | >50% | AI主导写作 | 🔴 红色 | AI生成了大部分内容,作者贡献较少 | ### 6.2 原AI率计算公式 ```tsx // utils/reportGenerator.ts interface AIReportData { totalWords: number; // 作品总字数 aiAcceptedWords: number; // AI生成且被采纳的字数 aiModifiedWords: number; // AI生成但被修改后采纳的字数 humanOnlyWords: number; // 纯人类写作的字数 traces: AITrace[]; // 全部留痕记录 } function calculateRawAIRate(data: AIReportData): number { // 原AI率 = AI采纳字数 / 总字数 // “修改后采纳”按50%计入AI字数(作者进行了修改,算半个原创) const effectiveAIWords = data.aiAcceptedWords + (data.aiModifiedWords * 0.5); return Math.round((effectiveAIWords / data.totalWords) * 100 * 10) / 10; } function getGrade(rawAIRate: number): 'A' | 'B' | 'C' | 'D' { if (rawAIRate <= 10) return 'A'; if (rawAIRate <= 30) return 'B'; if (rawAIRate <= 50) return 'C'; return 'D'; } function generateReport(data: AIReportData): AIReport { const rawAIRate = calculateRawAIRate(data); const grade = getGrade(rawAIRate); const traceStats = { total: data.traces.length, accepted: data.traces.filter(t => t.decision === 'accepted').length, rejected: data.traces.filter(t => t.decision === 'rejected').length, modified: data.traces.filter(t => t.decision === 'modified').length, byAction: { expand: data.traces.filter(t => t.action === 'expand').length, continue: data.traces.filter(t => t.action === 'continue').length, rewrite: data.traces.filter(t => t.action === 'rewrite').length, inspire: data.traces.filter(t => t.action === 'inspire').length, freeform: data.traces.filter(t => t.action === 'freeform').length, } }; return { workId: data.workId, grade, rawAIRate, totalWords: data.totalWords, aiContributionWords: data.aiAcceptedWords + data.aiModifiedWords, humanWords: data.humanOnlyWords, acceptanceRate: Math.round((traceStats.accepted + traceStats.modified) / traceStats.total * 100), traceStats, generatedAt: new Date().toISOString(), // 报告摘要(用AI生成一句话描述) summary: `本作品${grade}级,原AI率${rawAIRate}%。共${data.totalWords}字,AI参与${traceStats.total}次,采纳率${traceStats.accepted + traceStats.modified}/${traceStats.total}。` }; } ``` ### 6.3 报告展示界面 ``` ┌─────────────────────────────────────────────┐ │ AI使用报告 · 《霸总的小娇妻》 │ ├─────────────────────────────────────────────┤ │ │ │ ┌─────────────┐ │ │ │ │ │ │ │ 🟢 A │ │ │ │ 8.2% │ │ │ │ │ │ │ └─────────────┘ │ │ 几乎全部原创 │ │ │ ├─────────────────────────────────────────────┤ │ 总字数 45,230字 │ │ 人类原创 41,520字 (91.8%) │ │ AI贡献 3,710字 (8.2%) │ ├─────────────────────────────────────────────┤ │ AI操作统计 │ │ • 总调用: 47次 │ │ • 扩写: 18次 续写: 12次 改写: 8次 │ │ • 灵感: 6次 自由指令: 3次 │ │ • 采纳率: 75% (35/47) │ │ • 修改后采纳: 8次 │ ├─────────────────────────────────────────────┤ │ 章节明细 │ │ 第1章: A(3.2%) 第2章: A(5.1%) │ │ 第3章: B(12.4%) 第4章: A(7.8%) │ │ 第5章: A(9.0%) ... │ ├─────────────────────────────────────────────┤ │ 报告生成时间: 2026-03-25 21:30 │ │ 本报告由系统自动生成,作者不可修改。 │ └─────────────────────────────────────────────┘ ``` ### 6.4 报告 API ```tsx // 生成/更新作品报告 POST /api/writing/reports/generate Body: { workId: string } Response: { report: AIReport } // 获取作品报告 GET /api/writing/reports/:workId Response: { report: AIReport } // 获取章节级别报告 GET /api/writing/reports/:workId/chapters Response: { chapters: ChapterReport[] } ``` --- ## 七、作品管理 ### 7.1 作品列表页 用户从 Dashboard 点击「开始写作」进入作品列表: ``` ┌─────────────────────────────────────────────┐ │ 📚 我的作品 [+ 新建作品] │ ├─────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────┐ │ │ │ 《霸总的小娇妻》 🟢 A (8.2%) │ │ │ │ 都市言情 · 20章 · 45,230字 · 连载中 │ │ │ │ 最后编辑: 10分钟前 │ │ │ └─────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────┐ │ │ │ 《星辰变》 🟡 B (15.6%) │ │ │ │ 仙侠奇幻 · 8章 · 18,400字 · 草稿 │ │ │ │ 最后编辑: 2天前 │ │ │ └─────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────┘ ``` ### 7.2 新建作品流程 ``` 用户点击 [+ 新建作品] ↓ 弹出表单: - 作品名称(必填) - 作品类型(选择):都市言情 / 仙侠奇幻 / 悬疑推理 / 科幻 / 历史 / 其他 - 简介(选填) ↓ 创建成功 → 自动进入编辑器 → 自动创建「第1章」 ``` ### 7.3 Notion 数据库 — 作品表 | **字段名** | **类型** | **说明** | | --- | --- | --- | | 作品ID | title | 唯一标识 | | 作品名称 | text | 作品标题 | | 作者ID | text | 关联用户 | | 作品类型 | select | 都市言情 / 仙侠奇幻 / 悬疑推理 / 科幻 / 历史 / 其他 | | 总字数 | number | 实时更新 | | 章节数 | number | 实时更新 | | AI报告等级 | select | A / B / C / D | | 原AI率 | number | 百分比 | | 状态 | select | 草稿 / 连载中 / 已完结 / 已发布 | | 简介 | text | 作品简介 | | 创建时间 | date | 创建时间 | | 最后编辑 | date | 最后编辑时间 | ### 7.4 Notion 数据库 — 章节表 | **字段名** | **类型** | **说明** | | --- | --- | --- | | 章节ID | title | 唯一标识 | | 作品ID | text | 关联作品 | | 章节标题 | text | 如「第1章 相遇」 | | 章节序号 | number | 排序用 | | 内容 | text | Slate JSON 序列化存储 | | 字数 | number | 本章字数 | | 状态 | select | 草稿 / 编辑中 / 已完结 | | 最后编辑 | date | 最后保存时间 | --- ## 八、API 总览 | **接口** | **方法** | **功能** | **鉴权** | | --- | --- | --- | --- | | `/api/writing/works` | GET | 获取我的作品列表 | JWT | | `/api/writing/works` | POST | 新建作品 | JWT | | `/api/writing/works/:id` | GET | 获取作品详情 | JWT | | `/api/writing/works/:id` | PATCH | 更新作品信息 | JWT | | `/api/writing/works/:id/chapters` | GET | 获取章节列表 | JWT | | `/api/writing/works/:id/chapters` | POST | 新建章节 | JWT | | `/api/writing/chapters/:id` | GET | 获取章节内容 | JWT | | `/api/writing/chapters/:id` | PUT | 保存章节内容 | JWT | | `/api/writing/chapters/:id/order` | PATCH | 调整章节顺序 | JWT | | `/api/writing/ai/assist` | POST | AI辅助写作(SSE流) | JWT | | `/api/writing/traces` | POST | 记录留痕 | JWT | | `/api/writing/traces` | GET | 获取留痕列表 | JWT | | `/api/writing/traces/:id` | PATCH | 更新留痕状态 | JWT | | `/api/writing/reports/:workId` | GET | 获取AI报告 | JWT | | `/api/writing/reports/generate` | POST | 生成/更新报告 | JWT | --- ## 九、路由规划 | **路由** | **页面** | **说明** | | --- | --- | --- | | `/writing/works` | WorkListPage | 作品列表 | | `/writing/editor/:workId` | EditorPage | 码字台(默认打开最后编辑章节) | | `/writing/editor/:workId/:chapterId` | EditorPage | 码字台(指定章节) | | `/writing/report/:workId` | AIReportPage | AI使用报告详情 | --- ## 十、快捷键 | **快捷键** | **功能** | | --- | --- | | `Ctrl+S` | 手动保存 | | `Ctrl+/` | 呼AI助手(自由指令) | | `Ctrl+Shift+E` | 扩写选中文本 | | `Ctrl+Shift+W` | 续写 | | `Ctrl+Shift+R` | 改写选中文本 | | `Ctrl+Z` | 撤销 | | `Ctrl+Shift+Z` | 重做 | | `Esc` | 退出专注模式 / 关闭AI建议区 | | `F11` | 切换专注模式 | --- ## 十一、验收标准 | **验收项** | **标准** | | --- | --- | | 编辑器可用 | 可流畅输入中文,格式化正常,无卡顿 | | 章节管理 | 新建/切换/拖拽排序正常,字数实时统计 | | 自动保存 | 30秒自动保存 + 失焦保存,底部状态栏显示保存时间 | | AI浮动菜单 | 选中文本后弹出6个AI操作按钮 | | AI流式响应 | AI结果流式显示(SSE),不是一次性加载 | | 采纳/拒绝 | 采纳后AI文本插入编辑器,拒绝后清除建议区 | | 留痕记录 | 每次AI操作自动留痕,右侧面板可查看 | | AI报告 | 可生成ABCD级报告,等级和数据正确 | | 专注模式 | 切换后全屏写作,暗色主题,Esc退出 | | 移动端 | 手机端可编辑(左右侧栏自动收起) | | 数据持久化 | 作品/章节/留痕全部存入 Notion 数据库 | --- ## 十二、执行时序 ``` Phase 0: Slate.js编辑器 + 章节管理 + 工具栏 + 自动保存(预计 4h) ↓ Phase 1: AI辅助写作(浮动菜单 + SSE流 + 6种Action + 右侧AI面板)(预计 3h) ↓ Phase 2: 全程留痕系统(自动记录 + 留痕显示 + Notion存储)(预计 2h) ↓ Phase 3: AI使用报告(ABCD计算 + 报告界面 + 作品列表显示)(预计 2h) ↓ Phase 4: 作品管理(列表页 + 新建作品 + CRUD API)(预计 1.5h) ↓ Phase 5: 前后端联调 + Nginx路由 + 部署(预计 1.5h) ↓ → 预览站测试 → 人类验收 → 正式站上线 ``` --- ## 十三、后续扩展预留 本期完成后,后续可扩展(不在本指令范围): - **导出功能** — 导出为 TXT / DOCX / PDF - **协作编辑** — 多人实时协作编辑(CRDT) - **版本历史** — 每次保存的完整历史记录 - **模板库** — 网文各类型开头/大纲模板 - **章节统计** — 写作时间曲线、字数趋势图 - **多端同步** — 电脑/手机/平板无缝切换 ---