oh-my-muse/design-docs/前端-02-编辑器与影子层交互.md
zizi 2124a79312 docs(design): 补知识效用缺环——新增专题-07 消费契约与质量闭环 + 七册配套拍板
第一性原理结论:知识的价值只在被选中并改善产出的那一刻兑现;此前 SoT 钉死了治理
(谁能读什么),缺消费选择(该读哪几条)与输入侧质量(什么算好知识、怎么测)。

- 新增 专题-07 v1(唯一 owner):术语桥(卡↔SoT 载体)、按用途默认消费合同与注入
  视图两档、知识质量三性(可命中/可行动/可持续+口径)、回放评测(参考书=标准答案,
  三评测线+两道合规闸+知识策略对象与上线门禁)、长线进度三期消费、实验台实证附录、
  验收清单 8 条
- 专题-06 v4:拍板双层型判定(craft 1326 条实测无损→不拆,判据不变);新增 §6.4
  参照作品面(参考书实体演变=系统侧证据资产,蒸馏成叙事域成长曲线范式才入 Global);
  世界域六型登记演变历程元素;读取器 purpose 枚举 parse→extraction
- 架构-02 v11:aiContext 值域升级为布尔或用途集(实验台字段级用途裁剪实证反哺)
- 专题-03 v3 / 专题-04 v2(补 .md 改名+离线评估允许样本第 5 类)/ 后端-05 v11 /
  前端-03 v7 / 产品-01·02、前端-02、后端-03 断链修复 / 大纲 v10 / 映射表 v8
- prototypes/ 新增四页签开发者总览

依据:设计文档全库横切取证 + 实验台 9 批实拆实证(活卡 8587、消费端 0 实现、升格
卡向量 0%、p50 实例数 1)。经 codex 与 opus 双独立评审,必修项全部落实。
2026-07-18 00:02:51 +08:00

397 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 前端-02:编辑器与影子层交互
- 版本:v6
- 更新日期:2026-05-24
- 目标读者:前端 / 后端 / 架构 / 产品
- 阅读时间:25-40 分钟
- 边界说明:本文件只定义 `muse-studio` 用户端的写作台、正文编辑、AI 候选、待确认知识和恢复策略。管理后台不承载写作台;精确 API 看 `后端-05`,状态机看 `架构-04`,Accept 语义看 `专题-01`。
## 1. 所属前端
写作台属于独立用户端项目:
```text
muse-studio
-> /app-api/**
```
它不在 `yudao-ui-admin-vben` 中实现,不复用 Vben 管理后台 layout、菜单、表格工作台或权限页面。
写作台只调用 `/app-api/**`。当前用户、权益摘要、默认入口和可见产品空间来自 `/app-api/muse/me`;写作台不使用 `/app-api/auth/me`。
## 2. 写作台结构
写作台(Writing Desk)是用户打开某个作品后的默认入口。
| 区域 | 用户看到什么 | 前端职责 |
|---|---|---|
| 左侧 | 章节、章节摘要、章节目标、情节节拍、定位入口 | 帮用户理解当前章节位置,并跳转到规划、知识和历史 |
| 中间 | 当前章节正文编辑器 | 承载 Tiptap/ProseMirror 编辑、Block 保存、revision 冲突处理 |
| 右侧 | AI 候选、待确认知识、创作健康度、任务状态、参考来源摘要 | 承载候选卡流、知识提醒、质量解释和失败恢复 |
| 抽屉/面板 | 已确认设定、上下文命中、风险说明、历史记录 | 解释系统状态和可跳转定位,不替用户自动确认 |
普通用户默认看到“AI 候选 / 待确认知识 / 已确认设定 / 生成历史 / 创作健康度”,不直接看到 Shadow、Canonical、Archive、Pipeline、Prompt 等系统词。
## 3. Block 编辑
- 每个 Block 必须携带 `id`、`revision` 和结构化正文内容。
- 用户在编辑器里编辑的是正式正文草稿,保存成功后成为 Content Canonical。
- 写入正文必须经过 `/app-api/**` 的 expectedRevision 校验。
- 导入产生的 Block 和手动创建的 Block 使用同一编辑规则。
- 前端可以乐观更新,但服务端 revision 是唯一真相。
冲突处理:
| 冲突 | 前端处理 |
|---|---|
| revision 不匹配 | 展示本地版本、服务端版本和可选恢复动作 |
| 本地继续编辑后服务端失败 | 禁止静默覆盖新输入,进入显式冲突态 |
| 来源或授权变化 | 拦截接受/确认动作,引导重验或重新生成 |
## 4. 正文持久化与恢复
### 4.1 自动保存
编辑器内容变化后 debounce 2s 触发保存到服务端(`PUT /app-api/muse/works/{workId}/blocks/{blockId}`),携带 `expectedRevision` 做乐观并发控制。
保存状态指示器:
| 状态 | UI 展示 | 说明 |
|---|---|---|
| 已保存 | "已保存" + 时间戳 | 最近一次保存成功 |
| 保存中 | "保存中..." + loading | debounce 触发后等待响应 |
| 保存失败 | "保存失败(点击重试)" + 错误色 | 网络异常或 revision 冲突 |
### 4.2 IndexedDB 安全网
- 每次编辑变化同步写入 IndexedDB,key 为 `workId + blockId`,value 包含内容、本地时间戳和最后已知 revision。
- IndexedDB 写入不依赖服务端响应,作为崩溃恢复安全网。
- 正常情况下用户无感知 IndexedDB 的存在。
### 4.3 恢复入口
- 页面加载时对比 IndexedDB 版本与服务端版本(通过本地时间戳和服务端 `updatedAt` 比较)。
- 如果 IndexedDB 内容比服务端更新(说明上次保存未成功提交),展示恢复提示:"检测到未保存的本地修改,是否恢复?"
- 用户选择恢复:将 IndexedDB 内容加载到编辑器,触发一次保存。
- 用户选择放弃:清除 IndexedDB 中该 Block 的本地缓存,使用服务端版本。
- 保存成功后清除对应 IndexedDB 条目(或更新为与服务端一致)。
## 5. Block 模型与编辑器映射
### 5.1 Block 粒度
Block 粒度为场景/小节级。一个 Block 对应正文中一个相对独立的叙事单元(如一个场景、一个小节)。
### 5.2 分割点识别
- 自动识别:标题模式自动识别分割点,匹配 `##` 或「第X节」「第X章」等模式。
- 手动标记:用户可在编辑器中手动插入或移除分割标记。
- 编辑器中分割点可见(如水平分隔线 + 标签),但不干扰正常阅读和编辑。
### 5.3 Block 与 ProseMirror 的映射
- 每个 Block 对应一个独立的 ProseMirror Document(或顶级 Node)。
- 编辑器加载时按 Block 顺序拼装为完整文档视图,Block 边界以不可编辑的分隔节点标识。
- 每个 Block 独立维护 revision 和保存状态。
### 5.4 跨 Block 操作
- 选中跨 Block 文本时,操作拆分为对两个 Block 的独立修改,分别提交各自的 `expectedRevision`。
- 跨 Block 删除、粘贴等操作在前端拆分为多个 Block 级 Transaction,按顺序提交。
- 如果其中一个 Block 提交失败(revision 冲突),前端回滚该 Block 的本地变更并进入冲突处理。
### 5.5 AI 候选合并
- 接受候选时,通过 ProseMirror Transaction 替换目标 Block 内容。
- Transaction 保留 undo history,用户可撤销合并操作(本地撤销不影响服务端已提交的 revision)。
- 合并后立即触发保存,携带候选接受接口返回的新 revision。
## 6. 待确认对象分组
| 用户语言 | 底层对象 | 用户动作 |
|---|---|---|
| AI 候选 | AI Suggestion / Shadow Candidate | 原样接受、修改后合并、丢弃、重生成 |
| 待确认知识 | Knowledge Draft | 确认、忽略、重验来源、重新提取 |
| 规划候选 | Planning Candidate | 接受为规划项、修改后保存、丢弃 |
| 解析章节结果 | Chapter Parse Result | 整章确认进入知识草稿处理、整章驳回 |
| 生成历史 | Archive / Job History | 只读回看、定位来源、解释失败 |
这些对象可以共享卡片视觉,但不能共享提交语义。
待确认对象必须带来源 lineage、授权快照或来源状态摘要。前端只展示和传递后端返回的可信快照,不能自行判定来源仍然有效。
规划候选的接受、修改后保存和丢弃必须走规划 owner 的 `/app-api/**` 决策接口,由后端写入或拒绝写入规划正式事实。前端不得复用 AI Suggestion 的 accept 接口,也不得把规划确认塞进动态表单的通用保存动作。
## 7. AI 候选卡
候选卡至少展示:
- 候选正文或候选方案。
- 关联智能体和来源摘要。
- 创作健康度和质量维度摘要。
- 风险标记。
- 使用和排除的来源。
- 可用动作和硬闸门状态摘要(用户可读语言,不显示内部合同名)。
动作展示必须等待服务端返回最新硬闸门结果。前端可以展示本地草稿、质量摘要和加载态,但不能基于本地评分、本地 Zod 校验或按钮可见性自行允许接受或合并。
动作约束:
| 动作 | 允许写入 | 必须保持 |
|---|---|---|
| `accept_as_is` | 目标 Block 新 revision、候选归档 | 关联 Knowledge Draft 仍待确认;不写 Local KB;不自动确认规划正式事实 |
| `merge_after_edit` | 用户修改后的最终正文、候选归档 | 旧 Knowledge Draft 失效并退出当前待确认区;提交后重新提取新的 Knowledge Draft |
| `discard` | 候选归档为丢弃 | 不改正文;不改 Local KB;不改规划正式事实 |
接受候选的前端语义必须收敛为“正文决策”,不是“知识确认”。如果候选来自用户知识库、市场知识库或已安装智能体,前端必须展示对应来源和授权快照;购买、安装或绑定资产成功本身不写作品正文、不写 Local KB、不写规划正式事实。
作品资产当前默认不作为候选来源、参考来源或 AI 上下文。写作台只展示阅读、收藏、授权记录或后续能力禁用态;只有作品资产 feature gate、作品 owner 承接、来源 lineage、授权快照和使用预检全部闭合后,前端才允许出现模板化、参考写入或上下文绑定动作。
来源撤权、召回、下架、blocked、owner_missing 或授权快照失效时,前端只能禁用接受、提示重验或重新生成。前端不能自动确认知识,也不能自动回滚已经存在的正式正文或正式知识。
硬闸门失败必须展示用户可理解的阻断原因:
| 阻断来源 | 用户端展示 |
|---|---|
| 来源失效或 owner 缺失 | 当前来源不能继续用于接受,请更换来源或重新生成 |
| 授权撤销、过期或范围不足 | 当前授权不支持本次使用,请重新授权或移除该来源 |
| 合规阻断 | 当前内容或来源不允许继续处理 |
| 静态检查失败 | 当前结果存在格式、结构或安全检查问题 |
| 版本冲突 | 正文已被更新,请先处理冲突 |
| 作品资产 feature gate 未开启 | 作品资产当前只能阅读、收藏和查看授权记录 |
禁止文案:
- “已合并,关联知识草稿已确认”
- “已合并,草稿已经进入正式知识”
- “来源已撤权,已自动回滚正式事实”
- “安装成功,已写入作品设定”
允许文案:
- “已合并,关联知识草稿仍待确认”
- “已合并,旧知识草稿已失效,正在重新提取”
- “引用来源已被召回,当前候选不能继续接受”
- “安装成功,可在作品中选择使用”
### 7.1 候选接受与来源校验
接受时前端调用接口(`POST /app-api/muse/suggestions/{suggestionId}/accept`),后端实时校验来源版本和授权状态。前端不在本地缓存或判定来源有效性,每次接受操作由服务端做最终决策。
- 接受前:前端调用候选详情接口获取最新可用动作和硬闸门状态。
- 接受请求:传入 `suggestionId`、`expectedRevision` 和 `commandId`。
- 版本不匹配:服务端返回 `STATE_CONFLICT`,前端刷新候选卡状态和可用动作。
- 来源失效:服务端返回阻断原因,前端展示用户可理解的阻断说明。
## 8. 创作健康度展示
创作健康度是候选解释,不是作品排名。
展示内容:
- 总体状态:可用、已重写后可用、高风险、已阻断、需重验。
- 关键风险:设定冲突、角色失声、来源撤权、合规阻断。
- 维度摘要:设定一致性、角色声音、场景结构、文风、节奏。
- 来源摘要:用了哪些正文、Local KB、授权知识;哪些来源被排除。
- 下一步动作:接受、修改后合并、丢弃、重生成、重验来源。
前端不能绕过 blocked / invalidated / needs_recheck 接受候选。
<!-- 注:此处 needs_recheck 是 ActionPolicy 或 qualityState 层面的值,不是 SourceStatus 枚举值 -->
候选状态 `invalidated` 的 UI 处理:展示"已失效,不可接受",禁用接受和合并按钮,允许用户触发重新生成。候选失效原因(来源撤权、授权过期、质量结果过期等)必须以产品语言展示。
用户可以选择开放槽位中的智能体或知识库,但不能替换输入输出合规、拆分切块、RAG 入库、语义安全围栏、静态检查、质量门控、权限、审计和 Shadow -> Canonical 等保护节点。写作台只展示可选项和不可用原因,不暴露底层 Pipeline 控制权。
### 8.1 Source Status 前端处理策略
来源状态(Source Status)是候选、知识草稿、绑定和导出动作的前置条件。前端必须统一处理来源状态到 UI 的映射(参见 `后端-05-统一API契约-v1.md` §4.2 Source Status 定义)。
来源状态到 UI 映射表:
| sourceStatus | UI 展示 | 接受/确认按钮 | 用户可用动作 |
|---|---|---|---|
| `active` | 来源正常(默认不额外提示) | 启用 | 正常操作 |
| `stale` | "来源版本已更新,建议刷新" | 启用(带警告) | 刷新来源、继续操作 |
| `needs_recheck` | "来源需要重新验证" | 禁用 | 触发重验 |
<!-- 注:此处 needs_recheck 作为 sourceStatus UI 映射候选值,实际是 ActionPolicy 层面的判定结论;SourceStatus 合法值不含 needs_recheck,前端应以 actionPolicy=needs_recheck 驱动此 UI -->
| `revoked` | "来源授权已撤销" | 禁用 | 查看原因、替换来源 |
| `recalled` | "来源已被召回" | 禁用 | 查看原因、替换来源 |
| `delisted` | "来源已下架" | 禁用 | 查看原因、替换来源 |
| `blocked` | "来源已被阻断" | 禁用 | 查看原因、替换来源 |
| `owner_missing` | "来源归属缺失" | 禁用 | 联系支持、替换来源 |
| `unauthorized` | "来源授权不足" | 禁用 | 重新授权、替换来源 |
查询时机:
- 候选展示时:候选详情接口返回 `sourceSnapshot` 包含当前来源状态。
- 定期轮询:对处于 `needs_recheck` 或 `stale` 的来源,前端按 TanStack Query 的 `refetchInterval` 定期刷新状态(建议 30s-60s)。
<!-- 注:此处 needs_recheck 指 actionPolicy=needs_recheck 的判定结论,不是 SourceStatus 枚举值 -->
- 用户主动刷新:提供"刷新来源状态"按钮。
重验触发和结果展示:
- 用户点击"重新验证"调用 `POST /app-api/muse/source-status/recheck`,返回 `jobId`。
- 重验是异步任务,前端进入轮询等待。
- 重验完成后刷新来源状态;如果恢复为 `active`,重新启用接受/确认按钮。
- 重验失败或来源仍不可用时,展示失败原因和下一步建议。
来源失效时的 UI 降级:
- 禁用接受、确认、绑定和导出按钮。
- 展示失效原因(使用产品语言,不暴露技术状态码)。
- 候选卡标记为"来源不可用",视觉降级(灰色或警告色)。
- 已展示的候选内容保留可读,但不可操作。
## 9. 作品规划台交互
作品规划台(Planning Desk)是用户打开某个作品后的规划入口,与写作台平级。
### 9.1 一级入口切换
规划台包含五个一级入口,以 Tab 或侧边导航切换:
| 入口 | 内容 | 切换逻辑 |
|---|---|---|
| 作品设定 | 题材、类型、主题、基调、禁区、结局方向 | 默认入口;切换时拉取最新投影和已确认数据 |
| 章节大纲 | 章节顺序、摘要、目标、主线、支线、伏笔、情节节拍 | 切换时加载章节列表和大纲结构 |
| 世界设定 | 角色、地点、物品、组织、规则、事件、时间线 | 切换时加载世界设定投影 |
| 角色关系 | 角色档案、目标、动机、弱点、秘密、弧光、关系变化 | 切换时加载角色列表和关系图数据 |
| 文风检查 | 作者声音、句式、节奏、视角、风格漂移 | 切换时加载最近检查结果或空态 |
切换逻辑约束:
- 每次切换调用 `/app-api/muse/works/{workId}/meta-projections/{projectionKey}` 获取当前 section 的可见结构和数据。
- 切换不丢弃用户未提交的本地草稿;离开时提示保存或放弃。
- 各 section 的表单渲染由 MetaSchema 动态表单驱动(参见 `前端-03-元引擎与动态表单.md` §5.2 用户端渲染链路)。
### 9.2 规划候选展示与确认
用户触发 AI 生成、补全或整理后,结果以规划候选卡展示:
- 候选卡展示候选方案、来源摘要、质量结果和 diff(与当前正式规划的差异)。
- 可用动作:接受为规划项、修改后保存、丢弃。
- 接受调用 `POST /app-api/muse/works/{workId}/planning/candidates/{candidateId}/confirm`。
- 丢弃调用 `POST /app-api/muse/works/{workId}/planning/candidates/{candidateId}/discard`。
- 修改后保存:用户编辑候选内容后调用 confirm,传入修改后的数据。
- 候选确认必须带 `commandId`、`expectedRevision`、`sourceSnapshot`、`authorizationSnapshotId`。
多组候选时以列表或对比视图展示,用户逐一确认或丢弃。
### 9.3 文风检查结果展示
文风检查是异步任务:
1. 用户点击"文风检查"触发 `POST /app-api/muse/works/{workId}/planning/style-checks`,返回 `jobId`。
2. 前端进入轮询或通知等待。
3. 完成后调用 `GET /app-api/muse/works/{workId}/planning/style-checks/{jobId}` 获取结果。
4. 展示内容:风格漂移标记、句式分析、节奏评估、视角一致性、禁用风格命中和建议入口。
5. 检查结果只读展示,不直接修改正文或规划;用户可据此手动调整或触发重新生成。
### 9.4 动态表单渲染
规划台各 section 的表单字段、校验规则、可见性和可编辑状态均由后端投影返回,前端按 MetaSchema 动态表单渲染(参见 `前端-03-元引擎与动态表单.md` §3 用户端创作表单和 §5.2 用户端渲染链路)。
提交时必须带 `expectedSchemaVersion`、`expectedProjectionVersion` 和 `expectedDataRevision`,走 planning owner 的 `PUT /app-api/muse/works/{workId}/planning/{sectionKey}` 接口。
## 10. 知识与一致性工作面
知识与一致性工作面是用户在作品工作台中管理局域知识、处理知识草稿和检查一致性的入口。
### 10.1 局域知识库浏览
- 入口:作品工作台的"知识"Tab 或侧边导航。
- 调用 `GET /app-api/muse/works/{workId}/local-knowledge` 获取当前作品 Local KB 内容。
- 展示已确认知识条目列表,支持按类型(角色、地点、物品、规则等)筛选。
- 每条知识展示来源归因、确认时间和关联章节。
- 只读浏览;修正入口见 §8.4。
### 10.2 知识草稿处理
知识草稿(Knowledge Draft)来自 AI 提取、导入解析或正文候选合并后的重新提取。
列表展示:
- 调用 `GET /app-api/muse/works/{workId}/knowledge-drafts` 获取待确认草稿列表。
- 每条草稿展示:提取内容摘要、来源章节/Block、来源状态、风险标记。
- 状态标记:`pending`(待确认)、`confirmed`(已确认)、`ignored`(已忽略)、`invalidated`(已失效)、`needs_reextract`(需重新提取)。
详情与动作:
- 点击草稿进入详情,展示完整提取内容、来源 lineage 和授权快照。
- 可用动作:确认(`POST /app-api/muse/knowledge-drafts/{draftId}/confirm`)、忽略(`POST /app-api/muse/knowledge-drafts/{draftId}/ignore`)、重验来源(`POST /app-api/muse/knowledge-drafts/{draftId}/recheck`)。
- `invalidated` 状态展示"已失效,不可接受",允许触发重新生成。
- `needs_reextract` 状态展示"需重新提取,原草稿已过时",引导用户触发重新提取或等待系统自动重新提取。
### 10.3 一致性检查结果展示
一致性检查由 AI 任务产生,结果展示:
- 设定冲突列表:冲突的知识条目对、冲突类型和严重性。
- 角色失声提醒:长期未出现的角色或关系停滞。
- 时间线矛盾:事件顺序或时间跨度不一致。
- 每条结果关联到具体章节和知识条目,支持跳转定位。
- 结果只读展示,不自动修正。
### 10.4 手动修正入口
- 用户可从一致性检查结果或局域知识浏览中发起手动修正。
- 修正走规划 owner 或知识 owner 的对应命令接口,不走通用动态字段保存。
- 修正后相关知识草稿可能失效,需重新提取。
## 11. 同步与恢复
服务器状态建议由 TanStack Query 管理:
- Work / Chapter / Block。
- Active Suggestions。
- Knowledge Drafts。
- Candidate Quality Result。
- Job Status。
- Archive / History。
- Usage Summary。
本地 UI 状态建议由 Zustand 或局部状态管理:
- 当前候选卡。
- 右侧面板 tab。
- 冲突弹窗。
- 乐观更新快照。
- 跳转定位。
恢复策略:
1. 成功后按服务端返回的 revision 和状态刷新。
2. 可重试失败保留用户输入和上下文。
3. 不可重试失败禁用动作并解释原因。
4. 任务型操作进入轮询或通知,不阻塞正文已成功保存的主事务。
## 12. 导入解析与导出 UI
- 导入入口属于作品工作台,不属于作品列表深层弹窗。
- 导入正文可初始化章节和 Block。
- 全书解析必须展示章节级进度、失败原因和章节审阅入口。
- 章节审阅确认只推进到 Knowledge Draft 处理,不直接写 Local KB。
- 详情页负责解释,不提供逐条绕过章节边界的确认。
全书解析审阅交互:
- 章节级确认/驳回:每个 Chapter Parse Result 独立展示,用户可逐章确认(`POST /app-api/muse/chapter-parse-results/{resultId}/confirm`)或驳回(`POST /app-api/muse/chapter-parse-results/{resultId}/reject`)。
- 一键确认可确认章节:对所有状态为可确认且无高风险标记的章节,提供批量确认入口(`POST /app-api/muse/parse-jobs/{jobId}/chapters/batch-confirm`)。批量确认以章节为事务边界,允许部分失败。
- 高风险冲突处理:高风险章节(来源状态异常、质量阻断、revision 冲突)标记为不可批量确认,必须逐章审阅后单独处理。
- 部分失败展示:批量确认响应返回 `confirmedChapterResultIds`、`failedChapters`、`skippedChapters` 和 `partialFailure` 标记。前端按逐章结果展示成功、失败原因和可重试项;某章失败不影响已成功章节。
- 导出入口属于作品工作台,必须展示服务端返回的已包含/已排除导出清单(included/excluded manifest)、排除原因和可恢复动作。
- 下载凭证有时效和授权快照;凭证过期、来源被召回、授权被撤销或任务进入需重验时,前端必须禁用下载并引导重新检查或重新导出。
- 导出成功态不能压扁成单一“下载成功”;页面还要保留导出记录、下载状态、凭证失效、来源撤销后重验和部分内容被排除的说明。
## 13. 与管理后台关系
管理后台可以查看内容异常、导入导出记录、任务失败和治理摘要,但不承载普通用户写作台。管理员不能通过后台替用户接受 AI 候选、保存正文或确认作品知识。
## 14. 关联阅读
- 用户工作区规格:`产品-02C-用户工作区与作品工作台功能规格.md`
- 普通用户操作流程:`流程-01B-普通用户操作流程(操作视角).md`
- 普通用户系统流程:`流程-02B-普通用户系统处理流程(系统视角).md`
- Accept 专题:`专题-01-正文建议接受(Accept Suggestion)实现规范.md`
- 质量门控专题:`专题-04-生成质量门控与创作健康度设计方案.md`