Files
mnote/design/思维导图方案.md
T
2025-11-23 10:55:04 +08:00

208 lines
12 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.
# Wolai-clone 思维导图方案(v3.1)——复刻 MindManager 体验并与 BlockNote 大纲双向同步
## 0. 背景与目标
- v3.0 架构已确定使用 Next.js + BlockNote + Yjs,需新增思维导图模块,实现与笔记大纲/块树实时联动,体验对齐 MindManager/Wolai/Kmind。
- 核心诉求:**极致整齐的自动布局**、**节点富内容(图片/富文本/图标/link)**、**跨文档/跨导图的链接能力**、**与笔记大纲双向同步**。
- 设计方向:继续使用 @xyflow/reactReact Flow 11+)作为画布内核,自研布局 & 样式层,数据完全托管在 Supabasedocuments 表)与独立 mindmap 表中。
## 1. 体验原则
1. **MindManager 级布局**:节点水平/垂直间距固定,主干左右对称;支持“经典曲线”“直角线”两种连线;节点宽度随内容自动适配,最多两行后溢出省略。
2. **富内容节点**:每个节点可包含标题、富文本摘要、图标、emoji、标签、封面图片;支持 Markdown/快捷键编辑。
3. **多级链接**:节点可跳转到:
- 当前文档某块(blockId)→ 通过 `block://{id}` 链接并高亮目标块。
- 其他笔记(documentId)→ 打开对应页面。
- 其他导图的节点(mindmapId+nodeId)→ 支持导图嵌套导航。
4. **实时同步**:导图结构映射到笔记大纲(Tree);改导图 = 改大纲;在 BlockNote 中增删标题块 = 导图自动更新节点。
5. **Wolai/Kmind 外观**:圆角矩形 + 轻投影,hover 显示手型 + 菜单,选中高亮;暗黑/亮色一致。支持缩放、平移、迷你地图。
## 2. 技术架构
```
BlockNote (Y.Doc: document_tree)
├─ outline nodes ↔ mindmap nodes (双向映射表)
Mindmap SubDoc (Y.Doc: mindmap_{document_id})
React Flow 画布 + 自研 MindLayout Engine
Supabase tables:
documents (content jsonb)
mindmap_meta (id, document_id, layout_prefs, theme)
mindmap_nodes (id, mindmap_id, block_id, parent_id, data jsonb, position cache)
```
- 每份文档默认有一份 mindmap(也支持多个 mindmap);mindmap 数据存于 `mindmap_nodes`,并同步缓存到 BlockNote content(便于离线/导出)。
- 协作层使用 Yjs SubDoc:当打开导图时订阅 `mindmap_{document_id}`React Flow 节点/边与 SubDoc 同步,保持毫秒级更新。
## 3. 视觉规格(融合 MindManager 细节)
- **节点样式**
- 尺寸:`min-w 240px`,默认 280px,最大 384px;高度随内容自动撑开,不超过两行,超出显示省略。
- 圆角 24px、2px 边框;选中 `border-blue-500 ring-4 ring-blue-100 scale-105`,未选中 `border-slate-300 hover:border-blue-400 hover:shadow-2xl`
- 背景渐变 `linear-gradient(135deg,#ffffff 0%,#f8fafc 100%)`,阴影 `0 4px 15px rgba(0,0,0,0.08)`;选中提升到 `0 10px 25px rgba(59,130,246,0.15)`
- 左上角支持图标徽章(36px 圆形),顶部可插入封面(最大高 160px),右侧有链接指示器。
- 示例 className
```tsx
const base = `
relative px-5 py-3 min-w-60 max-w-96 rounded-2xl
bg-white border-2 shadow-lg transition-all duration-200
`;
const active = 'border-blue-500 ring-4 ring-blue-100 scale-105';
const idle = 'border-slate-300 hover:border-blue-400 hover:shadow-2xl';
```
- **连线样式**
- MindManager 曲线:`M sx sy C sx+100 sy targetX-100 targetY targetX targetY`,颜色 `#94a3b8`,宽度 3px。
- 备选直角线(smoothstep)满足 Kmind 用户;末端 arrowhead 半径 6px。
- **画布与工具栏**
- 画布背景 `bg-gradient-to-br from-slate-50 to-slate-100`,使用 React Flow `Background` gap 24px。
- 顶部 56px 工具栏,包含自动排版、主题切换、导出、折叠/展开、缩放重置;工具栏按钮遵循 `px-4 py-2 rounded-lg` 规范。
## 4. 对齐 MindManager 的布局策略
1. **层级布局**:根节点居中,一级节点左右分布;根据用户设置(左/右/双向)动态计算。
2. **自动间距**:使用自研 `MindLayout Engine`(基于 DAG 布局),输入节点树 + 样式参数,输出绝对坐标;支持:
- 同层节点纵向等距排列。
- 子节点根据最长文本宽度自动算水平偏移,保证连线整齐。
- 支持节点折叠/展开,折叠时子树隐藏但保留布局缓存。
3. **连线样式**:提供“曲线(贝塞尔)”“直角线”两种;线条宽度、颜色可继承主题。
4. **对齐辅助**:拖动节点时展示辅助线,松手后自动吸附至推荐位置;支持 `Shift+拖拽` 只在水平或垂直方向移动。
## 5. 节点内容设计
字段结构(存储于 `mindmap_nodes.data`):
```json
{
"title": "节点标题",
"richText": "<p>富文本</p>",
"icon": "mdi-lightbulb",
"emoji": "💡",
"tags": ["优先级:高", "待讨论"],
"image": { "url": "...", "width": 200, "height": 120 },
"link": {
"type": "block" | "document" | "mindmap-node" | "url",
"targetId": "block_xxx / doc_xxx / mindmap_y/node_z",
"title": "跳转提示"
},
"status": "todo | doing | done",
"collapsed": false
}
```
- 富文本编辑器使用 `@tiptap/react` 迷你实例或 BlockNote 内嵌 mini editor,支持粗体/斜体/高亮/超链接。
- 图片可从 Supabase Storage 选择或粘贴上传,节点支持设置小型封面或内嵌图片。
- 节点图标:内置 MindManager 风格图标库(优先级、进度、标记),同时支持 emoji。
## 6. 链接和导航
| 类型 | 格式 | 交互 |
|------|------|------|
| 块链接 | `block://{blockId}` | hover 显示块摘要,点击在文档中滚动并高亮该块。 |
| 文档链接 | `doc://{documentId}` | 打开对应页面,可在侧边栏预览。 |
| 导图节点 | `mind://{mindmapId}/{nodeId}` | 若当前导图即目标,则定位;否则打开目标导图并定位。 |
| 外部 URL | `https://...` | 新标签页打开。 |
- 链接编辑面板提供快速搜索(块/页面/导图节点),并记录最近使用项。
- 支持「一键转块」:把导图节点转换为 BlockNote 内的块,或把块拖入导图生成节点。
## 7. 大纲与导图的双向同步
### 数据映射
- 维护 `outlineNodeId ↔ mindmapNodeId` 映射表,存储在 `mindmap_nodes.block_id` 字段。
- BlockNote 标题块(H1~H4)与导图层级对应;非标题块可作为节点备注(richText)。
### 同步策略
1. **导图 → 大纲**
- 新建节点:创建对应 BlockNote 标题块(Yjs 操作),插入到同级相应位置。
- 删除节点:删除/归档对应块。
- 拖动节点:更新块的父级和排序(BlockNote reorder API)。
2. **大纲 → 导图**
- 在大纲中新建/调整标题块时,触发同步 Hook 更新 mindmap SubDoc。
- 对于仅存在于导图的节点,可标记 `detached=true`,大纲不显示;用户可手动“附着”到大纲。
### 冲突处理
- 通过 Yjs transaction + `lastWriterWins` 策略;若同一节点同时被导图与大纲修改,变更合并后派生 diff,在 UI 中提示“有更新,点击同步”。
- 提供“锁定导图”开关,当导图处于演示模式时暂停同步,避免误差。
## 8. 前端组件分层
1. `MindmapCanvas`:封装 React Flow + 主题/布局;负责渲染节点、连线、背景、缩放器。
2. `MindLayoutEngine`:输入节点树返回位置/尺寸,支持缓存与局部更新。
3. `MindNodeCard`:节点内容组件,内嵌富文本、标签、图片、链接、hover toolbar。
4. `MindLinkPanel`:统一链接管理,搜索块/文档/导图节点。
5. `OutlineSyncController`:监听 BlockNote、导图 SubDoc,执行同步动作。
6. `MindHistorySidebar`:展示导图版本历史/快照(可依赖 Supabase table versions)。
## 9. 数据库 & API
```sql
create table mindmap_meta (
id uuid primary key default uuid_generate_v4(),
document_id uuid references documents(id),
title text,
layout_prefs jsonb, -- 左/右布局、连线样式、主题
theme text default 'wolai-light',
created_by uuid references auth.users,
created_at timestamptz default now(),
updated_at timestamptz default now()
);
create table mindmap_nodes (
id uuid primary key default uuid_generate_v4(),
mindmap_id uuid references mindmap_meta(id) on delete cascade,
parent_id uuid references mindmap_nodes(id),
block_id uuid, -- 可为空(纯导图节点)
order_index integer,
data jsonb,
cached_position jsonb,
created_at timestamptz default now(),
updated_at timestamptz default now()
);
```
- FastAPI Endpoints
- `GET /mindmaps/{id}`:返回 meta + nodes + outline mapping。
- `POST /mindmaps`:创建新导图(可附加到文档)。
- `PATCH /mindmaps/{id}`:更新布局/主题。
- `POST /mindmaps/{id}/nodes`、`PATCH /.../{nodeId}`、`DELETE ...`:供批量导入/AI/脚本使用。
- `POST /mindmaps/{id}/export`:导出为 MMAP、OPML、PNG、SVG。
## 10. 实施计划
| 阶段 | 目标 | 核心任务 | 输出 |
|------|------|----------|------|
| P0 需求确认(0.5d) | 对齐视觉规范 & 交互 | - 与设计确认节点样式、主题变量、连线风格<br>- 列出与大纲同步的详细规则/边界<br>- 明确链接搜索/跳转需求 | 更新 PRD + Figma 草图 |
| P1 数据与 API1.5d | 建表 + 后端接口 | - Supabase 建 `mindmap_meta`/`mindmap_nodes` + RLS<br>- FastAPI mindmap CRUD + 导出占位<br>- 单元测试覆盖 | 后端 PR + Swagger |
| P2 前端内核(2d | React Flow + 布局引擎 | - 封装 `MindLayoutEngine`,实现左右对称/直角/曲线<br>- 节点/连线主题实现,支持折叠/缩放 | 画布 demo |
| P3 节点富内容(2d) | 节点编辑能力 | - 富文本/图标/图片/标签/状态组件<br>- 链接面板 + 搜索块/文档/导图节点<br>- 粘贴逻辑(从 MindManager/文本导入) | 节点交互完成 |
| P4 同步控制器(2d) | 导图 ↔ 大纲 | - 建立 block ↔ node 映射 SubDoc<br>- 实现双向增删改同步/冲突提示<br>- E2E 测试(Cypress + Playwright 多窗口) | 同步稳定 |
| P5 打磨 & 导出(1.5d | 性能/体验 | - 虚拟化/懒加载,支持 2k+ 节点<br>- 导出 PNG/SVG/OPML<br>- 快捷键、迷你地图、历史记录 | 发布候选 |
## 11. 验收标准
- [ ] 导图布局与 MindManager 对齐:节点间距统一,拖动自动吸附。
- [ ] 节点支持图片/富文本/图标/标签/链接,复制 MindManager 内容可无损粘贴。
- [ ] 节点链接在不同类型 (block/doc/mind/node) 下跳转准确,带 hover 预览。
- [ ] 与 BlockNote 大纲实时同步,双向修改 200ms 内可见,无冲突。
- [ ] 多人协作时节点光标、拖拽、折叠状态实时共享,无明显抖动。
- [ ] 支持导出 PNG/SVG/OPML/MMAP(后续),可导入 MindManager 文件(可放在扩展阶段)。
---
## 12. 落地提示
- P2 阶段可直接引入 `grok` 方案中的 `MindManagerNode`/`MindManagerEdge` 作为主题模板,结合 Tailwind CSS 变量封装成 `MindNodeCard` 多主题体系。
- 布局计算使用 elkjs`algorithm=layered`、`elk.layered.nodePlacement.strategy=BRANDES_KOEPF`),封装 `getMindManagerLayout` 并缓存,确保自动排版按钮在 200ms 内完成 500+ 节点重新布局。
- 同步控制器上线前,编写 OPML/MMAP → `mindmap_nodes` 的导入脚本,用真实 MindManager 数据验证字段与链接策略,并准备导图 ↔ 大纲操作回放工具以排查协作冲突。
此方案在保留 MindManager 用户习惯的同时,借助 Supabase + React Flow 构建可扩展的思维导图系统,并与 BlockNote 文档深度联动。按 P0-P5 推进,可在 1.5~2 周内完成 MVP 并持续迭代高级功能。