# Wolai-clone 协同表格方案(v3.1)——Luckysheet 体验 × Supabase 数据底座 ## 0. 背景与目标 - 当前 v3.0 架构已经完成 BlockNote + Yjs + Hocuspocus + Supabase Realtime 的基础协同能力,内置块类型仅支持「简单表格」,无法满足飞书/钉钉/金山文档级交互。 - 新版本需要让用户在文档任意位置插入「在线表格块」,可在文档内预览、可全屏编辑、可多人实时协作,并支持 Excel 级功能(公式、条件格式、批量粘贴等)。 - 同时,考虑到未来要把表格作为独立数据对象(多处引用、导出、AI/OCR 写入等),必须把表格数据与 BlockNote 主文档解耦,避免大表拖垮文档 CRDT。 ## 1. 设计原则 1. **用户心智优先**:界面与交互最大程度贴近 Excel/WPS/飞书表格,复制粘贴零障碍。 2. **数据解耦**:BlockNote 块只保存 `tableId` 与视图参数,真实表格数据落在 Supabase + 独立 Yjs SubDoc,确保性能、复用与权限扩展。 3. **协同一致性**:复用现有 Yjs/Hocuspocus/Supabase Realtime 通道,内嵌/全屏共享同一数据源,支持多人光标与冲突解决。 4. **渐进增强**:先满足核心编辑体验,再分阶段接入高级能力(导入导出、公式库、与 MinerU/AI 的互通)。 ## 2. 技术选型与理由 | 维度 | 方案 | 理由 | |------------------|--------------------------------|------| | 表格 UI/编辑器 | Luckysheet (@dream-num) | Excel 级 UI/工具栏/公式/条件格式,复制粘贴兼容 WPS/飞书/钉钉,支持 headless 嵌入。 | | 数据渲染内核 | Luckysheet + 虚拟滚动 | 经过大规模验证,500×100 也能稳定运行。 | | 实时协作 | Yjs SubDoc + luckysheet-yjs-binding | 官方 binding,直接复用现有 Hocuspocus Provider;每张表格一个 SubDoc,避免主文档体积膨胀。 | | 数据持久化 | Supabase Postgres (`document_tables`, `document_table_rows`) + 定时快照 | 让表格成为独立实体,可复用/引用/授权,同时方便后台 API、导出和 AI 写入。 | | 内联预览 | 自研 React 轻量预览组件 + 行列摘要 | 保持文档流畅,默认展示前 5 行,支持 hover 工具条。 | | 全屏编辑 | `` + Luckysheet | 提供 Excel 式工具栏、状态栏、协作者指示、暗黑模式。 | | 公式引擎 | Luckysheet 内置 + HyperFormula(后续增强) | 先满足 SUM/IF 等高频场景,再按需升级。 | > 放弃:自研 Data Grid(周期长)、Handsontable(商业授权)、AG-Grid(过重)、Tiptap Table(功能不足)。 ## 3. 架构概览 ``` ┌───────────────────────────┐ │ Next.js 前端 │ │ ┌───────────────────────┐ │ │ │ BlockNote (文档 Y.Doc) │ │ │ │ └─ TableBlock │ │ │ │ attrs: {tableId} │ │ │ └───────────────────────┘ │ │ │引用 │ │ ┌───────────────────────┐ │ │ │ LuckysheetProvider │ │ │ │ └─ Y.SubDoc(tableId)│ │ │ │ └─ Supabase Realtime│ │ │ └───────────────────────┘ │ └────────────┬──────────────┘ │REST/RPC ┌────────────▼──────────────┐ │ FastAPI 后端 + Supabase │ │ ├─ document_tables │ │ ├─ document_table_rows │ │ ├─ RLS / Realtime 触发器 │ │ └─ 导出/导入/AI 接口 │ └───────────────────────────┘ ``` - **BlockNote 主文档**:仅存 `tableId`、标题、视图配置等轻量信息。 - **表格 Y.SubDoc**:按需加载;Luckysheet 与之绑定,实现实时协作。 - **Supabase 数据**:提供持久化/查询/权限/导出能力;Yjs 定时把最新快照写入数据库,同时监听数据库变化以支持非 Web 客户端。 ## 4. 数据模型 ```sql create table document_tables ( id uuid primary key default gen_random_uuid(), workspace_id uuid not null references workspaces(id) on delete cascade, document_id uuid not null references documents(id) on delete cascade, title text not null default '未命名表格', schema jsonb not null default '{}'::jsonb, -- 列定义/格式/宽度 view_preferences jsonb not null default '{}'::jsonb, is_archived boolean not null default false, snapshot jsonb, last_synced_at timestamptz, created_by uuid references profiles(id) on delete set null, updated_by uuid references profiles(id) on delete set null, created_at timestamptz not null default timezone('utc', now()), updated_at timestamptz not null default timezone('utc', now()) ); create table document_table_rows ( id uuid primary key default gen_random_uuid(), workspace_id uuid not null references workspaces(id) on delete cascade, document_id uuid not null references documents(id) on delete cascade, table_id uuid not null references document_tables(id) on delete cascade, row_index integer not null, -- 稳定排序键 row_data jsonb not null default '{}'::jsonb, -- 单元格字典,按列 key 存储 row_hash text, is_deleted boolean not null default false, updated_by uuid references profiles(id) on delete set null, created_at timestamptz not null default timezone('utc', now()), updated_at timestamptz not null default timezone('utc', now()) ); ``` - ✅(2025-02-22)`supabase_local` 已执行建表 + 索引 + 触发器 + RLS,迁移文件:`supabase/migrations/20250222_add_document_tables.sql`。 - RLS:沿用 `workspace_members`,`document_tables`/`document_table_rows` 在写入前通过触发器校验 workspace/document 一致,所有读写均需加入同一 workspace。 - 每张表格的实时编辑依赖 Yjs SubDoc;后台任务(导出 CSV/Excel、AI 填表、MinerU OCR 转表)通过 REST API 操作数据库。 - BlockNote 块示例: ```json { "id": "block_xxx", "type": "table", "props": { "tableId": "d3d7-...", "displayMode": "compact", "previewRows": 5 } } ``` ## 5. 功能模块拆解 1. **块插入与预览** - 斜杠命令 `/table`、工具栏按钮、AI 建议等入口。 - 默认创建 10×5 空表,预览显示前 5 行 + 列头,hover 显示快速操作(新建/全屏/复制链接)。 2. **全屏编辑器** - Excel 风格工具栏(行列操作、合并、筛选、条件格式、公式插入、单元格格式)。 - 协作者状态:顶部显示头像、单元格边框高亮。 - 暗黑模式、移动端强制全屏。 3. **数据同步** - Luckysheet ↔ Y.SubDoc:官方 binding。 - SubDoc ↔ Supabase:节流(1-2s)后写入 `document_tables`/`document_table_rows`;大表行级 diff。 - 后端提供导出 CSV/Excel、批量导入 API。 4. **高级能力** - 条件格式模版、冻结行列、查看历史版本。 - 允许多个文档引用同一 `tableId`(只读/编辑权限可控)。 - AI/ MinerU 写表:后端接口 `/api/v1/tables/{id}/rows` 支持 append/merge。 ## 6. 实施计划 | 阶段 | 时间 | 目标 | 关键任务 | 产出 / 验收 | |------|------|------|----------|-------------| | P0 需求巩固 | 0.5d | 明确体验 & 数据需求 | - 联合设计/产品确认预览、高级功能优先级
- 定义列类型 MVP(文本/数字/货币/日期/选择/复选/公式/引用)
- 确认与 MinerU/AI 的接口需求 | 更新 PRD + 交互稿 | | P1 数据面准备 | 1d | 建 Supabase 表 & API | - 执行 SQL 建表 + RLS + 触发器(Supabase Realtime 通知)
- FastAPI 增加 `/tables` CRUD、`/tables/{id}/rows` 批量读写
- 单元测试 + API 文档 | 后端分支 + Swagger | | P2 Yjs/Luckysheet 骨架 | 2d | 协同内核跑通 | - 引入 @dream-num/luckysheet、luckysheet-yjs-binding
- 实现 ``,封装 SubDoc 生命周期、连接状态提示
- 支持单独打开表格编辑页(不依赖 BlockNote) | 可共享链接、协同无冲突 | | P3 BlockNote 表格块 & 预览 | 2d | 文档内插入与缩略展示 | - 自定义 block schema + slash command
- 预览组件(前5行、hover toolbar、loading/错误态)
- 表格块和 Supabase 数据绑定(创建时写表、删除时软删) | 文档里可插入表格并跳转全屏 | | P4 全屏编辑器 & 工具栏 | 3d | 飞书式编辑体验 | - ``:工具栏、状态栏、协作者列表
- 支持插入/删除/合并/冻结/条件格式/基础公式
- 完善暗黑/移动端 UI | 500×50 表格流畅、多端一致 | | P5 持久化 & 性能 | 2d | 数据安全 & 优化 | - SubDoc → Supabase 节流、row-level diff
- 历史快照(定时写入 table_versions)
- 预览模式虚拟滚动、全屏懒加载资源 | 刷新不丢数据、大表不卡顿 | | P6 高级扩展 | 2d+ | 导入导出 & AI | - CSV/Excel 导入导出
- MinerU OCR 输出自动转表 + 写入
- 表格引用共享、权限控制 UI | E2E 测试 + 文档 | > 若时间紧,可先完成 P0~P4 形成可用 MVP,之后再迭代 P5/P6。 **进展速记(2025-02-22)** - ✅ P1「执行 SQL 建表 + RLS + 触发器」已完成(详见上文数据模型 & 迁移文件),剩余 `/tables`/`/tables/{id}/rows` API + 单元测试待开发。 - ✅ P2「Luckysheet Provider + Yjs SubDoc 骨架」:Next.js 侧封装 `LuckysheetCanvas`,复用 Hocuspocus 通道,表格编辑自动广播到 Y.Doc 与 Supabase snapshot。 - ✅ P3「BlockNote 表格块 & 预览」:自定义 `tableBlock` + slash `/table`,支持在线创建、缩略展示、重命名、全屏入口。 - ✅ P4「全屏编辑器」:落地 ``,集成 Luckysheet 工具栏、保存状态、协同提示,500×50 表格实测流畅。 ## 7. 依赖与工具 ```bash pnpm add @dream-num/luckysheet luckysheet-yjs-binding @hocuspocus/provider yjs y-protocols zustand lucide-react # 后端 pip install fastapi supabase-py psycopg[binary] uvicorn[standard] ``` - 设计稿:Figma(飞书表格参考)。 - 协同测试:Cypress + Playwright(多客户端场景)。 ## 8. 验收清单 - [ ] `/table` 插入后出现缩略预览,支持命名/重命名。 - [ ] 多端同时编辑同一表,光标位置、单元格内容同步延迟 < 800ms。 - [ ] 刷新或重连后表格数据一致,Supabase 中有对应记录。 - [ ] 全屏编辑支持:插入/删除行列、调整列宽、冻结、合并、条件格式、公式 (SUM/AVERAGE/IF)。 - [ ] 支持从 Excel/WPS/飞书/钉钉直接粘贴,保留行列和基础格式。 - [ ] CSV/Excel 导出可用,至少支持 UTF-8。 - [ ] 移动端默认全屏,横屏提示可编辑。 ## 9. 后续路线(与整体架构衔接) 1. **多视图**:基于同一 `tableId` 派生看板、画廊,复用 Supabase 数据。 2. **AI Assist**:支持「生成表格」「自动补数据」「智能公式建议」,后端复用 LightRAG + GPT-4o。 3. **OCR 写表**:MinerU 解析复杂表格后直接写入 `document_table_rows`,用户可在 Luckysheet 中二次确认。 4. **权限与共享**: 表格可独立分享/只读/协作,并在后台记录操作日志。 此方案兼顾用户熟悉的 Excel 体验与 Supabase 数据化能力,为后续多视图、AI、OCR 等模块铺平道路。接下来可按 P0~P4 推进 MVP,实现飞书级表格块体验。*** End Patch