- 拆分 FileSystem.vue 为模块化组件架构 - 新增 Markdown Mermaid 图表渲染支持 - 新增 180+ 编程语言代码高亮 - 修复编辑/预览模式切换渲染问题 - 优化亮色/暗色模式主题适配 - 新增 TypeScript 类型定义
341 lines
10 KiB
Markdown
341 lines
10 KiB
Markdown
# 右键菜单系统设计
|
||
|
||
**设计日期**:2026-01-28
|
||
**设计范围**:数据库客户端全局右键菜单系统
|
||
**状态**:设计阶段
|
||
|
||
---
|
||
|
||
## 一、设计概述
|
||
|
||
### 1.1 设计目标
|
||
|
||
- **统一体验**:所有区域的右键菜单使用统一的设计和交互方式
|
||
- **易于扩展**:新增菜单项和功能区域时,可以快速集成
|
||
- **上下文感知**:根据点击位置和对象类型,显示相应的菜单项
|
||
- **简洁强大**:菜单项精简,但功能完整
|
||
|
||
### 1.2 适用范围
|
||
|
||
- **连接树区域**:连接、数据库、表/集合/Key节点的右键菜单
|
||
- **SQL编辑器区域**:编辑器内容、Tab标签的右键菜单(未来扩展)
|
||
- **结果区域**:表格、JSON内容的右键菜单(未来扩展)
|
||
|
||
### 1.3 设计原则
|
||
|
||
1. **按需显示**:根据节点类型和上下文,只显示相关的菜单项
|
||
2. **分组清晰**:相关功能分组,使用分隔线区分
|
||
3. **操作明确**:菜单项名称清晰,避免歧义
|
||
4. **快捷操作**:常用功能提供快捷键提示
|
||
|
||
---
|
||
|
||
## 二、连接树右键菜单设计
|
||
|
||
### 2.1 连接节点右键菜单
|
||
|
||
**触发条件**:右键点击连接节点
|
||
|
||
**菜单项**:
|
||
```
|
||
┌─────────────────────────┐
|
||
│ 查看结构 │
|
||
│ 编辑连接 │
|
||
│ 删除连接 │
|
||
├─────────────────────────┤
|
||
│ 刷新 │
|
||
│ 测试连接 │
|
||
└─────────────────────────┘
|
||
```
|
||
|
||
**菜单项说明**:
|
||
- **查看结构**:查看连接的数据库列表结构(如果支持)
|
||
- **编辑连接**:编辑连接配置
|
||
- **删除连接**:删除连接(需确认)
|
||
- **刷新**:刷新连接状态和数据库列表
|
||
- **测试连接**:测试连接是否可用
|
||
|
||
---
|
||
|
||
### 2.2 数据库节点右键菜单
|
||
|
||
**触发条件**:右键点击数据库节点
|
||
|
||
**菜单项(MySQL/MongoDB)**:
|
||
```
|
||
┌─────────────────────────┐
|
||
│ 查看结构 │
|
||
│ 生成SELECT语句 │
|
||
├─────────────────────────┤
|
||
│ 刷新 │
|
||
└─────────────────────────┘
|
||
```
|
||
|
||
**菜单项(Redis DB)**:
|
||
```
|
||
┌─────────────────────────┐
|
||
│ 查看结构 │
|
||
│ 生成KEYS命令 │
|
||
├─────────────────────────┤
|
||
│ 刷新 │
|
||
└─────────────────────────┘
|
||
```
|
||
|
||
**菜单项说明**:
|
||
- **查看结构**:查看数据库的表/集合列表结构
|
||
- **生成SELECT语句**:生成 `SELECT * FROM database.table LIMIT 100;`
|
||
- **生成KEYS命令**:生成 `KEYS *` 命令(Redis)
|
||
- **刷新**:刷新表/集合列表
|
||
|
||
---
|
||
|
||
### 2.3 表/集合节点右键菜单
|
||
|
||
**触发条件**:右键点击表/集合节点
|
||
|
||
**菜单项(MySQL)**:
|
||
```
|
||
┌─────────────────────────┐
|
||
│ 查看结构 │
|
||
│ 生成SELECT语句 │
|
||
│ 复制表名 │
|
||
├─────────────────────────┤
|
||
│ 刷新 │
|
||
└─────────────────────────┘
|
||
```
|
||
|
||
**菜单项(MongoDB)**:
|
||
```
|
||
┌─────────────────────────┐
|
||
│ 查看结构 │
|
||
│ 生成find语句 │
|
||
│ 复制集合名 │
|
||
├─────────────────────────┤
|
||
│ 刷新 │
|
||
└─────────────────────────┘
|
||
```
|
||
|
||
**菜单项说明**:
|
||
- **查看结构**:查看表/集合的结构信息(字段、索引等)
|
||
- **生成SELECT语句**:生成 `SELECT * FROM database.table LIMIT 100;`
|
||
- **生成find语句**:生成 `db.collection.find({})`(MongoDB)
|
||
- **复制表名/集合名**:复制到剪贴板
|
||
- **刷新**:刷新表结构
|
||
|
||
---
|
||
|
||
### 2.4 Key节点右键菜单(Redis)
|
||
|
||
**触发条件**:右键点击Key节点
|
||
|
||
**菜单项**:
|
||
```
|
||
┌─────────────────────────┐
|
||
│ 查看结构 │
|
||
│ 生成GET命令 │
|
||
│ 复制Key名 │
|
||
├─────────────────────────┤
|
||
│ 刷新 │
|
||
└─────────────────────────┘
|
||
```
|
||
|
||
**菜单项说明**:
|
||
- **查看结构**:查看Key的详细信息(类型、TTL、值预览)
|
||
- **生成GET命令**:根据Key类型生成相应命令(GET、HGETALL等)
|
||
- **复制Key名**:复制Key名称到剪贴板
|
||
- **刷新**:刷新Key信息
|
||
|
||
---
|
||
|
||
## 三、技术实现设计
|
||
|
||
### 3.1 组件结构
|
||
|
||
```
|
||
ContextMenu.vue (全局右键菜单组件)
|
||
├── 菜单项配置(根据节点类型动态生成)
|
||
├── 菜单项渲染(使用 Arco Design Dropdown)
|
||
└── 事件处理(触发相应操作)
|
||
|
||
ConnectionTree.vue
|
||
└── 集成 ContextMenu 组件
|
||
└── 根据节点类型传递菜单配置
|
||
```
|
||
|
||
### 3.2 菜单配置数据结构
|
||
|
||
```typescript
|
||
interface MenuItem {
|
||
key: string // 唯一标识
|
||
label: string // 显示文本
|
||
icon?: string // 图标(可选)
|
||
disabled?: boolean // 是否禁用
|
||
divider?: boolean // 是否为分隔线
|
||
children?: MenuItem[] // 子菜单(可选)
|
||
}
|
||
|
||
interface MenuConfig {
|
||
items: MenuItem[] // 菜单项列表
|
||
position: { // 菜单位置
|
||
x: number
|
||
y: number
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3.3 菜单项注册机制
|
||
|
||
```typescript
|
||
// 菜单项注册表
|
||
const menuRegistry = {
|
||
'connection': [
|
||
{ key: 'view-structure', label: '查看结构', icon: 'icon-eye' },
|
||
{ key: 'edit', label: '编辑连接', icon: 'icon-edit' },
|
||
{ key: 'delete', label: '删除连接', icon: 'icon-delete' },
|
||
{ key: 'divider-1', divider: true },
|
||
{ key: 'refresh', label: '刷新', icon: 'icon-refresh' },
|
||
{ key: 'test', label: '测试连接', icon: 'icon-check' }
|
||
],
|
||
'database': [
|
||
{ key: 'view-structure', label: '查看结构', icon: 'icon-eye' },
|
||
{ key: 'generate-sql', label: '生成SELECT语句', icon: 'icon-code' },
|
||
{ key: 'divider-1', divider: true },
|
||
{ key: 'refresh', label: '刷新', icon: 'icon-refresh' }
|
||
],
|
||
'table': [
|
||
{ key: 'view-structure', label: '查看结构', icon: 'icon-eye' },
|
||
{ key: 'generate-sql', label: '生成SELECT语句', icon: 'icon-code' },
|
||
{ key: 'copy-name', label: '复制表名', icon: 'icon-copy' },
|
||
{ key: 'divider-1', divider: true },
|
||
{ key: 'refresh', label: '刷新', icon: 'icon-refresh' }
|
||
],
|
||
// ... 其他节点类型
|
||
}
|
||
```
|
||
|
||
### 3.4 事件处理机制
|
||
|
||
```typescript
|
||
// 统一的事件处理接口
|
||
interface MenuEventHandler {
|
||
(nodeData: TreeNodeData, menuKey: string): void | Promise<void>
|
||
}
|
||
|
||
// 事件映射表
|
||
const eventHandlers: Record<string, MenuEventHandler> = {
|
||
'view-structure': (nodeData) => {
|
||
// 触发查看结构事件
|
||
emit('table-structure', {
|
||
connectionId: nodeData.connectionId,
|
||
database: nodeData.database,
|
||
tableName: nodeData.tableName || nodeData.title,
|
||
dbType: nodeData.dbType,
|
||
nodeType: nodeData.type
|
||
})
|
||
},
|
||
'edit': (nodeData) => {
|
||
emit('connection-edit', nodeData.connectionId)
|
||
},
|
||
'delete': (nodeData) => {
|
||
emit('connection-delete', nodeData.connectionId)
|
||
},
|
||
'generate-sql': (nodeData) => {
|
||
// 生成SQL语句
|
||
const sql = generateSQL(nodeData)
|
||
emit('table-select', { ...nodeData, sql })
|
||
},
|
||
'copy-name': (nodeData) => {
|
||
// 复制名称到剪贴板
|
||
copyToClipboard(nodeData.tableName || nodeData.title)
|
||
},
|
||
'refresh': (nodeData) => {
|
||
// 刷新节点数据
|
||
refreshNode(nodeData)
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 四、实现细节
|
||
|
||
### 4.1 菜单显示位置
|
||
|
||
- **定位方式**:使用鼠标事件坐标定位
|
||
- **边界处理**:菜单超出视口时自动调整位置
|
||
- **层级管理**:使用 z-index 确保菜单在最上层
|
||
|
||
### 4.2 菜单交互
|
||
|
||
- **点击外部关闭**:点击菜单外部区域自动关闭
|
||
- **ESC键关闭**:按ESC键关闭菜单
|
||
- **键盘导航**:支持方向键导航菜单项(可选,P2)
|
||
|
||
### 4.3 菜单样式
|
||
|
||
- **使用 Arco Design Dropdown**:保持与系统风格一致
|
||
- **图标支持**:菜单项支持图标显示
|
||
- **禁用状态**:禁用项显示为灰色,不可点击
|
||
- **分隔线**:使用分隔线区分功能组
|
||
|
||
---
|
||
|
||
## 五、扩展性设计
|
||
|
||
### 5.1 插件化菜单项
|
||
|
||
```typescript
|
||
// 菜单项插件接口
|
||
interface MenuItemPlugin {
|
||
name: string
|
||
condition: (nodeData: TreeNodeData) => boolean // 显示条件
|
||
getMenuItem: (nodeData: TreeNodeData) => MenuItem // 生成菜单项
|
||
handler: (nodeData: TreeNodeData) => void // 处理函数
|
||
}
|
||
|
||
// 注册插件
|
||
function registerMenuItemPlugin(plugin: MenuItemPlugin) {
|
||
// 注册逻辑
|
||
}
|
||
```
|
||
|
||
### 5.2 动态菜单项
|
||
|
||
- **权限控制**:根据用户权限动态显示/隐藏菜单项
|
||
- **上下文感知**:根据当前状态动态调整菜单项
|
||
- **条件显示**:某些菜单项只在特定条件下显示
|
||
|
||
---
|
||
|
||
## 六、实现优先级
|
||
|
||
### P0(必须实现)
|
||
1. ✅ 连接节点右键菜单(查看结构、编辑、删除、刷新)
|
||
2. ✅ 数据库节点右键菜单(查看结构、生成SQL、刷新)
|
||
3. ✅ 表节点右键菜单(查看结构、生成SQL、复制表名、刷新)
|
||
4. ✅ Key节点右键菜单(查看结构、生成命令、复制Key名、刷新)
|
||
|
||
### P1(重要功能)
|
||
1. 菜单定位和边界处理
|
||
2. 菜单项图标支持
|
||
3. 复制功能实现
|
||
|
||
### P2(优化功能)
|
||
1. 键盘导航支持
|
||
2. 菜单项插件化
|
||
3. 权限控制
|
||
|
||
---
|
||
|
||
## 七、总结
|
||
|
||
右键菜单系统设计遵循以下原则:
|
||
|
||
1. **统一设计**:所有区域的右键菜单使用统一的设计和交互
|
||
2. **易于扩展**:通过配置和插件机制,易于添加新功能
|
||
3. **上下文感知**:根据节点类型和状态,显示相关菜单项
|
||
4. **简洁强大**:菜单项精简但功能完整
|
||
|
||
通过以上设计,可以实现一个统一、易用、易扩展的右键菜单系统。
|
||
|