# 右键菜单系统设计 **设计日期**:2025-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 } // 事件映射表 const eventHandlers: Record = { '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. **简洁强大**:菜单项精简但功能完整 通过以上设计,可以实现一个统一、易用、易扩展的右键菜单系统。