Files
eaiadmin 90031b75f3 docs: 重构仓库文档目录并迁移训练素材
按当前架构重组 docs 目录,统一中文命名与目录分层,并将训练原材料迁移到独立目录以保持架构文档边界清晰。
2026-09-22 23:23:16 +08:00

625 lines
23 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.
# 工作流画布交互设计调研报告
> **版本:V2.0 | 最后更新:2026-08-17**
> **目标产品:eai_agentplatform-app · 数字员工平台 · 工坊(Studio)**
---
## 目录
1. [调研范围与背景](#1-调研范围与背景)
2. [行业产品全景对比](#2-行业产品全景对比)
3. [节点体系设计](#3-节点体系设计)
- 3.1 三节点 vs 五节点体系
- 3.2 子类型(SubType)架构
- 3.3 连接器作为被引用资源
4. [画布交互模型](#4-画布交互模型)
- 4.1 拖入创建(Drag & Drop)
- 4.2 右键菜单体系
- 4.3 键盘快捷键体系
- 4.4 选中与视觉反馈
- 4.5 Edge 交互(连线)
5. [布局与导航](#5-布局与导航)
6. [技术实现(VueFlow)](#6-技术实现vueflow)
- 6.1 核心事件
- 6.2 自定义节点
- 6.3 自定义边
- 6.4 CSS 主题与样式
7. [当前实现状态](#7-当前实现状态)
8. [待完成项](#8-待完成项)
9. [参考资料](#9-参考资料)
---
## 1. 调研范围与背景
### 1.1 调研目标
为数字员工平台的 **工坊(Studio)** 模块设计一套符合行业标准、贴近业务用户心智的工作流画布交互模型。核心需求:
- 业务用户能通过 **拖拽 + 配置** 的方式定义数字员工的工作流程
- 画布交互对标 Dify / n8n / Make / Zapier / Coze 等主流产品
- 节点体系从 SY18(信源/动作/结果/权限)简化为 3 节点体系(开始/动作/结束)
### 1.2 调研的产品
| 产品 | 定位 | 节点体系 | 画布引擎 | 参考版本 |
|------|------|----------|----------|----------|
| **Dify** | AI 工作流编排 | 开始/LLM/工具/结束等 | React Flow | v1.14.0 |
| **n8n** | 自动化工作流 | 触发器/动作 | 自研 | latest |
| **Make** | 可视化自动化 | 触发器/动作/模块 | 自研 | latest |
| **Zapier** | 轻量自动化 | Trigger/Action/Search | 自研 | latest |
| **Coze** | AI Bot 构建 | 开始/LLM/插件/知识库/结束 | 自研 | latest |
| **Langflow** | LLM 流程编排 | Input/LLM/Output | React Flow | latest |
| **VueFlow** | 画布引擎库 | N/A | Vue Flow | v1.44+ |
---
## 2. 行业产品全景对比
### 2.1 产品定位对比
| 维度 | Dify | n8n | Make | Zapier | Coze | 本产品 |
|------|------|-----|------|--------|------|--------|
| 目标用户 | 开发者/AI 工程师 | 技术运营 | 业务用户 | 业务用户 | 业务用户+开发者 | HR/销售/业务用户 |
| 复杂度 | 中高 | 高 | 中 | 低 | 中 | 中 |
| 拖入创建 | ✅ | ✅ | ✅ | ❌(点击添加) | ✅ | ✅ |
| 右侧检查器 | ✅ | ✅ | ✅ | ✅(弹窗) | ✅ | ✅ |
| 节点右键菜单 | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
| Edge 右键菜单 | ✅(PR#33391) | ✅ | ✅ | ❌ | ❌ | ✅ |
| Delete 键删除 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Ctrl+D 复制 | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ |
| Ctrl+Z 撤销 | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| 连线 "+" 按钮 | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
### 2.2 画布布局对比
| 产品 | 左侧面板 | 右侧面板 | 工具栏 | 布局风格 |
|------|----------|----------|--------|----------|
| Dify | 节点选择(可折叠) | 检查器(选中后出现) | 顶部薄栏 | 左-中-右 |
| n8n | 节点库 | 编辑面板 | 顶部 | 左-中-右 |
| Make | 模块库(浮层) | 配置面板 | 顶部 | 中-右(浮层) |
| Zapier | 无(步骤式) | 弹窗配置 | 顶部 | 步骤向导 |
| Coze | 节点/插件/知识库 | 配置区(底部弹出) | 顶部 | 左-中-右 |
| **本产品** | **节点库+工具区** | **检查器面板** | **顶部 48px** | **左-中-右** |
---
## 3. 节点体系设计
### 3.1 三节点 vs 五节点体系
**行业共识:主流产品均采用 3~4 种核心节点类型。**
Dify: Start → LLM/Tool → End
n8n: Trigger → Action → No explicit end
Make: Trigger → Module → No explicit end
Zapier: Trigger → Action/Search → No explicit end
Coze: Start → LLM/Plugin/Knowledge → End
**本产品的演进:**
- **旧(SY18 模型)**:5 种节点(input / connector / action / result / permission)
- **新(Zapier/Dify 对齐)**:3 种节点(start / action / end)
- start(开始节点):取代旧的 input + connector
- action(动作节点):保留旧的 action
- end(结束节点):取代旧的 result + permission
### 3.2 子类型(SubType)架构
三节点通过 **子类型(SubType)** 实现具体的行为分化,避免了节点类型爆炸:
```
start (开始节点)
├── schedule (⏰ 定时触发)
├── file (📎 文件触发)
├── connector (🔌 连接器触发)
└── manual (✍️ 手动触发)
action (动作节点)
├── ai (🤖 AI 处理)
├── code (💻 代码处理)
├── condition (🔀 条件分支)
└── connector (🔌 连接器操作)
end (结束节点)
├── data (📊 返回数据)
├── file (📁 文件输出)
└── connector (🔌 连接器输出)
```
**核心设计原则:**
- 每种节点只有一个 **子类型下拉选择**,用户在检查器中切换
- subType 改变时自动清除不兼容的配置(如从 `connector` 切到 `ai` 时清除 `connectorKey`)
- 子类型的标签包含 emoji 前缀,便于视觉识别(参考 Dify 的节点 icon + label)
### 3.3 连接器作为被引用资源
**关键架构决策:连接器不是画布上的独立节点类型。**
在旧的 SY18 模型中,"信源"被理解为连接器。经过对 Zapier/Make.com/Coze/Dify 的调研发现:
| 产品 | 连接器(Connector)的角色 |
|------|------------------------|
| Zapier | Trigger 和 Action 通过下拉选择 APP + 事件/操作,APP 就是连接器 |
| Make | Module 可以选择不同的 Service,Service 就是连接器 |
| Dify | 工具(Tools)是独立节点,但连接器/数据源是 LLM 或知识库的属性 |
| Coze | 插件(Plugin)是独立节点,连接器是 Bot 的配置属性 |
**本产品的方案:**
- 连接器不是画布节点,而是 **start/action/end 节点通过 subType='connector' 引用的资源**
- 连接器列表在 **工具区** 中管理,由工具栏 `☑ 🔌 连接器` 按钮控制显示/隐藏
- 用户可以从工具区 **点击添加** 一个 start 节点并自动绑定到选中的连接器
- 在检查器中,当 subType='connector' 时,显示连接器绑定下拉
---
## 4. 画布交互模型
### 4.1 拖入创建(Drag & Drop)
**Dify 标准流程:**
1. 从左侧节点列表拖出一个节点类型
2. 拖到画布上释放
3. 节点出现在释放位置,自动选中并打开右侧配置面板
**本产品实现:**
```vue
<!-- 工具箱节点 -->
<div
v-for="item in toolboxItems"
draggable="true"
@dragstart="handleToolboxDragStart($event, item.key)"
@dragend="handleToolboxDragEnd"
>
...
</div>
<!-- 画布接收 drop -->
<div
class="canvas-shell"
@dragover.prevent="handleCanvasDragOver"
@drop.prevent="handleCanvasDrop"
@dragleave="handleCanvasDragLeave"
>
...
</div>
```
**拖放数据流:**
```javascript
dragstart → setData('application/dw-node-kind', kind)
dragover → 显示 drop 提示(drag-over class)
drop → screenToFlowCoordinate → createCanvasNode
dragend → 清理状态
```
### 4.2 右键菜单体系
**Dify 标准(PR #34138 + PR #33391):**
- **节点右键菜单**:编辑节点 / 复制节点 / 删除节点 / 断开所有连线
- 新版本还支持多选节点时的对齐操作
- **Edge 右键菜单**:删除连线(PR #33391, 2026-03 合并)
- 右键点击连线弹出删除选项
- 菜单互斥:同一时间只有一个菜单可见
- **画布空白右键菜单**:粘贴 / 适配视图 / 重置
**本产品实现:**
**节点右键菜单:**
```vue
<div v-if="contextMenu.visible" class="node-context-menu"
:style="{ left: contextMenu.x + 'px', top: contextMenu.y + 'px' }" @click.stop>
<div class="context-menu-item" @click="editNodeFromContext">✏️ 编辑节点</div>
<div class="context-menu-item" @click="duplicateNodeFromContext">📋 复制节点</div>
<div class="context-menu-divider"></div>
<div class="context-menu-item" @click="deleteNodeFromContext">🗑️ 删除节点</div>
<div class="context-menu-item" @click="disconnectNodeFromContext">🔗 断开所有连线</div>
</div>
<!-- Edge 右键菜单 -->
<div v-if="edgeContextMenu.visible" class="node-context-menu edge-context-menu"
:style="{ left: edgeContextMenu.x + 'px', top: edgeContextMenu.y + 'px' }" @click.stop>
<div class="context-menu-item" @click="deleteEdgeFromContext">🗑️ 删除连线</div>
</div>
```
**菜单互斥逻辑:**
```javascript
function handleEdgeContextMenu({ edge, event }) {
event.preventDefault()
closeNodeContextMenu() // 关闭节点菜单
closeEdgeContextMenu() // 关闭已有边菜单
edgeContextMenu.edgeId = edge.id
edgeContextMenu.x = event.clientX
edgeContextMenu.y = event.clientY
edgeContextMenu.visible = true
}
function handlePaneClick() {
selectedNodeId.value = ''
closeNodeContextMenu()
closeEdgeContextMenu()
}
```
### 4.3 键盘快捷键体系
**Dify 快捷键标准:**
| 快捷键 | 功能 |
|--------|------|
| Delete | 删除选中的节点或边 |
| Backspace | 删除选中节点或边(有争议,用户易误触) |
| Ctrl+D | 复制选中节点 |
| Ctrl+Z | 撤销 |
| Ctrl+Shift+Z / Ctrl+Y | 重做 |
| Shift + 点击 | 多选节点 |
| Arrow keys | 移动选中节点 |
| Ctrl+A | 全选 |
**本产品实现:**
```javascript
function handleKeyDown(event) {
const tag = event.target.tagName
// 输入框中不触发
if (tag === 'INPUT' || tag === 'TEXTAREA' || event.target.isContentEditable) return
if (event.key === 'Delete' || event.key === 'Backspace') {
// 1. 先关菜单(如果有)
if (contextMenu.visible || edgeContextMenu.visible) {
closeNodeContextMenu()
closeEdgeContextMenu()
event.preventDefault()
return
}
// 2. 删选中的边
const selectedEdges = edges.value.filter(e => e.selected)
if (selectedEdges.length > 0) {
edges.value = edges.value.filter(e => !e.selected)
event.preventDefault()
return
}
// 3. 删选中的节点
const selectedNodes = nodes.value.filter(n => n.selected)
if (selectedNodes.length > 0) {
const selectedIds = new Set(selectedNodes.map(n => n.id))
nodes.value = nodes.value.filter(n => !selectedIds.has(n.id))
edges.value = edges.value.filter(e => !selectedIds.has(e.source) && !selectedIds.has(e.target))
event.preventDefault()
}
}
}
```
### 4.4 选中与视觉反馈
**节点选中状态:**
- VueFlow 原生支持 `node.selected` 属性
- 点击节点 → 节点获得 `.selected` class → 边框变色 + 阴影增强
- 点击画布空白 → 取消全部选中
**本产品的颜色体系:**
| 节点类型 | 边框色 | 选中色 |
|----------|--------|--------|
| start | `#409eff` (蓝) | 实线蓝色 + 蓝光阴影 |
| action | `#e6a23c` (橙) | 实线橙色 + 橙光阴影 |
| end | `#67c23a` (绿) | 实线绿色 + 绿光阴影 |
### 4.5 Edge 交互(连线)
**Dify 标准:**
1. **连接操作**:从一个节点的右侧 handle 拖到另一个节点的左侧 handle
2. **选中**:点击连线 → 连线高亮(变蓝变粗)
3. **右键菜单**:右键点击连线 → 弹出删除选项
4. **Delete 键删除**:选中连线后按 Delete 键
5. **Hover "+" 按钮**:鼠标悬停在连线上 → 中点出现 "+" 按钮 → 点击后插入一个新节点(串行)
6. **断开连接**:从 handle 拖出新连线覆盖已有连线,自动替换
**本产品实现:**
**Edge 视觉反馈(CSS):**
```css
/* 点击区域加宽 */
:deep(.vue-flow__edge-path) {
stroke-linecap: round;
transition: stroke 0.15s, stroke-width 0.15s;
}
/* hover 高亮 */
:deep(.vue-flow__edge:hover .vue-flow__edge-path) {
stroke: #409eff;
stroke-width: 2.5;
}
/* 选中高亮 */
:deep(.vue-flow__edge.selected .vue-flow__edge-path) {
stroke: #409eff;
stroke-width: 3;
}
```
**Handle hover:**
```css
:deep(.vue-flow__handle) {
transition: transform 0.12s, background 0.12s;
}
:deep(.vue-flow__handle:hover) {
transform: scale(1.3);
background: #409eff;
}
```
---
## 5. 布局与导航
### 5.1 整体布局结构
```
┌─────────────────────────────────────────────────────────────┐
│ [头部 Header · 48px] │
├────────┬────────────────────────────────────┬───────────────┤
│ 左侧 │ 画布区域 │ 右侧检查器 │
│ 节点库 │ Canvas (VueFlow) │ Inspector │
│ +工具区 │ │ (选中后出现) │
│ │ ┌────┐ ┌────┐ ┌────┐ │ │
│ │ │ S │──→│ A │──→│ E │ │ │
│ │ └────┘ └────┘ └────┘ │ │
│ │ │ │
├────────┴────────────────────────────────────┴───────────────┤
│ [工具栏] ← ☑ 🔌 连接器 | ⚙ 设置 | [保存] │
└─────────────────────────────────────────────────────────────┘
```
### 5.2 左侧节点库(Toolbox)
| 区域 | 内容 | 可折叠 |
|------|------|--------|
| 头部 | "节点库" + ◀ 折叠按钮 | ✅ |
| 节点列表 | 开始节点/动作节点/结束节点(可拖拽) | 跟随折叠 |
| 分隔线 | - | - |
| 工具区标题 | "工具区" | - |
| 连接器工具 | 连接器列表(由工具栏按钮控制可见性) | ✅(点击文字折叠) |
**展开状态宽度:200px**
**折叠状态宽度:52px(只显示图标)**
### 5.3 右侧检查器(Inspector)
| 区域 | 内容 |
|------|------|
| 头部 | "节点检查器" |
| 当前节点 | 显示节点标题(只读) |
| 节点类型 | 显示类型标签(只读) |
| 子类型选择 | el-select 下拉(start: 定时/文件/连接器/手动; action: AI/代码/条件/连接器; end: 数据/文件/连接器) |
| 连接器绑定 | 仅 subType='connector' 时显示,el-select 选择连接器 |
| 节点标题 | el-input 可编辑 |
| 节点说明 | el-input textarea 可编辑 |
| 节点位置 | X/Y 坐标(只读) |
| 上下游 | 上游节点 / 下游节点(只读) |
---
## 6. 技术实现(VueFlow)
### 6.1 核心事件
| VueFlow 事件 | 用途 | 当前状态 |
|-------------|------|----------|
| `@node-click` | 点击节点 → 选中 + 显示检查器 | ✅ |
| `@node-context-menu` | 右键节点 → 弹出菜单 | ✅ |
| `@edge-click` | 点击连线 → 选中高亮 | ✅ |
| `@edge-context-menu` | 右键连线 → 删除菜单 | ✅ |
| `@connect` | 建立连线 | ✅ |
| `@pane-click` | 点击画布空白 → 取消选中 + 关菜单 | ✅ |
| `@pane-ready` | 画布初始化 → 绑定键盘事件 | ✅ |
| `@nodes-change` | 节点变化 | ❌(未用) |
| `@edges-change` | 边变化 | ❌(未用) |
| `@node-drag-stop` | 拖拽停止 | ❌(未用) |
### 6.2 自定义节点
```javascript
// 节点定义
const newNode = {
id: `${kind}-${nodeCounter}`,
type: 'dw', // 自定义节点类型,对应 <template #node-dw>
position: { x, y },
draggable: true,
connectable: true,
selectable: true,
data: {
kind, // 'start' | 'action' | 'end'
typeLabel, // '▶ 开始' | '⚡ 动作' | '📤 结束'
subType, // 子类型,默认取第一个
title, // 节点标题
detail, // 节点说明
connectorKey, // 仅 subType='connector' 时有值
},
}
```
```vue
<!-- 自定义节点渲染模板 -->
<template #node-dw="{ data, selected }">
<div class="dw-node" :class="[data.kind, { selected }]">
<Handle type="target" :position="Position.Left" />
<div class="dw-node-type">{{ data.typeLabel }}</div>
<div v-if="data.subType" class="dw-node-subtype">
{{ nodeKindConfig[data.kind]?.subTypes?.find(s => s.value === data.subType)?.label || '' }}
</div>
<div class="dw-node-title">{{ data.title }}</div>
<div class="dw-node-detail">{{ data.detail }}</div>
<Handle type="source" :position="Position.Right" />
</div>
</template>
```
### 6.3 自定义边
目前使用 VueFlow 内置边类型:
- `type: 'smoothstep'` — 圆角折线
- `markerEnd: MarkerType.ArrowClosed` — 终点箭头
**待实现的自定义边功能:**
- [ ] 边中点悬停 "+" 按钮(需自定义 `edgeTypes`)
- [ ] 边标签显示(显示连线条件或数据映射)
### 6.4 CSS 主题与样式
**必须导入的样式:**
```javascript
import '@vue-flow/core/dist/style.css' // 基础样式
import '@vue-flow/core/dist/theme-default.css' // 可选默认主题
```
**关键 CSS 变量覆盖:**
```css
:root {
--vf-node-bg: #fff;
--vf-node-text: #1f2d3d;
--vf-connection-path: #b1b1b7;
--vf-handle: #555;
}
```
**自定义节点类名:**
| 类名 | 用途 |
|------|------|
| `.dw-node` | 所有自定义节点 |
| `.dw-node.start` | 开始节点(蓝色边框) |
| `.dw-node.action` | 动作节点(橙色边框) |
| `.dw-node.end` | 结束节点(绿色边框) |
| `.dw-node.selected` | 选中态(边框变色 + 阴影) |
---
## 7. 当前实现状态
### 7.1 已完成功能
| 功能 | 状态 | 实现位置 |
|------|------|----------|
| 3 节点体系(start/action/end) | ✅ | `toolboxItems` + `nodeKindConfig` |
| 子类型下拉选择 | ✅ | 检查器面板 `el-select` |
| 连接器绑定(subType=connector) | ✅ | 检查器面板条件渲染 |
| 拖入创建(drag & drop) | ✅ | `handleToolboxDragStart` → `handleCanvasDrop` |
| 节点右键菜单 | ✅ | `handleNodeContextMenu` → 4 个菜单项 |
| Edge 右键菜单 | ✅ | `handleEdgeContextMenu` → 删除连线 |
| Delete 键删除 | ✅ | `handleKeyDown`(全局 document 监听) |
| Edge hover 高亮 | ✅ | CSS `:deep(.vue-flow__edge:hover)` |
| Edge 选中高亮 | ✅ | CSS `:deep(.vue-flow__edge.selected)` |
| Handle hover 放大 | ✅ | CSS `:deep(.vue-flow__handle:hover)` |
| 工具栏连接器开关 | ✅ | `connectorToolEnabled` + `☑/☐` 按钮 |
| 工具区折叠 | ✅ | `connectorListCollapsed` + 点击"连接器"文字 |
| 连接器创建弹窗 | ✅ | `connectorDialogVisible` + `createConnectorFromForm` |
| 右键菜单互斥 | ✅ | `closeNodeContextMenu()` / `closeEdgeContextMenu()` |
| 键盘监听生命周期 | ✅ | `onMounted` 添加 / `onUnmounted` 移除 |
| 输入保护(不误删) | ✅ | `tagName === 'INPUT'` 等判断 |
### 7.2 当前代码架构
```
StudioPage.vue
├── Template
│ ├── 工具栏 (.canvas-toolbar)
│ │ ├── 返回按钮 + 标题 + 节点/边计数
│ │ └── ☑ 连接器 + ⚙ 设置 + 保存
│ ├── 新手引导 (无模式时)
│ ├── 模式选择弹窗 (模板/复制)
│ ├── 设置弹窗
│ ├── 连接器创建弹窗
│ ├── 主布局 (.studio-grid)
│ │ ├── 左侧节点库+工具区 (.toolbox-panel)
│ │ ├── 中间画布 (.canvas-shell > VueFlow)
│ │ └── 右侧检查器 (.inspector-panel)
│ ├── 节点右键菜单 (.node-context-menu)
│ └── Edge 右键菜单 (.edge-context-menu)
├── Script
│ ├── 状态定义 (ref/reactive)
│ ├── 计算属性 (computed)
│ ├── 模板/配置数据 (templateCards, toolboxItems, nodeKindConfig)
│ ├── 业务函数 (createDraft, rebootCanvas, saveDw, ...)
│ ├── 交互函数 (handleNodeClick, handleNodeContextMenu, handleKeyDown, ...)
│ └── 生命周期 (onMounted, onUnmounted, watch)
└── Style (scoped)
├── 工具栏 (.canvas-toolbar)
├── 新手引导 (.canvas-landing)
├── 主布局 (.studio-grid)
├── 节点库 (.toolbox-panel / .toolbox-item)
├── 工具区 (.toolbox-tool-area)
├── 画布 (.canvas-shell / .dw-flow)
├── DW 节点 (.dw-node / .dw-node.start/.action/.end)
├── 检查器 (.inspector-panel)
├── 弹窗公用 (.dialog-template-grid)
├── 连接器 (.toolbox-connector-item)
├── 右键菜单 (.node-context-menu)
├── Edge 交互 (vue-flow__edge hover/selected)
└── 响应式 (@media)
```
---
## 8. 待完成项
### 8.1 高优先级
| 功能 | 说明 | Dify 参考 |
|------|------|-----------|
| **Ctrl+D 复制节点** | 选中节点后按 Ctrl+D 快速复制 | ✅ |
| **Ctrl+Z 撤销/重做** | 历史记录栈,支持撤销和重做操作 | ✅ |
| **Edge "+" 按钮** | hover 在连线中点显示 "+",点击后插入新节点(串行) | ✅ (最新版本) |
| **编译面板清理** | `compileCanvas()` 中仍有 `input/connector/result/permission` 旧 kind 引用 | - |
### 8.2 中优先级
| 功能 | 说明 |
|------|------|
| **画布右键菜单** | 右键点击画布空白 → 粘贴/适配视图/重置 |
| **多选操作** | Shift+点击 多选,批量删除/复制/对齐 |
| **对齐辅助线** | 拖拽节点时的参考线 |
| **MiniMap** | 缩略图导航 |
| **Edge 标签** | 在连线上显示条件标签(如"是/否") |
### 8.3 低优先级
| 功能 | 说明 |
|------|------|
| **自动保存** | 画布变化后自动保存草稿 |
| **全屏模式** | 画布全屏编辑 |
| **节点注释/便签** | 在画布上添加文字注释 |
| **模板片段** | 选中部分节点另存为模板片段 |
| **导入/导出** | JSON 导入导出画布定义 |
---
## 9. 参考资料
### 9.1 Dify 相关
| 链接 | 内容 |
|------|------|
| [Dify Edge Context Menu PR #33391](https://github.com/langgenius/dify/pull/33391) | 2026-03 合并的 Edge 右键菜单实现 |
| [Dify Multi Node Context Menu PR #34138](https://github.com/langgenius/dify/pull/34138) | 2026-03 合并的多选节点菜单 |
| [Dify Backspace Issue #23354](https://github.com/langgenius/dify/issues/23354) | Backspace 误删节点问题讨论 |
| [Dify Backspace Discussion #20140](https://github.com/langgenius/dify/discussions/20140) | 用户要求移除 Backspace 快捷键 |
### 9.2 VueFlow 相关
| 链接 | 内容 |
|------|------|
| [VueFlow 官方文档](https://vueflow.dev/) | 核心 API、自定义节点/边、主题 |
| [VueFlow Edge Guide](https://vueflow.dev/guide/edge.html) | 边的增删改查 |
| [VueFlow Theming Guide](https://vueflow.dev/guide/theming.html) | CSS 变量、自定义主题 |
### 9.3 本产品内部文档
| 文档 | 内容 |
|------|------|
| [SY18 - 专员最小定义模型](../01_System_Overall/SY18_Specialist_Minimal_Definition_Model.md) | 信源/动作/结果/权限模型 |
| [SY17 - UI 线框图](../01_System_Overall/SY17_Workbench_UI_Wireframes.md) | 工作台 UI 框架 |
| [DR03 - 交互规范](../08_Design_Rules/DR03_Interaction_Rules.md) | 全局交互规范 |
---
> **文档维护者:AI 工程团队**
> **下次评审:2026-08-24**