Appearance
模块:Canvas Editor
唯一职责:承载 Vue Flow 画布容器,协调节点创建、连线交互、视口管理、WebSocket 实时同步。
边界
属于本模块:
- 初始化 Vue Flow 实例并通过 HTTP API 加载画布数据
- 建立 WebSocket 连接,管理实时同步生命周期
- 提供节点创建入口(工具栏对话框、浮动菜单)
- 连线的全部职责(创建、删除、渲染、持久化、验证、连接角色规则)
- 管理画布视口(平移、缩放)
- 展示画布 Header(名称编辑)、Toolbar、Footer(缩放控制、网格切换)
- 预加载模型列表
- 节点 Quick Look 预览(空格键触发全屏预览、方向键切换)
- 追踪鼠标悬浮的节点(
hoveredNodeId)
不属于本模块:
- 节点内部的编辑逻辑(由 Node System 模块负责)
- AI 生成调用(由节点组件 → Services 模块负责)
- 后端 API 通信细节(由 Services 模块负责)
对外接口
Canvas Editor 是页面组件(路由 /canvas/:id),不对外暴露 API。仅通过路由参数 id 访问,无 props / emits。
消费的接口
| 依赖模块 | 调用的方法/属性 | 用途 |
|---|---|---|
| canvasStore | loadCanvas(id) | HTTP 加载画布详情 |
| canvasStore | currentCanvas | 读取画布名称 |
| canvasStore | renameCanvas(id, name) | Header 编辑名称 |
| flowStore | (CONNECT 快照初始化) | 初始化 Vue Flow 节点/边 |
| flowStore | addNode(type, position) | 创建节点(乐观 + WS Command) |
| flowStore | addEdge(edge) | 创建连线 |
| flowStore | addBatchEdges(memberIds, targetId, handleType) | 批量创建连线 |
| flowStore | validateEdge(edge) | 连线前验证 |
| modelsStore | fetchAllModels() | 预加载模型列表 |
| useCanvasWs | connect() / disconnect() | 管理 WS 连接生命周期 |
| useCanvasWs | getFlowService() | 获取 FlowService 实例注入 flowStore |
| useCanvasWs | status | 显示连接状态 |
提供的注入
| Key | 类型 | 消费方 |
|---|---|---|
CANVAS_ID_KEY | InjectionKey<string> | 所有子组件(节点、工具栏) |
IS_CONNECTING_KEY | InjectionKey<Ref<boolean>> | NodeShell(连线拖拽视觉反馈) |
HOVERED_NODE_ID_KEY | InjectionKey<Readonly<Ref<string|null>>> | Quick Look(预览目标解析) |
不变量
- 页面加载时,先 HTTP 获取画布数据,再建立 WS 连接
- 如果
canvasId对应的画布不存在,显示错误页面(含返回 Workspace 入口) - 画布中的持久化节点类型只能是
text、image、video(group节点为临时节点,不发送到后端) - 连线创建前必须通过
validateEdge验证 - 离开页面时自动断开 WS 连接并释放资源
错误场景
| 场景 | 模块行为 | 调用方职责 |
|---|---|---|
路由参数 id 对应的画布不存在 | 显示错误提示页面,含返回 Workspace 入口 | 无需处理(页面自身兜底) |
| WS 连接失败或断线 | 自动重连,连接状态可视化反馈 | 无需处理 |
modelsStore.fetchAllModels() 网络超时或失败 | 模型下拉列表为空,不阻塞画布加载 | 节点层显示"模型加载失败"提示 |
| WS Command 被 Reject | flowStore 回滚乐观更新 | 无需处理 |
实现位置
| 角色 | 文件路径 |
|---|---|
| 页面 | app/pages/canvas/[id].vue |
| 核心逻辑 | app/composables/useCanvasEditor.ts |
| WS 连接管理 | app/composables/useCanvasWs.ts |
| Header | app/components/canvas/CanvasHeader.vue |
| Toolbar | app/components/canvas/CanvasToolbar.vue |
| Footer | app/components/canvas/CanvasFooter.vue |
| 节点类型对话框 | app/components/canvas/NodeTypeDialog.vue |
| 浮动菜单 | app/components/canvas/FloatingNodeMenu.vue |
| 浮动菜单逻辑 | app/composables/useFloatingNodeMenu.ts |
| Group Node | app/components/nodes/GroupNode.vue |
| Group Node 逻辑 | app/composables/useGroupNode.ts |
| 连线拖拽路由 | app/composables/useEdgeConnection.ts |
| 自定义边组件 | app/components/canvas/SoftBeamEdge.vue |
| Beam 计算工具 | app/utils/beam.ts |
| 批量连线预览 | app/components/canvas/GroupConnectionLine.vue |
| Quick Look 逻辑 | app/composables/useQuickLook.ts |
| Quick Look UI | app/components/canvas/QuickLookOverlay.vue |