Files
new-markdown/docs/02-architecture.md

67 lines
6.7 KiB
Markdown
Raw Permalink 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.
# 阶段 0 · 产品架构设计
> 对齐需求文档 §1–§19。本文件是阶段 1–7 的施工图:模块边界、数据流、关键机制。
> 界面结构与操作逻辑按需求 §3 定稿,本文件不复述菜单清单,只定实现结构。
## 1. 总体结构
```text
┌──────────────────────────── Tauri 2 应用 ────────────────────────────┐
│ 前端 (React + TS) │
│ ├─ app/ 窗口装配:标题栏、菜单、标签页、侧边栏、状态栏 │
│ ├─ editor/ 编辑器装配层(Milkdown Kit 组装、命令、装饰、序列化) │
│ ├─ features/ 文件树 / 大纲 / 查找替换 / 图片 / 导出 / 主题 / 设置 │
│ └─ stores/ 文档会话状态(每标签一份 EditorSession) │
│ │ invoke / event(Tauri IPC) │
│ 后端 (Rust) │
│ ├─ fs 命令 读/写(临时文件+原子替换)、目录遍历、监听外部变更 │
│ ├─ sqlite 设置 / 最近文件 / 工作区 / 恢复记录(不存正文) │
│ └─ export PDF 打印管线、DOCX 生成等重活与系统能力 │
└───────────────────────────────────────────────────────────────────────┘
```
职责红线:正文只在前端编辑器文档模型与磁盘 .md 之间流动;Rust 侧不解析 Markdown 结构(导出管线除外);SQLite 永不成为正文唯一副本。
## 2. 编辑器装配层(核心)
阶段 0 原型 `prototype/src/editor.ts` 即装配层的雏形,正式版按此扩展:
- **创建工厂**:`createMarkdownEditor(root, markdown, onUpdate)` —— commonmark + gfm + history + listener + clipboard + indent。阶段 2/3 在同一工厂按序叠加:源码模式桥、数学、Mermaid、代码高亮装饰、表格浮动工具栏、图片节点视图。UI 与测试共用工厂,保证测过的即交付的。
- **文档模型**:ProseMirror Node 树为唯一编辑态;Markdown 文本只是它的序列化投影。打开 = remark 解析建模;保存 = serializer 序列化。禁止任何模块绕过模型直接拼接 md 文本修改文档(查找替换、标题拖拽排序等结构操作一律走事务)。
- **序列化策略**:`remarkStringifyOptionsCtx` 统一配置(当前 `bullet: '-'`);序列化只在保存/导出/源码模式切换时全量执行,编辑期仅 listener 节流通知脏状态,不逐键全量序列化(性能纪律)。
- **输入规则与标记显隐**:Typora 式「当前节点显示标记、其余隐藏」用 ProseMirror Decoration 按选区所在节点动态切换(阶段 2 核心工作),不触发文档事务、不进历史栈。
- **IME**:不拦截 composition 事件、不在 composition 期间跑输入规则(ProseMirror View 原生语义 + 装配层显式守卫,阶段 2 写进编辑器测试清单并在 Windows 真机用微软拼音/搜狗各验一轮)。
- **历史**:history 插件独立栈;格式切换、结构命令均以单事务提交,保证一次 Ctrl+Z = 一次用户动作。
## 3. 文档会话与数据安全(需求 §8/§17)
- 每个标签页 = 一个 `EditorSession`:{ 文件路径 | 未命名、文档模型、脏标记、编码/换行符、上次保存哈希 }。
- **保存**:序列化 → 写同目录临时文件 → 原子替换 → 更新哈希。全程失败(权限/磁盘满)向用户明确报错,保留脏状态与恢复记录,绝不静默丢弃。
- **自动保存**:可配置延迟(默认停顿 2s 后、仅对已命名且无外部冲突的文档),走同一保存管线。
- **恢复记录**:每次编辑节流写入 SQLite recovery_records(文档键 + 序列化全文 + 时间戳);正常关闭清除;异常启动时提示恢复。
- **外部修改检测**:Rust 监听已打开文件;外部变更且本地无修改 → 静默重载;本地已修改 → 弹窗三选(重载丢弃 / 保留本地另存 / 对比),不自动覆盖任何一方。
- **编码**:读入探测 UTF-8 / UTF-8 BOM / GBK(Rust 侧解码),内部统一 UTF-8;保存默认 UTF-8(保留原 BOM 策略可配置),换行符 LF/CRLF 按原文或设置。
## 4. UI 结构(需求 §3 的实现映射)
- **窗口**:Tauri 自定义标题栏(decorations 关闭 + 前端标题栏组件),拖动区、双击最大化、最小/最大/关闭走 window API;Win10/11 同一实现。
- **布局**:菜单栏(原生菜单语义的自绘实现,保证快捷键与禁用态一致)→ 标签栏 → [可折叠侧边栏 | 编辑区] → 状态栏。侧边栏宽度/状态持久化;编辑区正文容器限宽居中(主题变量控制),侧边栏开合不改变正文宽度设定。
- **侧边栏双模式**:文件树(Rust 目录遍历 + 懒加载)/ 大纲(由文档模型标题节点实时投影,点击定位、跟随光标高亮、拖拽排序转结构事务)。
- **主题**:两层——应用 UI 主题(CSS 变量)与文档主题(作用域限定在 `.editor-doc` 容器内的 CSS,自定义主题 CSS 经作用域重写后注入,无法污染应用 UI,对应需求 §11.2 红线)。内置 7 主题阶段 5 自行实现。
- **设置中心**:左分类右内容,全部落 SQLite settings 表,重启生效;快捷键表独立存储并做冲突检测(需求 §14/§15)。
## 5. 导入导出(需求 §12/§13,阶段 5)
- 导出 HTML:由文档模型经 remark 管线生成 + 当前文档主题 CSS 内联,图片相对路径可选打包为独立文件目录或 base64 单文件。
- 导出 PDF / 打印:隐藏打印视图 + 专用 print CSS,WebView2 打印管线;页眉页脚/页码走打印参数。
- 导出 DOCX:Rust 侧(docx 生成库)按模型结构映射标题/列表/表格/图片。
- 导入 TXT/HTML:转 Markdown 后建模;DOCX/EPUB 排后续阶段。
## 6. 目录结构
按需求 §22 建议落地,阶段 1 建仓时创建(`src/editor/` 内部细分为 core/extensions/markdown/commands/decorations/serializers)。阶段 0 仓库当前只有 `docs/`、`prototype/`、`samples/`,不预铺正式工程空架子。
## 7. 阶段门禁
每阶段:构建通过 + 该阶段自动化测试 + 人工验收清单(见 03 号报告模板)→ 大王确认 → 下一阶段。编辑器相关阶段额外要求:往返稳定性测试套件(阶段 0 已建)必须全绿,新增语法支持必须先给套件加用例。