# Tydora 产品设计文档

> 版本：0.0.10 | 更新日期：2026-07-27

---

## 目录

1. [产品概述](#1-产品概述)
2. [功能架构总览](#2-功能架构总览)
3. [编辑器系统](#3-编辑器系统)
4. [侧栏系统](#4-侧栏系统)
5. [WikiLink 知识管理系统](#5-wikilink-知识管理系统)
6. [多窗口架构](#6-多窗口架构)
7. [思维导图](#7-思维导图)
8. [知识图谱](#8-知识图谱)
9. [文件预览](#9-文件预览)
10. [主题系统](#10-主题系统)
11. [命令面板与快速打开](#11-命令面板与快速打开)
12. [发布系统](#12-发布系统)
13. [设置系统](#13-设置系统)
14. [图片管理](#14-图片管理)
15. [自动更新](#15-自动更新)
16. [全局快捷键汇总](#16-全局快捷键汇总)
17. [数据持久化](#17-数据持久化)
18. [后端服务（Rust）](#18-后端服务rust)
19. [技术栈与依赖](#19-技术栈与依赖)
20. [已知限制与未来规划](#20-已知限制与未来规划)

---

## 1. 产品概述

### 1.1 产品定位

Tydora 是一款基于 Tauri v2 + React 19 的桌面 Markdown 编辑器，专为知识管理和笔记场景设计。产品融合了 WYSIWYG 与源码两种编辑模式，提供 Obsidian 风格的双向链接系统，并支持将笔记发布为静态网站。

### 1.2 核心理念

- **双模式编辑**：即时渲染（IR）模式提供所见即所得的编辑体验，源码（SV）模式满足精确控制需求
- **仓库级知识管理**：以"仓库（Vault）"为单位组织文件，支持多仓库切换
- **双向链接**：`[[wiki-link]]` 语法构建知识网络，自动生成反向链接关系
- **发布即用**：一键将笔记仓库发布为可部署的静态网站

### 1.3 目标平台

| 平台 | 优先级 | 打包格式 |
|------|--------|----------|
| Windows | 主要 | NSIS 安装包 |
| macOS | 支持 | DMG |
| Linux | 支持 | AppImage |

### 1.4 技术栈

| 层级 | 技术 |
|------|------|
| 前端框架 | React 19 + TypeScript |
| 构建工具 | Vite 6 |
| 编辑器引擎 | TipTap 3.x（WYSIWYG）+ CodeMirror 6（源码） |
| Markdown 序列化 | tiptap-markdown |
| 桌面框架 | Tauri v2（Rust 后端） |
| 可视化 | D3.js（图谱）、markmap（思维导图）、mermaid（图表） |
| 语法高亮 | highlight.js、lowlight |

---

## 2. 功能架构总览

### 2.1 模块关系

```
┌─────────────────────────────────────────────────────────────┐
│                        主窗口 (App)                          │
│  ┌──────────┐  ┌──────────────────────┐  ┌───────────────┐  │
│  │  侧栏    │  │      编辑器区域       │  │  反向链接面板  │  │
│  │ ┌──────┐ │  │ ┌──────────────────┐ │  │               │  │
│  │ │文件树│ │  │ │  TipTapEditor    │ │  │  Backlinks    │  │
│  │ ├──────┤ │  │ │  (IR 模式)       │ │  │  Panel        │  │
│  │ │ 大纲 │ │  │ ├──────────────────┤ │  │               │  │
│  │ ├──────┤ │  │ │ CodeMirrorEditor │ │  └───────────────┘  │
│  │ │ 搜索 │ │  │ │  (SV 模式)       │ │                     │
│  │ ├──────┤ │  │ └──────────────────┘ │                     │
│  │ │仓库  │ │  │  ┌────────────────┐  │                     │
│  │ │切换器│ │  │  │WikiLink 补全   │  │                     │
│  │ └──────┘ │  │  └────────────────┘  │                     │
│  └──────────┘  └──────────────────────┘                     │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ 顶栏：文件名 | 保存状态 | 模式 | 字数 | 更新 | 窗口控制 │   │
│  └──────────────────────────────────────────────────────┘   │
│  ┌──────────────────────────────────────────────────────┐   │
│  │ 底栏：字数统计 | 视图模式                              │   │
│  └──────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘
                           │
          ┌────────────────┼────────────────┐
          ▼                ▼                ▼
   ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
   │  设置窗口    │ │ 思维导图窗口 │ │ 知识图谱窗口 │
   │  (独立)     │ │  (独立)     │ │  (独立)     │
   └─────────────┘ └─────────────┘ └─────────────┘
                           │
                           ▼
                    ┌─────────────┐
                    │  发布系统    │
                    │ (静态网站)  │
                    └─────────────┘
```

### 2.2 核心模块清单

| 模块 | 职责 | 关键文件 |
|------|------|----------|
| 编辑器 | Markdown 内容编辑 | `TipTapEditor.tsx`, `CodeMirrorEditor.tsx` |
| 侧栏 | 文件管理、大纲、搜索 | `Sidebar.tsx` |
| WikiLink | 双向链接系统 | `LinkIndexService.ts`, `LinkParser.ts`, `WikiLinkAutocomplete.tsx` |
| 主题 | 外观定制 | `ThemeManager.ts`, `CustomThemeManager.ts`, `themes.tsx` |
| 设置 | 应用配置 | `Settings.tsx` |
| 发布 | 静态网站生成 | `PublishPanel.tsx`, `PublishService.ts` |
| 可视化 | 思维导图、知识图谱 | `MindmapView.tsx`, `GraphView.tsx` |
| 多窗口 | 独立窗口管理 | `lib.rs` (Rust 命令) |

---

## 3. 编辑器系统

### 3.1 双模式架构

Tydora 提供两种编辑模式，通过 `Ctrl+/` 快捷键切换：

| 模式 | 标识 | 引擎 | 适用场景 |
|------|------|------|----------|
| 即时渲染 (IR) | `"ir"` | TipTap 3.x | 日常写作、WYSIWYG 体验 |
| 源码模式 (SV) | `"sv"` | CodeMirror 6 | 精确控制 Markdown 语法 |

默认模式可在设置中配置（编辑器 → 默认模式）。

### 3.2 TipTap 编辑器

基于 TipTap 3.x 构建，注册 22+ 扩展，通过 `forwardRef` + `useImperativeHandle` 暴露编辑器 API。

#### 核心扩展

| 扩展 | 用途 |
|------|------|
| StarterKit | 核心扩展集合（段落、代码块、链接、格式等） |
| Bold / Italic / Strike / Code | 行内格式化 |
| Blockquote | 引用块（扩展支持 Callout 序列化） |
| BulletList / OrderedList / ListItem | 列表 |
| Heading | H1-H6 标题 |
| Placeholder | 占位符文本 |
| CodeBlockLowlight | 语法高亮代码块 |
| Image | 图片（支持 inline、base64、本地文件） |
| Link | 超链接 |
| Table / TableRow / TableCell / TableHeader | 可调整大小的表格 |
| TaskList / TaskItem | 任务列表（支持嵌套） |
| Highlight | 文本高亮 |
| Typography | 智能排版 |
| Markdown (tiptap-markdown) | Markdown ↔ HTML 双向转换 |

#### 自定义扩展

| 扩展 | 文件 | 功能 |
|------|------|------|
| WikiLink | `extensions/wiki-link.ts` | `[[双向链接]]` 节点，支持 `[[note#heading\|alias]]` 语法 |
| SearchHighlight | `extensions/search-highlight.ts` | 搜索结果高亮装饰器 |
| CodeBlockToolbar | `extensions/code-block-toolbar.ts` | 代码块浮动工具栏（语言选择、复制、折叠、行号） |
| TableFloatingToolbar | `extensions/table-floating-toolbar.ts` | 表格浮动工具栏（对齐、行列操作） |
| Frontmatter | `extensions/frontmatter.ts` | YAML frontmatter 块，语法高亮，可折叠 |
| Callout | `extensions/callout.ts` | GitHub 风格提示块（15 种类型） |
| Mermaid | `extensions/mermaid.ts` | Mermaid 图表实时预览，内嵌 CodeMirror 编辑器 |

#### Callout 类型

支持 15 种 GitHub 风格的 Callout，每种都有独特图标和标签：

| 类型 | 标签 | 语法 |
|------|------|------|
| note | 注意 | `[!NOTE]` |
| tip | 提示 | `[!TIP]` |
| important | 重要 | `[!IMPORTANT]` |
| warning | 警告 | `[!WARNING]` |
| caution | 注意 | `[!CAUTION]` |
| abstract | 摘要 | `[!ABSTRACT]` |
| info | 信息 | `[!INFO]` |
| success | 成功 | `[!SUCCESS]` |
| question | 问题 | `[!QUESTION]` |
| failure | 失败 | `[!FAILURE]` |
| danger | 危险 | `[!DANGER]` |
| bug | Bug | `[!BUG]` |
| example | 示例 | `[!EXAMPLE]` |
| quote | 引用 | `[!QUOTE]` |
| FAQ | FAQ | `[!FAQ]` |

Callout 支持 `+`/`-` 修饰符控制折叠状态。

#### 编辑器 API（EditorHandle）

通过 `useImperativeHandle` 暴露的方法：

| 方法 | 说明 |
|------|------|
| `getValue()` | 获取 Markdown 内容 |
| `setValue(val)` | 设置内容（带内部标志防止循环） |
| `insertTextAtCursor(text)` | 在光标处插入文本 |
| `replaceRangeWithWikiLink(from, note, heading?, display?)` | 替换范围为 WikiLink 节点 |
| `resize()` | 重新聚焦编辑器 |
| `highlightSearch(query)` | 搜索高亮 |
| `clearHighlight()` | 清除高亮 |
| `executeCommand(name)` | 执行命名命令 |
| `scrollToHeading(text, line)` | 滚动到标题 |
| `scrollToLine(line)` | 滚动到行 |
| `getCursorOffset()` | 获取光标位置 |
| `isSourceMode()` | 检查当前模式 |

### 3.3 CodeMirror 编辑器

源码模式使用 CodeMirror 6，功能包括：

- **语言自动检测**：根据文件扩展名识别 20+ 语言（md、js、ts、tsx、jsx、html、css、json、xml、yaml 等）
- **语法高亮**：两套主题 — `markdownHighlighting`（标题大小、强调等）和 `codeHighlighting`（程序代码）
- **编辑功能**：行号、活动行高亮、代码折叠、括号匹配、自动关闭括号、自动补全、搜索高亮、自动换行
- **主题同步**：监听 `code-theme-changed` 事件动态切换高亮主题

### 3.4 Markdown 序列化

使用 `tiptap-markdown` 扩展实现双向转换：

```typescript
// 获取 Markdown
const md = (editor.storage as any).markdown.getMarkdown();

// 设置内容（HTML 或 Markdown）
editor.commands.setContent(htmlOrMarkdown);
```

### 3.5 图片处理

- **粘贴拦截**：拦截 `image/*` 剪贴板内容，自动保存到 vault 并插入图片节点
- **拖拽支持**：拖拽图片文件到编辑器自动保存并插入
- **图片存储**：通过 ImageManager 保存到 vault-assets 目录
- **路径解析**：自定义 Image NodeView 解析相对路径，支持本地文件和远程图片
- **远程图片**：通过 Rust `fetch_remote_image` 代理加载外部图片

### 3.6 链接编辑行为（IR 模式）

- **点击链接**：将渲染的链接转换为 Markdown 源码 `[text](url)` 进行编辑
- **点击外部**：恢复渲染的链接
- **Ctrl+Click**：打开链接（外部链接通过 `open_url`，本地文件通过 `open_file`）
- **Escape**：恢复正在编辑的链接

### 3.7 表格浮动工具栏

选中表格时显示浮动工具栏，功能包括：

| 功能 | 说明 |
|------|------|
| 网格选择器 | 8×10 网格调整表格尺寸 |
| 对齐 | 左对齐、居中、右对齐 |
| 插入行 | 在上方/下方插入行 |
| 插入列 | 在左侧/右侧插入列 |
| 删除 | 删除行/列 |
| 合并 | 合并单元格 |
| 拆分 | 拆分单元格 |
| 删除表格 | 删除整个表格 |

### 3.8 代码块工具栏

代码块上方显示浮动工具栏：

| 功能 | 说明 |
|------|------|
| 语言选择 | 30+ 语言下拉选择，支持搜索 |
| 复制代码 | 一键复制到剪贴板 |
| 删除 | 删除代码块 |
| 折叠 | 折叠/展开代码块 |
| 行号 | 可配置的行号显示 |

### 3.9 右键菜单

编辑器内右键显示图标网格布局菜单：

| 行 | 功能 |
|----|------|
| 第一行（剪贴板） | 剪切、复制、粘贴、删除 |
| 第二行（行内） | 加粗、斜体、删除线、行内代码、链接 |
| 第三行（块级） | 引用、无序列表、有序列表、任务列表、高亮 |
| 子菜单 | 标题（H1-H6、段落）、插入（图片、分割线、表格、代码块、数学公式、WikiLink） |

每个菜单项显示对应快捷键。

### 3.10 快捷键系统

支持 45+ 可自定义快捷键，分为 10 个分类：

| 分类 | 示例 |
|------|------|
| 格式 | 加粗、斜体、删除线、行内代码、代码块、链接、高亮、引用、分割线 |
| 列表 | 无序列表、有序列表、任务列表、缩进、任务状态切换 |
| 标题 | H1-H6、段落 |
| 插入 | 表格、上方/下方插入 |
| 表格 | 插入行/列、删除行/列、对齐 |
| 编辑 | 撤销、重做、全选 |
| 视图 | 侧栏、打字机模式、思维导图 |
| 模式 | 切换到 IR/SV 模式 |
| 系统 | Escape、快速打开、命令面板 |

快捷键支持：
- 点击录制新的快捷键组合
- 按键组合搜索过滤
- 单个快捷键重置为默认
- 全部重置

---

## 4. 侧栏系统

### 4.1 文件树

递归渲染的目录文件结构，功能包括：

| 功能 | 说明 |
|------|------|
| 懒加载 | 点击展开时才加载子目录内容 |
| 排序 | 目录优先，然后按字母排序 |
| 隐藏点文件 | 不显示以 `.` 开头的文件 |
| 活跃高亮 | 当前打开的文件高亮显示 |
| 状态保持 | 展开/折叠状态在文件切换时保持 |
| 拖拽移动 | 鼠标拖拽文件到目标目录（5px 阈值） |
| 内联重命名 | 点击重命名显示输入框，Enter 确认，Escape 取消 |

### 4.2 文件操作菜单

右键菜单支持以下操作：

| 操作 | 文件菜单 | 文件夹菜单 | 空白区域菜单 |
|------|----------|------------|--------------|
| 新建文件 | ✓ | ✓ | ✓ |
| 新建文件夹 | ✓ | ✓ | ✓ |
| 重命名 | ✓ | ✓ | - |
| 删除 | ✓（确认对话框） | ✓（确认对话框） | - |
| 复制路径 | ✓ | ✓ | ✓ |
| 在新窗口打开 | ✓ | - | - |
| 在系统管理器打开 | ✓ | ✓ | ✓ |
| 创建副本 | ✓ | - | - |
| 搜索 | ✓ | ✓ | ✓ |

### 4.3 大纲

解析 Markdown 内容中的 `# ~ ######` 标题，渲染为层级列表：

- 支持 H1-H6 六级标题
- 点击标题滚动编辑器到对应位置
- 空内容时显示"无标题"提示

### 4.4 搜索系统

跨文件增量搜索功能：

| 特性 | 说明 |
|------|------|
| 触发方式 | 侧栏搜索按钮 或 `Ctrl+Shift+F` |
| 搜索范围 | Vault 内 35+ 可搜索文件类型 |
| 并发控制 | 12 个并发文件读取 |
| 结果上限 | 最多 50 条结果 |
| 文件缓存 | 已读取文件缓存提高性能 |
| 文件大小限制 | 跳过超过 1MB 的文件 |
| 防抖 | 150ms 防抖，支持取消信号 |
| 结果展示 | 文件名 + 行号 + 高亮匹配文本 |
| 跳转 | 点击结果打开文件并滚动到匹配行 |

### 4.5 仓库切换器

底部仓库管理区域：

| 状态 | 显示内容 |
|------|----------|
| 空仓库 | "打开仓库"按钮 + 设置齿轮 |
| 有仓库 | 当前仓库名 + 齿轮图标 |

仓库菜单包含：
- 仓库列表（活跃仓库标记）
- 每个仓库的移除按钮（X）
- "打开新仓库"选项
- "发布为网站"选项
- 设置按钮（打开设置窗口）

### 4.6 侧栏调整

- 拖拽右侧边缘调整宽度
- 最小宽度 180px，最大宽度 800px
- 宽度持久化到 localStorage

---

## 5. WikiLink 知识管理系统

### 5.1 语法规范

Tydora 支持 Obsidian 风格的 WikiLink 语法：

| 语法 | 说明 | 示例 |
|------|------|------|
| `[[note]]` | 链接到笔记 | `[[我的笔记]]` |
| `[[note#heading]]` | 链接到笔记的特定标题 | `[[我的笔记#第一章]]` |
| `[[note\|alias]]` | 带别名的链接 | `[[我的笔记\|别名]]` |
| `[[note#heading\|alias]]` | 带标题和别名 | `[[我的笔记#第一章\|第一章]]` |
| `![[embed]]` | 嵌入笔记内容 | `![[我的笔记]]` |
| `[[[note]]]` | 中括号语法（中文输入法兼容） | `[[[我的笔记]]]` |

### 5.2 自动补全

输入 `[[` 时触发自动补全：

| 特性 | 说明 |
|------|------|
| 触发条件 | 输入 `[[`（中英文括号均支持） |
| 搜索方式 | 模糊匹配笔记名称 |
| 键盘导航 | ↑/↓ 或 Ctrl+J/K 选择 |
| 确认选择 | Enter |
| 关闭 | Escape |
| 无匹配 | 显示"无匹配，Enter 创建新笔记" |
| 定位 | 视口感知定位（上方/下方自动切换） |

### 5.3 链接索引服务

`LinkIndexService` 单例维护三个核心索引：

| 索引 | 类型 | 说明 |
|------|------|------|
| `outlinks` | `Map<filePath, noteName[]>` | 每个文件链接到哪些笔记 |
| `backlinks` | `Map<noteName, filePath[]>` | 每个笔记被哪些文件链接 |
| `fileByName` | `Map<noteName, filePath>` | 按笔记名快速查找文件 |

操作方法：
- `buildIndex(vaultPath)` — 全量重建（批量读取所有 .md 文件）
- `updateFileLinks(filePath, vaultPath)` — 增量更新单个文件
- `removeFile(filePath)` — 清理已删除文件的索引
- `getBacklinks(noteName)` / `getOutlinks(filePath)` — 查询操作
- `findFileByNoteName(noteName)` — 精确匹配，然后大小写不敏感匹配（最短路径优先）
- `searchNotes(query)` — 模糊搜索用于自动补全
- `serialize()` / `deserialize(json)` — JSON 序列化用于跨窗口传输

### 5.4 反向链接面板

可折叠面板显示当前文件的链接关系：

| 区域 | 说明 |
|------|------|
| 反向链接 | 哪些文件通过 `[[note]]` 引用了当前笔记，附带上下文段落（最多 200 字符） |
| 出链 | 当前文件引用了哪些笔记 |

点击链接跳转到对应文件。

### 5.5 链接存在性标记

- 有效链接：`data-exists="true"`，渲染为可点击的样式化链接
- 无效链接：`data-exists="false"`，渲染为不同颜色（表示目标笔记不存在）

### 5.6 嵌入支持

`![[embed]]` 语法嵌入笔记内容：
- 异步加载目标笔记内容
- 显示前 500 字符
- 渲染为引用块样式

### 5.7 文件监听与索引同步

基于 Rust `notify` crate 的实时文件监听：
- Vault 切换时自动启动监听
- 文件变更事件防抖处理（300ms）
- 自动增量更新 LinkIndexService 索引
- 组件卸载或 Vault 切换时停止监听

---

## 6. 多窗口架构

### 6.1 窗口类型

| 窗口 | 触发方式 | 默认大小 | 特性 |
|------|----------|----------|------|
| 主窗口 | 应用启动 | 1200×800 | 编辑器、侧栏等核心 UI |
| 设置窗口 | `open_settings_window` | 800×600 | 独立设置面板，无装饰 |
| 文件窗口 | `open_file_in_new_window` | 1200×800 | 独立编辑文件 |
| 思维导图窗口 | `open_mindmap_window` | 900×600 | Markmap 可视化 |
| 知识图谱窗口 | `open_graph_window` | 1000×700 | D3.js 力导向图 |

### 6.2 窗口特性

- **无装饰窗口**：所有窗口使用自定义标题栏（最小化、最大化/还原、关闭）
- **窗口状态持久化**：位置、大小、最大化状态保存到 localStorage
- **多显示器支持**：启动时验证窗口位置是否在可见显示器上
- **防抖保存**：窗口移动和调整大小时 300ms 防抖保存状态
- **单实例控制**：设置、思维导图、图谱窗口已存在时聚焦而非新建

### 6.3 跨窗口通信

- **Tauri 事件**：`theme-changed`（主题同步）、`mindmap-content-update`（思维导图内容同步）、`open-file`（文件窗口打开文件）
- **localStorage**：`zmd-mindmap-content`（思维导图内容缓存）
- **JSON 序列化**：LinkIndexService 的 `serialize()`/`deserialize()` 跨窗口传输链接索引

---

## 7. 思维导图

### 7.1 渲染引擎

基于 markmap-lib（转换器）和 markmap-view（渲染器），将 Markdown 标题层级转换为交互式思维导图。

### 7.2 交互功能

| 操作 | 说明 |
|------|------|
| 右键拖拽 | 平移视图 |
| 键盘导航 | 方向键在节点间移动 |
| Enter/Space | 折叠/展开节点 |
| 缩放 | 按钮或滚轮缩放 |
| 适配视图 | 自动适配所有节点 |
| 展开级别 | 选择 1-6 级或全部展开 |

### 7.3 工具栏

| 按钮 | 功能 |
|------|------|
| 适配 | 自动适配视图 |
| 放大 | 放大视图 |
| 缩小 | 缩小视图 |
| 展开级别 | 下拉选择 1-6 或全部 |

### 7.4 配置项

| 配置 | 说明 | 默认值 |
|------|------|--------|
| maxWidth | 最大节点宽度 | - |
| duration | 动画时长 | 300ms |
| spacing | 水平/垂直间距 | - |
| lineWidth | 连线宽度 | - |
| initialExpandLevel | 初始展开级别 | - |
| colorFreezeLevel | 颜色冻结层级 | - |

### 7.5 实时同步

- 主窗口内容变更时通过 Tauri 事件 `mindmap-content-update` 同步
- localStorage 轮询作为备用同步机制（1 秒间隔）
- 思维导图窗口独立监听文件变更

---

## 8. 知识图谱

### 8.1 渲染引擎

基于 D3.js 力导向图（force-directed graph），可视化 Vault 中的 WikiLink 关系网络。

### 8.2 视觉编码

| 元素 | 编码方式 |
|------|----------|
| 节点大小 | 与入链数量成正比 |
| 节点颜色 | 按目录分组（d3.schemeTableau10 调色板） |
| 标签 | 显示笔记名称 |
| 边 | 表示 `[[link]]` 关系 |

### 8.3 交互功能

| 操作 | 说明 |
|------|------|
| 拖拽节点 | 重新定位节点 |
| 缩放平移 | 滚轮缩放，拖拽平移 |
| 悬停 | 高亮关联节点和边，淡化其他元素 |
| 工具提示 | 显示笔记名称和链接数 |
| 点击节点 | 打开笔记并关闭图谱 |
| Escape | 关闭图谱 |

### 8.4 配置项

| 配置 | 说明 |
|------|------|
| 节点大小 | 节点半径基础值 |
| 标签字号 | 节点标签字体大小 |
| 链接距离 | 节点间连线长度 |
| 电荷强度 | 节点间排斥力 |
| 边透明度 | 连线透明度 |

### 8.5 独立窗口

- 从 localStorage 缓存加载链接索引
- 异步刷新索引数据
- 文件监听自动刷新图谱
- 点击节点通过 Tauri 事件 `open-file` 通知主窗口打开文件

---

## 9. 文件预览

### 9.1 支持格式

| 类型 | 扩展名 | 功能 |
|------|--------|------|
| 图片 | jpg, png, gif, webp, bmp, ico, svg, avif, heic, heif | 滚轮缩放（0.1x-5x）、重置按钮 |
| 视频 | mp4, webm, ogg, mov, avi, mkv, wmv, flv, m4v | 原生播放控件 |
| 音频 | mp3, wav, ogg, flac, aac, m4a, wma | 音乐图标 + 原生控件 |
| PDF | pdf | iframe 嵌入 |
| 其他 | - | 文件图标 + "无法预览"提示 |

### 9.2 文件类型检测

- `isEditableFile()` 检查 35+ 扩展名判断是否在编辑器中打开
- `isMarkdownFile()` 判断使用 TipTap 还是 CodeMirror
- 非可编辑文件在 FilePreview 中展示

### 9.3 图片预览特性

- 滚轮缩放：0.1x 到 5x
- 重置按钮：恢复原始大小
- 返回按钮：返回文件树
- 文件名显示

---

## 10. 主题系统

### 10.1 内置主题

8 种精心设计的内置主题：

| 主题 | 风格 |
|------|------|
| white | 简洁白净 |
| mint | 薄荷绿（默认） |
| mint-dark | 薄荷暗色 |
| liquid-glass | 液态玻璃 |
| claude-code | Claude Code 风格 |
| purple | 紫色系 |
| hermes | Hermes 风格 |
| next | 未来感 |

### 10.2 自定义主题

- **导入**：从 CSS 文件导入自定义主题
- **编辑**：变量编辑器支持颜色选择器（颜色变量）、滑块（尺寸变量）、文本输入（其他变量）
- **删除**：删除已导入的自定义主题
- **存储**：主题文件存储在 `appDataDir/themes/`，manifest.json 追踪元数据
- **CSS 解析**：自动解析 `:root`、`.dark`、`[data-theme]` 选择器，转换为 `[data-theme="custom-{id}"]`

### 10.3 代码主题

11 种内置代码语法高亮配色：

| 主题 | 风格 |
|------|------|
| GitHub Light | GitHub 浅色 |
| Atom One Light | Atom One 浅色 |
| VS Code Light | VS Code 浅色 |
| Solarized Light | Solarized 浅色 |
| GitHub Dark | GitHub 深色 |
| Atom One Dark | Atom One 深色 |
| VS Code Dark | VS Code 深色 |
| Nord | Nord 配色 |
| Monokai | Monokai |
| Dracula | Dracula |
| Solarized Dark | Solarized 深色 |

- **Auto 模式**：跟随应用主题（浅色 → github-light，深色 → github-dark）
- **自定义代码主题**：支持导入自定义代码主题
- **主题同步**：通过 `code-theme-changed` 事件同步到 CodeMirror 编辑器

### 10.4 跨窗口同步

- 主题变更通过 Tauri 事件 `theme-changed` 同步到所有窗口
- CSS 变量通过 `document.documentElement.dataset.theme` 设置
- 自定义主题 CSS 注入为 `<style>` 元素，切换时启用/禁用

---

## 11. 命令面板与快速打开

### 11.1 命令面板（Ctrl+P）

全屏覆盖层，提供 48+ 命令的快速访问：

| 分类 | 命令 |
|------|------|
| 文件 | 保存、打开、新窗口 |
| 编辑 | 撤销、重做 |
| 视图 | 侧栏、模式、打字机、思维导图、图谱、发布 |
| 模式 | 切换到 IR/SV |
| 格式 | 加粗、斜体、删除线、行内代码、代码块、链接、引用、分割线、表格 |
| 列表 | 无序、有序、任务 |
| 标题 | H1-H6、段落 |
| 插入 | 图片、脚注、目录、数学公式 |
| 窗口 | 最小化、最大化、关闭 |
| 设置 | 打开设置、各设置标签页 |

特性：
- 模糊搜索评分，支持别名
- 最近命令（最多 5 条）存储在 localStorage
- 键盘导航：↑/↓、Ctrl+J/K、Enter 执行、Escape 关闭
- 搜索结果高亮匹配文本

### 11.2 快速打开（Ctrl+O）

快速文件打开覆盖层：

| 模式 | 说明 |
|------|------|
| 无查询 | 显示最近文件（每个 Vault 最多 20 条） |
| 有查询 | 递归加载 Vault 所有文件，模糊匹配 |

匹配排序：精确匹配 > 前缀匹配 > 包含匹配 > 路径匹配
结果上限：50 条
显示：文件名 + 相对路径

---

## 12. 发布系统

### 12.1 发布流程

```
配置发布设置 → 点击"开始发布" → 构建静态网站 → 完成/预览/打开目录
```

### 12.2 发布面板状态

| 状态 | 显示 |
|------|------|
| 空闲 | 描述文本 + "开始发布"按钮 |
| 发布中 | 不确定进度条 + "正在构建静态网站..." |
| 完成 | 成功消息 + "预览站点" + "打开输出目录" |
| 错误 | 错误消息 + 警告图标 |

### 12.3 发布设置

| 配置项 | 说明 | 可选值 |
|--------|------|--------|
| 站点名称 | 网站标题 | 自由文本 |
| 站点描述 | 网站描述 | 自由文本 |
| 语言 | 网站语言 | zh / en / ja / ko |
| 站点 URL | 部署地址 | URL |
| 页脚 | 页脚内容 | 自由文本 |
| 仓库目录 | Vault 相对路径 | 路径 |
| 构建模式 | 构建范围 | 完整发布 / 仅公开笔记 |
| Base Path | GitHub Pages 路径 | 路径 |
| 输出目录 | 构建输出位置 | 路径（支持浏览选择） |

构建模式说明：
- **完整发布**：发布所有 Markdown 文件
- **仅公开笔记**：仅发布 frontmatter 中包含 `publish: public` 的文件

### 12.4 发布服务

- 配置文件：`markdown-publish.config.json`（存储在 Vault 根目录）
- CLI 工具：`@abstractwebunit/markdown-publish`
- 后处理：自动执行 `website/postbuild.mjs` 脚本（注入落地页样式等）

### 12.5 预览服务器

- 基于 Node.js 内置 HTTP 服务器
- 监听 `127.0.0.1:3000`
- 支持 SPA 路由（index.html 回退）
- 自动打开浏览器
- 支持停止服务器

---

## 13. 设置系统

### 13.1 窗口特性

- 独立 Tauri 窗口（800×600，无装饰）
- 左侧导航栏支持搜索过滤（中英文）
- 自定义窗口控件
- 窗口状态持久化
- `Ctrl+W` 关闭设置窗口

### 13.2 设置标签页

#### 通用（General）

| 配置项 | 说明 | 选项 |
|--------|------|------|
| 外观 | 应用主题模式 | 跟随系统 / 浅色 / 深色 |
| 编辑器字体 | 字体选择 | 7 种（含霞鹜文楷 LXGW WenKai） |
| 字号 | 编辑器字号 | 10-24px |
| 自动保存 | 内容变更自动保存 | 开关 |

#### 主题（Theme）

- 8 种内置主题网格展示
- 自定义主题导入/编辑/删除
- 代码主题选择器（12 内置 + 自定义）
- 主题变量编辑器（颜色选择器、滑块、文本输入）

#### 快捷键（Shortcuts）

- 45+ 快捷键按分类展示
- 搜索过滤（支持按键组合搜索）
- 点击录制新快捷键
- 单个重置 / 全部重置

#### 编辑器（Editor）

| 配置项 | 说明 | 选项 |
|--------|------|------|
| 默认模式 | 启动时的编辑模式 | IR / SV |
| 打字机模式 | 光标居中 | 开关 |
| 缓存 | 编辑器缓存 | 开关 |
| 计数器类型 | 字数统计方式 | Markdown / 纯文本 |
| 自动空格 | 中英文间自动加空格 | 开关 |
| 自动链接 | 自动识别链接 | 开关 |
| 代码块行号 | 显示行号 | 开关 |
| 预览最大宽度 | 内容最大宽度 | 像素值 |
| 数学引擎 | 数学公式渲染 | KaTeX / MathJax |
| 链接行为 | 链接打开方式 | 配置项 |

#### 思维导图（Mindmap）

| 配置项 | 说明 |
|--------|------|
| maxWidth | 最大节点宽度 |
| spacing | 水平/垂直间距 |
| lineWidth | 连线宽度 |
| initialExpandLevel | 初始展开级别 |
| duration | 动画时长 |
| colorFreezeLevel | 颜色冻结层级 |

#### 图谱（Graph）

| 配置项 | 说明 |
|--------|------|
| 节点大小 | 节点半径 |
| 标签字号 | 标签字体大小 |
| 链接距离 | 节点间距离 |
| 电荷强度 | 排斥力强度 |
| 边透明度 | 连线透明度 |

#### 图片（Image）

| 配置项 | 说明 | 选项 |
|--------|------|------|
| 存储模式 | 图片保存位置 | vault-assets / 固定目录 / 图床 |
| 文件名格式 | 文件命名方式 | 原始 / 时间戳 / 两者组合 |
| 自动创建目录 | 自动创建 assets 目录 | 开关 |
| 固定目录路径 | 固定存储路径 | 路径 |

#### 发布（Publish）

完整发布配置表单（同第 12 节）。

#### 关于（About）

- 应用图标和版本信息
- 检查更新按钮（显示下载进度条）
- GitHub 仓库链接
- 问题反馈链接

---

## 14. 图片管理

### 14.1 存储模式

| 模式 | 说明 |
|------|------|
| vault-assets | 存储在 Vault 的 `.assets` 目录（默认） |
| 固定目录 | 存储在用户指定的固定路径 |
| 图床 | 预留，未来支持上传到图床服务 |

### 14.2 文件名格式

| 格式 | 说明 | 示例 |
|------|------|------|
| 原始 | 保持原始文件名 | `photo.jpg` |
| 时间戳 | 使用时间戳命名 | `1720000000000.jpg` |
| 两者组合 | 时间戳 + 原始文件名 | `1720000000000_photo.jpg` |

### 14.3 图片插入流程

1. 粘贴/拖拽图片到编辑器
2. ImageManager 自动保存图片到配置的存储位置
3. 文件名去重（计数器后缀）
4. 计算 Markdown 相对路径
5. 插入图片节点到编辑器

### 14.4 远程图片

- 通过 Rust `fetch_remote_image` 命令代理加载外部图片
- 避免 CORS 问题
- Image NodeView 自动处理本地/远程图片的路径解析

---

## 15. 自动更新

### 15.1 更新流程

```
启动检查 → 发现更新 → 显示更新按钮 → 下载（进度条） → 安装 → 重启
```

### 15.2 技术实现

- 基于 `@tauri-apps/plugin-updater`
- 检查 GitHub Releases 端点
- 公钥签名验证（minisign）
- Windows 使用 passive 安装模式

### 15.3 用户界面

- 顶栏显示更新按钮和版本号
- 下载进度条显示百分比
- 安装完成后自动重启应用

---

## 16. 全局快捷键汇总

### 16.1 系统级快捷键

| 快捷键 | 功能 |
|--------|------|
| Ctrl+S | 保存文件 |
| Ctrl+O | 快速打开文件 |
| Ctrl+P | 命令面板 |
| Ctrl+W | 关闭窗口/应用 |

### 16.2 视图级快捷键

| 快捷键 | 功能 |
|--------|------|
| Ctrl+\ | 切换侧栏 |
| Ctrl+/ | 切换 IR/SV 模式 |
| Ctrl+M | 打开思维导图 |
| Ctrl+G | 切换内联图谱 |
| Ctrl+Alt+T | 切换打字机模式 |
| Ctrl+' | 全屏 |

### 16.3 编辑级快捷键

| 快捷键 | 功能 |
|--------|------|
| Ctrl+B | 加粗 |
| Ctrl+I | 斜体 |
| Ctrl+D | 删除线 |
| Ctrl+E | 行内代码 |
| Ctrl+U | 代码块 |
| Ctrl+K | 超链接 |
| Ctrl+= | 高亮 |
| Ctrl+; | 引用 |
| Ctrl+Shift+H | 水平分割线 |
| Ctrl+L | 无序列表 |
| Ctrl+O | 有序列表 |
| Ctrl+J | 任务列表 |
| Ctrl+T | 表格 |
| Ctrl+Alt+1~6 | H1-H6 标题 |
| Ctrl+Alt+0 | 段落 |
| Ctrl+Z | 撤销 |
| Ctrl+Y | 重做 |

> 注：所有快捷键均可在设置中自定义。

---

## 17. 数据持久化

### 17.1 localStorage 键值

| 键名 | 内容 |
|------|------|
| `zmd-vaults` | 仓库列表 |
| `zmd-active-vault` | 当前活跃仓库索引 |
| `zmd-sidebar-width` | 侧栏宽度 |
| `zmd-window-state` | 窗口位置/大小/最大化状态 |
| `zmd-theme` | 当前主题 |
| `zmd-editor-settings` | 编辑器设置 |
| `zmd-general-settings` | 通用设置 |
| `zmd-shortcuts` | 快捷键配置 |
| `zmd-mindmap-settings` | 思维导图设置 |
| `zmd-graph-settings` | 图谱设置 |
| `zmd-image-settings` | 图片设置 |
| `zmd-recent-files` | 最近文件列表 |
| `zmd-mindmap-content` | 思维导图内容缓存 |

### 17.2 文件系统存储

| 路径 | 内容 |
|------|------|
| `appDataDir/themes/` | 自定义主题 CSS 文件 |
| `appDataDir/themes/manifest.json` | 主题元数据 |
| `appDataDir/code-themes/` | 自定义代码主题文件 |
| `appDataDir/code-themes/manifest.json` | 代码主题元数据 |
| `vault/markdown-publish.config.json` | 发布配置 |

---

## 18. 后端服务（Rust）

### 18.1 Tauri 插件

| 插件 | 用途 |
|------|------|
| `tauri-plugin-fs` | 文件系统访问（读/写/目录/重命名/删除） |
| `tauri-plugin-dialog` | 系统对话框（打开/保存/确认） |
| `tauri-plugin-window-state` | 窗口状态持久化 |
| `tauri-plugin-updater` | 应用自动更新 |
| `tauri-plugin-process` | 进程管理（重启） |

### 18.2 自定义命令

| 命令 | 用途 |
|------|------|
| `get_default_content` | 获取默认编辑器内容 |
| `get_app_version` | 获取应用版本号 |
| `get_cwd` | 获取当前工作目录 |
| `open_settings_window` | 打开设置窗口 |
| `open_file_in_new_window` | 在新窗口打开文件 |
| `open_file_location` | 在系统文件管理器中定位文件 |
| `open_file` | 用系统默认应用打开文件 |
| `open_directory` | 在系统文件管理器中打开目录 |
| `open_url` | 用系统默认浏览器打开 URL |
| `open_mindmap_window` | 打开思维导图窗口 |
| `open_graph_window` | 打开知识图谱窗口 |
| `watch_vault` | 启动仓库文件系统监听 |
| `unwatch_vault` | 停止仓库文件系统监听 |
| `run_markdown_publish` | 调用 CLI 发布网站 |
| `preview_site` | 启动 HTTP 服务器预览 |
| `stop_preview` | 停止预览服务器 |
| `fetch_remote_image` | 代理加载远程图片 |

### 18.3 URI 协议

注册 `local-file://` URI 协议，用于加载本地文件资源：
- 路径百分号解码
- 支持中文路径和特殊字符
- 避免 CSP 限制

### 18.4 文件监听

基于 `notify` crate 的文件系统监听：
- `WatcherState` 使用 `Mutex<Option<RecommendedWatcher>>` 管理状态
- 支持 Create、Modify、Remove 事件
- 前端防抖处理（300ms）

---

## 19. 技术栈与依赖

### 19.1 前端依赖

| 依赖 | 版本 | 用途 |
|------|------|------|
| react / react-dom | ^19.0.0 | UI 框架 |
| @tiptap/* | ^3.27.1 | 编辑器引擎 |
| tiptap-markdown | ^0.9.0 | Markdown 序列化 |
| @codemirror/* | ^6.x | 源码编辑器 |
| d3 / d3-force | ^7.9.0 / ^3.0.0 | 图谱可视化 |
| markmap-lib / markmap-view | ^0.18.12 | 思维导图 |
| mermaid | ^11.16.0 | 图表渲染 |
| highlight.js | ^11.11.1 | 语法高亮 |
| lowlight | ^3.3.0 | 代码块高亮 |
| @tauri-apps/* | ^2.x | Tauri 前端 API |

### 19.2 开发依赖

| 依赖 | 版本 | 用途 |
|------|------|------|
| @vitejs/plugin-react | ^4.3.0 | Vite React 插件 |
| typescript | ^5.6.0 | 类型检查 |
| vite | ^6.0.0 | 构建工具 |
| @tauri-apps/cli | ^2.0.0 | Tauri CLI |
| patch-package | ^8.0.1 | 依赖补丁 |

### 19.3 Rust 依赖

| 依赖 | 用途 |
|------|------|
| serde / serde_json | 序列化 |
| notify | 文件系统监听 |
| tauri-plugin-* | Tauri 插件 crate |

---

## 20. 已知限制与未来规划

### 20.1 已知限制

| 问题 | 说明 |
|------|------|
| TipTap v3 + React 19 兼容性 | Focus 扩展在 React 19 渲染时序下可能报错，已通过 barrel export 问题分析定位 |
| Vite 预构建缓存 | 直接修改 node_modules 不会被 Vite 加载，需使用 patch-package |
| ProseMirror 插件错误 | 插件内部错误无法被上层 try-catch 拦截 |
| 测试覆盖 | 项目目前没有配置 test/lint/format 脚本 |

### 20.2 已开发但未集成的功能

| 功能 | 状态 | 说明 |
|------|------|------|
| Slash 命令菜单 | 代码完成 | `/` 触发的命令菜单 |
| 选中文本浮动工具栏 | 代码完成 | 选中文本时显示的格式工具栏 |
| 拖拽手柄 | 代码完成 | 自定义块级元素拖拽 |
| SafeFocus 扩展 | 代码完成 | 替代有 bug 的 Focus 扩展 |

### 20.3 未来可能的扩展方向

- 图床服务集成（图片上传）
- 协同编辑支持
- 插件系统
- 更多导出格式（PDF、HTML）
- 移动端适配
- 国际化（i18n）

---

> 本文档基于 Tydora v0.0.10 代码库生成，反映当前已实现的功能。
