Private
Public Access
1
0

重构:文件系统模块化架构,优化应用启动流程

This commit is contained in:
2026-01-28 00:28:54 +08:00
parent 4a9b25a505
commit 8c577f70e7
123 changed files with 32030 additions and 967 deletions

View File

@@ -0,0 +1,91 @@
# MVP开发路线图
**创建日期**2025-01-28
**基于**[MVP规划.md](./MVP规划.md)
**目标**以MVP为方向指引任务推进
---
## 一、当前状态
### 1.1 MVP完成度
详细完成度检查请参考:[MVP发布检查.md](../核对报告/MVP发布检查.md)
**快速概览**
- **核心功能P0**100% ✅
- **重要功能P1**100% ✅(表结构编辑可延后)
- **优化功能P2**0% ⬜
- **总体完成度**约90%
### 1.2 MVP发布评估
**✅ 已达到MVP发布标准**
详细评估请参考:[MVP发布检查.md](../核对报告/MVP发布检查.md)
---
## 二、MVP开发路线图
### 阶段1核心功能 ✅ 已完成2025-01-28
- ✅ 连接管理、SQL执行、表结构查看、右键菜单
### 阶段2重要功能 ✅ 已完成
- ✅ 测试连接功能
- ⚠️ 表结构编辑基础框架完成完整功能延后到1.1版本
- ❌ 书签管理、模板管理(已删除)
### 阶段3MVP发布 ✅ 已完成
- ✅ 测试用例完善、最终测试、发布准备
### 阶段4优化功能 ⬜ 后续迭代
- ⬜ 性能优化、用户体验优化、高级功能
---
## 三、基于MVP的任务优先级
### 3.1 MVP发布前P0
1.**核心功能** - 已完成
2.**测试连接功能** - 已完成
3.**完善测试用例** - MVP发布准备
### 3.2 MVP发布后P1
1.**表结构编辑完善** - 可编辑表格、数据验证、后端API
2.**性能优化** - 大数据量查询优化
3.**用户体验优化** - 快捷键、主题等
### 3.3 后续迭代P2
1.**高级功能** - 数据导出/导入、查询历史等
2.**多数据库扩展** - Oracle、ES、ClickHouse等
---
## 四、后续任务
### P1重要功能
- ⬜ 表结构编辑完善可编辑表格、数据验证、后端API
- ⬜ 性能优化:大数据量查询优化
### P2优化功能
- ⬜ 高级功能:数据导出/导入、查询历史等
- ⬜ 多数据库扩展Oracle、ES、ClickHouse等
---
## 五、发布决策
详细发布检查请参考:[MVP发布检查.md](../核对报告/MVP发布检查.md)
**当前状态**:✅ **已满足发布条件可以发布MVP v1.0**
**后续规划**
- 版本1.1:完善表结构编辑功能
- 版本1.2:性能优化和用户体验优化
---
## 六、相关文档
- [MVP规划.md](./MVP规划.md)
- [MVP发布检查.md](../核对报告/MVP发布检查.md)
- [任务规划.md](../任务规划.md)

View File

@@ -0,0 +1,234 @@
# 数据库客户端 MVP最小可用产品规划
**创建日期**2025-01-28
**目标**:定义最小可用产品范围,指导开发优先级
**原则**:核心功能优先,快速验证,迭代优化
---
## 一、MVP目标
### 1.1 核心价值
提供基础的数据库连接管理和SQL执行能力支持MySQL、Redis、MongoDB三种数据库类型的基本操作。
### 1.2 用户场景
- **场景1**开发者需要快速连接数据库并执行SQL查询
- **场景2**:开发者需要查看表结构信息
- **场景3**:开发者需要管理多个数据库连接
### 1.3 成功标准
- ✅ 可以创建、编辑、删除数据库连接
- ✅ 可以执行SQL/命令并查看结果
- ✅ 可以查看表/集合/Key的结构信息
- ✅ 支持MySQL、Redis、MongoDB三种数据库类型
---
## 二、MVP功能范围
### 2.1 核心功能P0 - 必须)
#### 2.1.1 连接管理 ✅
- ✅ 创建数据库连接MySQL、Redis、MongoDB
- ✅ 编辑数据库连接
- ✅ 删除数据库连接
- ✅ 连接列表管理
- ✅ 连接信息持久化存储
**状态**:✅ 已完成
#### 2.1.2 SQL/命令执行 ✅
- ✅ SQL编辑器暂时只保留一个编辑区
- ✅ SQL执行MySQL
- ✅ 命令执行Redis、MongoDB
- ✅ 结果展示表格、JSON
- ✅ 执行统计(影响行数、执行时间)
- ✅ SQL内容自动保存
- ⚠️ 多Tab支持暂时移除后续版本恢复
**状态**:✅ 已完成
#### 2.1.3 表结构查看 ✅
- ✅ MySQL表结构查看字段、索引
- ✅ MongoDB集合结构查看文档示例、字段统计、索引
- ✅ Redis Key信息查看类型、TTL、值预览
- ✅ 右键菜单触发
- ✅ 结构信息展示
**状态**:✅ 已完成
#### 2.1.4 右键菜单系统 ✅
- ✅ 连接节点右键菜单
- ✅ 数据库节点右键菜单
- ✅ 表/集合/Key节点右键菜单
- ✅ 菜单项动态显示
- ✅ 菜单功能集成
**状态**:✅ 已完成
---
### 2.2 重要功能P1 - 重要但非必需)
#### 2.2.1 表结构编辑 ⚠️
- ✅ 编辑模式框架
- ⬜ 可编辑表格实现
- ⬜ 数据验证
- ⬜ 后端API实现
**状态**:⚠️ 基础框架完成40%
---
### 2.3 优化功能P2 - 可延后)
#### 2.3.1 高级功能
- ⬜ 数据导出/导入
- ⬜ 查询历史记录
- ⬜ SQL格式化
- ⬜ 自动补全增强
#### 2.3.2 性能优化
- ⬜ 大数据量查询优化
- ⬜ 连接池优化
- ⬜ 前端渲染优化
#### 2.3.3 用户体验优化
- ⬜ 快捷键支持
- ⬜ 主题切换
- ⬜ 布局自定义
---
## 三、MVP功能清单
### 已完成功能 ✅
- ✅ 核心功能P0连接管理、SQL执行、表结构查看、右键菜单
- ✅ 重要功能P1测试连接
- ⚠️ 表结构编辑编辑框架完成完整功能待1.1版本
### 已删除功能 ❌
- ❌ 书签管理功能(已删除)
- ❌ SQL模板管理功能已删除
### 待实现功能 ⬜
- P1表结构编辑完整实现可编辑表格、数据验证、后端API
- P2性能优化、用户体验优化、高级功能
---
## 四、MVP发布标准
### 4.1 功能完整性
- ✅ 核心功能P0全部完成
- ⚠️ 重要功能P1基本完成表结构编辑可延后
- ⬜ 优化功能P2可延后
### 4.2 质量标准
- ✅ 无阻塞性Bug
- ✅ 核心功能测试通过
- ✅ 代码质量检查通过
- ✅ 文档完整
### 4.3 用户体验
- ✅ 基本操作流畅
- ✅ 错误提示清晰
- ✅ 界面简洁易用
---
## 五、MVP开发路线图
### 阶段1核心功能 ✅ 已完成
- ✅ 连接管理
- ✅ SQL执行
- ✅ 表结构查看
- ✅ 右键菜单
**完成时间**2025-01-28
### 阶段2重要功能 ⚠️ 进行中
- ✅ 书签管理(基本完成)
- ✅ 模板管理(基本完成)
- ⚠️ 表结构编辑(基础框架完成,待完善)
**预计完成时间**2025-01-29
### 阶段3优化功能 ⬜ 待开始
- ⬜ 性能优化
- ⬜ 用户体验优化
- ⬜ 高级功能
**预计开始时间**阶段2完成后
---
## 六、MVP功能优先级
### P0必须完成- MVP核心
1. ✅ 连接管理(创建、编辑、删除)
2. ✅ SQL/命令执行
3. ✅ 结果展示
4. ✅ 表结构查看
5. ✅ 右键菜单系统
### P1重要功能- MVP增强
1. ✅ 测试连接功能
2. ⚠️ 表结构编辑(基础框架完成,可延后)
### P2优化功能- 后续迭代
1. ⬜ 性能优化
2. ⬜ 用户体验优化
3. ⬜ 高级功能
---
## 七、MVP当前状态
### 7.1 完成度统计
- **核心功能P0**100% ✅
- **重要功能P1**100% ✅(表结构编辑可延后)
- **优化功能P2**0% ⬜
- **总体完成度**约90%
### 7.2 可发布性评估
详细发布评估请参考:[MVP发布检查.md](../核对报告/MVP发布检查.md)
**结论****当前版本已达到MVP标准可以发布MVP版本**
---
## 八、MVP后续迭代计划
### 版本1.1MVP+
- 完善表结构编辑功能
- 实现测试连接功能
- 优化用户体验
### 版本1.2(增强版)
- 性能优化
- 数据导出/导入
- 查询历史记录
### 版本2.0(完整版)
- 高级功能
- 插件系统
- 协作功能
---
## 九、发布建议
详细检查结果请参考:[MVP发布检查.md](../核对报告/MVP发布检查.md)
-**MVP版本**:当前版本即可发布(核心功能完整)
- ⚠️ **表结构编辑**可延后到1.1版本
-**后续优化**:性能优化、用户体验优化(后续迭代)
---
## 十、相关文档
- [需求设计/需求.md](./需求设计/需求.md)
- [MVP开发路线图.md](./MVP开发路线图.md)
- [MVP发布检查.md](../核对报告/MVP发布检查.md)
- [任务规划.md](../任务规划.md)

View File

@@ -0,0 +1,109 @@
# 设计文档
## 目录说明
设计文档用于存储功能设计、架构设计等设计相关文档。
### 核心原则
1. **抽象与实现分离**:设计文档描述"做什么"和"为什么",不描述"怎么做"
2. **引用知识库**:设计文档应引用知识库中的规范和参考
3. **关联决策**设计文档应关联相关的决策记录ADR
---
## 📋 需求设计
**位置**`需求设计/`
**用途**:功能需求、业务需求
### 文档类型
- 功能需求文档
- 数据库类型差异分析
- 业务规则说明
---
## 🏗️ 架构设计
**位置**`架构设计/`
**用途**:系统架构、组件架构设计
### 文档类型
- 前端架构设计
- 后端架构设计
- 事件系统设计
- 右键菜单系统设计
---
## ⚙️ 功能设计
**位置**`功能设计/`
**用途**:具体功能的设计文档
### 文档类型
- 表结构查看功能设计
- 多表结构查看方案分析
- 待讨论问题汇总
---
## 🎨 样式设计
**位置**:根目录
**用途**:前端布局和样式系统设计
### 文档类型
- 前端布局样式系统设计
---
## 📝 设计文档模板
### 功能设计模板
```markdown
# {功能名称}设计
**状态**{设计中|已完成|已废弃}
**创建日期**YYYY-MM-DD
**最后更新**YYYY-MM-DD
## 一、设计目标
功能要解决什么问题?
## 二、设计约束
引用:[知识库/规范/编码规范.md](../../知识库/规范/编码规范.md)
## 三、设计方案
### 3.1 方案概述
### 3.2 详细设计
## 四、相关决策
- [ADR-{序号}](../../决策记录/ADR-{序号}.md)
## 五、待讨论问题
- [问题追踪/待讨论/{问题}.md](../../问题追踪/待讨论/{问题}.md)
## 六、实现计划
1. 步骤1
2. 步骤2
```
---
## 🔗 关联关系
设计文档应明确关联:
- **知识库**:引用的规范和参考
- **决策记录**:相关的架构决策
- **问题追踪**:待讨论和待实现的问题

View File

@@ -0,0 +1,118 @@
# SQL历史功能设计
**设计日期**2025-01-28
**设计目标**明确SQL历史功能的设计SQL由SQL编辑区保存得到
---
## 一、功能定位
### 1.1 核心概念
**SQL历史**自动记录SQL编辑区的Tab历史用于追溯和恢复之前编辑的SQL内容。
### 1.2 功能特征
-**自动记录**系统自动记录SQL编辑区的Tab内容
-**时间序列**:按时间顺序记录
-**追溯功能**查看之前编辑了什么SQL
-**快速恢复**双击历史记录恢复到SQL编辑器
---
## 二、数据来源
### 2.1 数据来源
SQL历史数据来源于 **SQL编辑区的Tab**
- 每个SQL编辑Tab的内容自动保存到SQLite
- Tab的创建、更新、删除都会同步到历史记录
- 历史记录显示所有已保存的Tab内容
### 2.2 数据结构
```typescript
interface SqlHistory {
id: number
title: string // Tab标题如"查询 1"
content: string // SQL内容
connectionId?: number // 关联的连接ID可选
tabId?: string // 关联Tab ID
createdAt: number // 创建时间
updatedAt: number // 更新时间
}
```
---
## 三、功能实现
### 3.1 数据同步
SQL历史与SQL编辑区的Tab实时同步
```typescript
// index.vue
watch(() => sqlEditorRef.value, (editor: any) => {
if (editor && typeof editor.getTabs === 'function') {
sqlEditorTabs.value = editor.getTabs()
}
}, { immediate: true, deep: true })
```
### 3.2 使用流程
```
用户双击历史记录
SqlHistoryList → emit('use-history', content)
ResourcePanel → emit('use-resource', content)
index.vue → handleUseResource(content)
SqlEditor.insertSQL(content) → 替换当前Tab内容
```
---
## 四、UI展示
### 4.1 显示位置
SQL历史显示在左侧资源管理面板的"SQL历史"Tab中。
### 4.2 显示内容
- Tab标题
- 相对时间刚刚、X分钟前、X小时前
- 连接信息(如果有)
### 4.3 交互方式
- **双击**使用历史记录加载到当前Tab
- **右键菜单**:编辑、删除等(待实现)
---
## 五、后续扩展
### 5.1 待实现功能
- SQL执行历史记录记录执行的SQL、结果、时间
- 历史搜索功能
- 历史删除功能
- 从历史"保存为书签"(待书签功能实现后)
### 5.2 其他概念
- **书签**个人收藏的常用SQL待实现
- **模板**标准SQL模板待实现
---
## 六、相关文档
- [左侧资源管理面板设计.md](./左侧资源管理面板设计.md)
- [需求设计/需求.md](../需求设计/需求.md)

View File

@@ -0,0 +1,314 @@
# 多表结构查看方案分析
**分析日期**2025-01-28
**分析范围**:多表结构查看的不同实现方案
**状态**:方案分析
---
## 一、需求分析
### 1.1 使用场景
用户可能需要:
- 同时查看多个表的结构,进行对比
- 查看表结构时,需要查看其他表的结构作为参考
- 在SQL编写过程中需要频繁查看不同表的结构
### 1.2 当前限制
- **方案一**:单表查看,查看新表时替换当前结构
- 优点:简单直接,界面不混乱
- 缺点:无法同时查看多个表的结构
---
## 二、方案对比
### 方案一结果面板Tab中查看当前方案
**实现方式**
- 在结果面板的"结构"Tab中查看
- 查看新表时替换当前结构
**优点**
- ✅ 实现简单
- ✅ 界面简洁
- ✅ 符合当前架构
**缺点**
- ❌ 无法同时查看多个表
- ❌ 切换表时丢失之前的结构信息
**适用场景**
- 单表结构查看
- 临时查看表结构
---
### 方案二SQL编辑器Tab中展示
**实现方式**
- 在SQL编辑器的Tab区域新增"结构"类型的Tab
- 每个表结构作为一个独立的Tab
- Tab标题`结构: database.table`
**界面布局**
```
┌─────────────────────────────────────────────────────────┐
│ SQL编辑器区域 │
├─────────────────────────────────────────────────────────┤
│ [查询 1] [查询 2] [结构: test.users] [结构: test.orders] │
├─────────────────────────────────────────────────────────┤
│ │
│ [结构内容区域] │
│ - 字段信息 │
│ - 索引信息 │
│ │
└─────────────────────────────────────────────────────────┘
```
**优点**
- ✅ 可以同时查看多个表的结构
- ✅ Tab管理统一用户习惯好
- ✅ 结构Tab和SQL Tab可以并存方便对比
**缺点**
- ⚠️ SQL编辑器Tab区域可能变得拥挤
- ⚠️ 需要区分SQL Tab和结构Tab
- ⚠️ Tab切换逻辑更复杂
**实现细节**
```typescript
// Tab类型定义
interface Tab {
id: string
key: string
title: string
type: 'sql' | 'structure' // Tab类型
content?: string // SQL内容仅SQL Tab
structureData?: StructureData // 结构数据仅结构Tab
connectionId?: number
database?: string
tableName?: string
}
// Tab管理
const tabs = ref<Tab[]>([])
// 创建结构Tab
const createStructureTab = (data: TableStructureEvent) => {
const tabKey = `structure-${data.connectionId}-${data.database}-${data.tableName}`
// 检查是否已存在
const existingTab = tabs.value.find(t => t.key === tabKey)
if (existingTab) {
activeTab.value = existingTab.key
return
}
// 创建新Tab
const newTab: Tab = {
id: null,
key: tabKey,
title: `结构: ${data.database}.${data.tableName}`,
type: 'structure',
connectionId: data.connectionId,
database: data.database,
tableName: data.tableName,
structureData: null // 异步加载
}
tabs.value.push(newTab)
activeTab.value = newTab.key
// 异步加载结构数据
loadStructureData(newTab)
}
```
---
### 方案三结构Tab内部子Tab
**实现方式**
- 在结果面板的"结构"Tab内部使用子Tab区分不同表
- 子Tab标题`database.table`
**界面布局**
```
┌─────────────────────────────────────────────────────────┐
│ 结果面板 │
├─────────────────────────────────────────────────────────┤
│ [结果] [消息] [结构] │
├─────────────────────────────────────────────────────────┤
│ [test.users] [test.orders] [test.products] │
├─────────────────────────────────────────────────────────┤
│ │
│ [当前表结构内容] │
│ │
└─────────────────────────────────────────────────────────┘
```
**优点**
- ✅ 结构查看区域独立不影响SQL编辑器
- ✅ 可以同时查看多个表的结构
- ✅ 结构Tab位置固定用户习惯好
**缺点**
- ⚠️ 结构Tab内部Tab管理复杂度中等
- ⚠️ Tab层级较深可能影响用户体验
---
### 方案四:侧边栏结构查看器
**实现方式**
- 在左侧连接树区域,新增一个可折叠的结构查看面板
- 或者使用抽屉Drawer从侧边滑出
**界面布局**
```
┌──────────┬─────────────────────────────────────────┐
│ 连接树 │ SQL编辑器 │
│ │ │
│ [结构] │ │
│ ────────│ │
│ test.users│ │
│ - 字段 │ │
│ - 索引 │ │
└──────────┴─────────────────────────────────────────┘
```
**优点**
- ✅ 结构查看区域独立
- ✅ 可以同时查看多个表使用Tab
- ✅ 不影响SQL编辑器和结果区域
**缺点**
- ⚠️ 需要额外的UI空间
- ⚠️ 可能影响连接树的显示
---
## 三、方案推荐
### 3.1 短期方案P0
**推荐:方案一(当前方案)+ 方案二(可选)**
- **默认使用方案一**:在结果面板的"结构"Tab中查看查看新表时替换
- **可选支持方案二**:通过右键菜单选项"在新Tab中查看结构"在SQL编辑器Tab区域创建结构Tab
**实现策略**
1. 右键菜单添加"查看结构"和"在新Tab中查看结构"两个选项
2. "查看结构":使用方案一(结果面板)
3. "在新Tab中查看结构"使用方案二SQL编辑器Tab
---
### 3.2 长期方案P2
**推荐方案三结构Tab内部子Tab**
- 在结果面板的"结构"Tab内部使用子Tab管理多个表结构
- 提供更好的多表对比体验
- 不影响SQL编辑器Tab区域
---
## 四、实现建议
### 4.1 方案二实现要点
**Tab类型区分**
```typescript
// Tab类型
type TabType = 'sql' | 'structure'
// Tab渲染
<template>
<a-tab-pane
v-for="tab in tabs"
:key="tab.key"
:title="tab.title"
>
<!-- SQL Tab -->
<SqlEditorContent v-if="tab.type === 'sql'" :tab="tab" />
<!-- 结构Tab -->
<StructureContent v-else-if="tab.type === 'structure'" :tab="tab" />
</a-tab-pane>
</template>
```
**Tab标题样式**
- SQL Tab`查询 1``查询 2`
- 结构Tab`结构: database.table`(使用不同颜色或图标区分)
**Tab关闭逻辑**
- SQL Tab可以关闭最后一个不可关闭
- 结构Tab可以关闭关闭时清除结构数据
---
### 4.2 方案三实现要点
**子Tab管理**
```typescript
// 结构Tab状态
const structureTabs = ref<Array<{
key: string
title: string
connectionId: number
database: string
tableName: string
data: StructureData | null
}>>([])
const activeStructureTab = ref<string>('')
```
**Tab切换**
- 查看新表结构时如果已存在则切换到对应Tab
- 如果不存在创建新Tab并加载数据
---
## 五、用户体验对比
| 方案 | 多表查看 | 界面简洁 | 实现复杂度 | 用户习惯 |
|------|---------|---------|-----------|---------|
| 方案一 | ❌ | ✅ | ✅ 低 | ✅ 好 |
| 方案二 | ✅ | ⚠️ | ⚠️ 中 | ✅ 好 |
| 方案三 | ✅ | ✅ | ⚠️ 中 | ⚠️ 中 |
| 方案四 | ✅ | ⚠️ | ⚠️ 中 | ⚠️ 中 |
---
## 六、最终建议
### 6.1 实现策略
**阶段一P0**
- 实现方案一:结果面板"结构"Tab单表查看
- 右键菜单:添加"查看结构"选项
**阶段二P1**
- 扩展方案二:支持"在新Tab中查看结构"
- 右键菜单:添加"在新Tab中查看结构"选项
- SQL编辑器Tab区域支持结构Tab类型
**阶段三P2**
- 考虑方案三结构Tab内部子Tab
- 提供更好的多表对比体验
### 6.2 决策要点
- **先实现方案一**:满足基本需求,实现简单
- **后续扩展方案二**:提供多表查看能力,不影响现有功能
- **未来考虑方案三**:如果用户反馈需要更好的多表查看体验
---
**结论**先使用方案一单表查看后续根据用户反馈决定是否实现方案二SQL编辑器Tab或方案三结构Tab子Tab

View File

@@ -0,0 +1,277 @@
# 左侧资源管理面板设计
**设计日期**2025-01-28
**设计目标**在左侧功能区下方增加资源管理面板统一管理SQL编辑器历史、书签和SQL模板
---
## 一、需求概述
### 1.1 功能目标
- 在左侧功能区分上下两部分
- 下方增加资源管理面板(参考数据库连接树的效果)
- 整合SQL编辑器历史、书签、SQL模板列表
### 1.2 设计原则
- 保持与数据库连接树一致的UI风格
- 支持折叠/展开
- 支持快速访问和操作
---
## 二、布局设计
### 2.1 整体布局
```
┌─────────────────────────┐
│ 左侧功能区(上下分区) │
├─────────────────────────┤
│ 上部分:数据库连接树 │
│ - 连接列表 │
│ - 数据库/表结构 │
├─────────────────────────┤
│ 下部分:资源管理面板 │
│ ┌─────────────────────┐ │
│ │ 资源管理(可折叠) │ │
│ ├─────────────────────┤ │
│ │ 📝 SQL编辑器历史 │ │
│ │ ⭐ 书签 │ │
│ │ 📋 SQL模板 │ │
│ └─────────────────────┘ │
└─────────────────────────┘
```
### 2.2 布局参数
- **上部分(连接树)**:可调整高度,默认占 60%
- **下部分(资源面板)**:可调整高度,默认占 40%
- **分隔条**:支持拖拽调整上下比例
- **最小高度**:每部分最小 150px
---
## 3. 组件设计
### 3.1 ResourcePanel 组件
#### 3.1.1 组件结构
```vue
<template>
<div class="resource-panel">
<!-- 头部标题和折叠按钮 -->
<div class="resource-panel-header">
<h3>资源管理</h3>
<a-button type="text" @click="toggleCollapse">
<icon-up v-if="!collapsed" />
<icon-down v-else />
</a-button>
</div>
<!-- 内容区域 -->
<div v-show="!collapsed" class="resource-panel-content">
<!-- Tab切换 -->
<a-tabs v-model:active-key="activeTab">
<a-tab-pane key="history" title="SQL历史">
<SqlHistoryList />
</a-tab-pane>
<a-tab-pane key="bookmarks" title="书签">
<BookmarkList />
</a-tab-pane>
<a-tab-pane key="templates" title="模板">
<TemplateList />
</a-tab-pane>
</a-tabs>
</div>
</div>
</template>
```
#### 3.1.2 功能特性
- **折叠/展开**:支持收起资源面板以节省空间
- **Tab切换**三个Tab分别显示SQL历史、书签、模板
- **搜索功能**每个Tab支持搜索过滤
- **右键菜单**:支持编辑、删除、使用等操作
---
## 四、子组件设计
### 4.1 SqlHistoryListSQL编辑器历史
#### 4.1.1 数据结构
```typescript
interface SqlHistoryItem {
id: string
title: string
content: string
connectionId: number | null
database: string | null
createdAt: number
updatedAt: number
}
```
#### 4.1.2 功能
- 显示所有SQL编辑器Tab的历史记录
- 支持按连接、数据库筛选
- 支持搜索(标题、内容)
- 支持双击打开到新Tab
- 支持右键删除
#### 4.1.3 UI设计
- 树形列表参考ConnectionTree
- 每个历史项显示:标题、连接信息、更新时间
- 支持拖拽排序(按使用频率)
---
### 4.2 BookmarkList书签列表
#### 4.2.1 数据结构
```typescript
interface BookmarkItem {
id: number
name: string
sql: string
connectionId: number | null
database: string | null
description?: string
createdAt: number
}
```
#### 4.2.2 功能
- 显示所有书签
- 支持按连接筛选
- 支持搜索名称、SQL、描述
- 支持双击使用(插入到当前编辑器)
- 支持右键编辑、删除
#### 4.2.3 UI设计
- 树形列表参考ConnectionTree
- 每个书签显示:名称、描述、连接信息
- 支持分组(按连接分组)
---
### 4.3 TemplateListSQL模板列表
#### 4.3.1 数据结构
```typescript
interface TemplateItem {
id: number
name: string
sql: string
category?: string
description?: string
createdAt: number
}
```
#### 4.3.2 功能
- 显示所有SQL模板
- 支持按分类筛选
- 支持搜索名称、SQL、描述
- 支持双击使用(插入到当前编辑器)
- 支持右键编辑、删除
#### 4.3.3 UI设计
- 树形列表参考ConnectionTree
- 每个模板显示:名称、分类、描述
- 支持分组(按分类分组)
---
## 五、交互设计
### 5.1 折叠/展开
- 点击头部折叠按钮,收起/展开资源面板
- 折叠时只显示头部 (收缩下压到底部,让内容区留给连接列表)
- 展开时显示完整内容
### 5.2 高度调整
- 上下两部分之间可拖拽调整高度
- 支持双击重置为默认比例
- 最小高度限制:每部分 150px
### 5.3 快速操作
- **双击**:使用资源(打开历史/插入书签或模板)
- **右键**:显示上下文菜单(编辑、删除、复制等)
- **拖拽**:调整顺序(历史记录)
---
## 六、实现方案
### 6.1 组件结构
```
components/
ResourcePanel.vue # 主面板组件
SqlHistoryList.vue # SQL历史列表
BookmarkList.vue # 书签列表
TemplateList.vue # 模板列表
```
### 6.2 状态管理
- 使用 `useResourcePanel` composable 管理面板状态
- 使用现有的 `useMessageLog``useDbConnection` 等 composables
### 6.3 数据来源
- **SQL历史**:从 `SqlEditor` 组件的 `tabs` 状态获取
- **书签**:从后端 API 获取(已有 `GetBookmarks`
- **模板**:从后端 API 获取(已有 `GetTemplates`
---
## 七、样式设计
### 7.1 参考ConnectionTree样式
- 使用相同的字体、颜色、间距
- 使用相同的树形节点样式
- 使用相同的图标风格
### 7.2 自定义样式
- 面板头部:与连接树头部一致
- Tab切换紧凑型Tab样式
- 列表项:与连接树节点一致
---
## 八、技术实现要点
### 8.1 布局实现
- 使用 Flexbox 实现上下分区
- 使用 `ResizeObserver` 或自定义拖拽条实现高度调整
- 使用 `v-show` 实现折叠/展开动画
### 8.2 数据同步
- SQL历史与编辑器Tabs实时同步
- 书签和模板从后端加载,支持刷新
### 8.3 性能优化
- 列表虚拟滚动(如果数据量大)
- 懒加载(按需加载历史记录)
- 防抖搜索
---
## 九、后续扩展
### 9.1 功能扩展
- 支持收藏常用SQL
- 支持导出/导入资源
- 支持资源分组和标签
### 9.2 UI扩展
- 支持自定义面板位置(可拖拽到右侧)
- 支持多面板模式
- 支持面板主题切换
---
## 十、相关文档
- [前端布局样式系统设计.md](../需求设计/前端布局样式系统设计.md)
- [ConnectionTree.vue](../../../../go-desk/web/src/views/db-cli/components/ConnectionTree.vue)

View File

@@ -0,0 +1,374 @@
# 表结构查看功能 - 待讨论问题
**创建日期**2025-01-28
**目的**:整理设计文档中需要进一步讨论和明确的问题
---
## 一、实现细节待明确
### 1.1 MongoDB 字段统计实现方式
**问题**FIXME标记 - 使用采样统计默认采样10个文档
**需要讨论**
- ✅ 已确定使用采样统计默认采样10个文档
- ⚠️ 待明确:
- 采样方式:使用 `$sample` 聚合管道还是 `find().limit(10)` FIME:sample
- 采样数量10个是否足够是否需要可配置 FIXME:后期支持可配置
- 性能影响10个文档的性能如何是否需要异步加载 FIXME: 全异步
- 前端展示:是否需要显示"基于10个文档采样"的提示FIXME: 展示
**建议**
- 使用 `$sample` 聚合管道随机采样(更准确)
- 默认采样10个文档性能好准确性适中
- 前端明确标注"基于10个文档采样统计"
- 后续可扩展为可配置采样数量P2
---
### 1.2 触发查看结构(已确定)
**触发方式**
- ✅ 点击连接节点:查看连接的数据库列表结构
- ✅ 点击数据库节点:查看数据库的表/集合列表结构
- ✅ 点击表/集合/Key节点查看具体的表/集合/Key结构
- ✅ 结构信息展示区域自动激活(切换到"结构"Tab并打开
**实现方式**
-`handleTreeSelect` 中,根据节点类型触发 `table-structure` 事件
- 事件处理函数自动切换到结果面板的"结构"Tab
- 如果结果面板隐藏,自动显示
---
### 1.3 连接树右键菜单实现
**问题**:如何实现右键菜单触发"查看结构"
**需要讨论**
- ⚠️ 待明确:
- Arco Design Tree 组件是否支持右键菜单?
- 如果不支持,是否需要自定义实现?
- 右键菜单的选项有哪些查看结构、生成SQL、删除等
- 菜单位置和样式如何设计?
**建议**
- 检查 Arco Design Tree 的右键菜单支持
- 如果不支持,使用 `@contextmenu` 事件自定义菜单
- 菜单选项查看结构、生成SELECT语句、复制表名根据节点类型显示不同选项
FIXME: 系统性设计右键菜单补充相关设计文档
---
### 1.4 事件名称和参数传递(已确定)
**事件名称**:✅ `table-structure`
**参数格式**:✅ 已确定
```typescript
emit('table-structure', {
connectionId: number,
database: string,
tableName: string, // 表名/集合名/Key名对于连接和数据库节点可能为空
dbType: 'mysql' | 'mongo' | 'redis',
nodeType: 'table' | 'collection' | 'key' | 'database' | 'connection'
})
```
**事件处理**
-`index.vue` 中监听 `table-structure` 事件
- 调用 `useStructureState.loadStructure()` 加载结构数据
- 自动切换到结果面板的"结构"Tab
**详细设计**:详见 `事件系统设计.md`
---
### 1.5 结构Tab的显示/隐藏逻辑(已确定)
**方案**:✅ **方案二 - 始终显示Tab**
**实现方式**
- "结构"Tab始终显示在结果面板中
- 无数据时显示空状态提示:"请从连接树中选择节点查看结构"
- 有数据时显示结构内容
- 切换连接时,清空结构数据,显示空状态
- 执行SQL时结构Tab保留不清空数据
**优点**
- ✅ Tab位置固定用户习惯更好
- ✅ 用户可以随时查看结构,无需先触发查看
**空状态设计**
- 显示图标和提示文本
- 提供操作引导:"右键点击连接树节点 → 查看结构"
---
### 1.6 多表结构查看场景(已确定)
**方案**:✅ **方案一 - 单表查看,查看新表时替换当前结构**
**实现方式**
- 查看新表时,替换当前结构数据
- 结构Tab始终只有一个表的结构
- 简单直接,符合当前设计
**未来扩展**
- **方案二**在SQL编辑器Tab区域支持结构Tab
- 右键菜单添加"在新Tab中查看结构"选项
- 在SQL编辑器Tab区域创建结构Tab
- 可以同时查看多个表的结构
- 详见 `多表结构查看方案分析.md`
**当前阶段**
- P0使用方案一单表查看
- P2考虑实现方案二SQL编辑器Tab支持结构Tab
---
### 1.6 结构数据与查询结果的冲突
**问题**查看结构时执行SQL如何处理结果展示
**需要讨论**
- ⚠️ 待明确:
- 执行SQL时结构Tab是否自动切换到"结果"Tab
- 结构数据是否保留,还是清空?
- 用户如何切换回结构Tab
**建议**FIXME: OK
- 执行SQL时自动切换到"结果"Tab
- 结构数据保留,不清空
- 用户可以手动切换回"结构"Tab继续查看
---
## 二、技术实现待明确
### 2.1 数据缓存策略
**问题**:结构数据缓存的具体实现
**需要讨论**
- ⚠️ 待明确:
- 缓存位置:前端缓存(内存)还是后端缓存?
- 缓存Key如何生成唯一KeyconnectionId + database + tableName
- 缓存时间5分钟是否合适
- 缓存失效:何时清除缓存?(切换连接、表结构变更后)
**建议**OK
- 前端缓存:使用 Map 存储Key为 `${connectionId}-${database}-${tableName}`
- 缓存时间5分钟可配置
- 缓存失效:切换连接时清除,手动刷新时清除
---
### 2.2 权限检查实现
**问题**:编辑功能如何检查数据库用户权限
**需要讨论**
- ⚠️ 待明确:
- 权限检查时机:编辑模式切换时还是保存时?
- 权限检查方式:如何检查 ALTER TABLE、CREATE INDEX 权限?
- 权限不足时的提示:如何友好地提示用户?
**建议**OK
- 切换编辑模式时检查权限
- 使用 `SHOW GRANTS` 或尝试执行测试语句检查权限
- 权限不足时禁用编辑功能,显示提示信息
---
### 2.3 确认对话框设计
**问题**:编辑保存时的确认对话框内容
**需要讨论**
- ⚠️ 待明确:
- 对话框内容显示什么信息SQL语句、影响范围、风险提示
- 确认方式:是否需要二次确认?
- 取消操作:取消时如何处理未保存的修改?
**建议**OK
- 显示将要执行的 SQL 语句(完整 ALTER TABLE 语句)
- 显示影响范围(修改的字段/索引数量)
- 显示风险提示("此操作不可撤销,请确认"
- 取消时保留编辑内容,不切换回查看模式
---
### 2.4 错误处理和重试
**问题**:加载结构数据失败时的处理
**需要讨论**
- ⚠️ 待明确:
- 错误提示:如何显示错误信息?
- 重试机制:是否自动重试?重试次数?
- 部分失败:如果部分数据加载成功,如何处理?
**建议**OK
- 显示详细的错误信息(错误类型、错误消息)
- 提供"重试"按钮,不自动重试
- 部分失败时显示已加载的数据,标注失败的部分
---
## 三、用户体验待明确
### 3.1 加载状态展示
**问题**:加载结构数据时的用户体验
**需要讨论**
- ⚠️ 待明确:
- 加载提示显示什么内容Spin、进度条、加载文本
- 加载时间:如果加载较慢,是否需要超时处理?
- 骨架屏:是否需要使用骨架屏提升体验?
**建议**OK
- 使用 Arco Design Spin 组件 + "加载中..."文本
- 设置超时时间30秒超时后提示用户
- 大数据集时显示"数据较多,加载可能需要一些时间"的提示
---
### 3.2 空状态设计
**问题**:无结构数据时的展示
**需要讨论**
- ⚠️ 待明确:
- 空状态内容:显示什么提示?
- 操作引导:是否需要提供操作按钮?
**建议**OK
- 显示空状态图标和提示文本
- 提供"刷新"按钮
- 根据数据库类型显示不同的提示MySQL/MongoDB/Redis
---
### 3.3 数据刷新策略
**问题**:何时自动刷新结构数据
**需要讨论**
- ⚠️ 待明确:
- 自动刷新:是否需要自动刷新?(表结构可能被其他工具修改)
- 刷新时机切换Tab时定时刷新
- 手动刷新:刷新按钮的位置和样式?
**建议**OK
- 不自动刷新(避免不必要的请求)
- 提供手动刷新按钮在结构Tab工具栏
- 编辑保存后自动刷新
---
## 四、扩展功能待明确
### 4.1 导出功能实现
**问题**:导出功能的具体实现方式
**需要讨论**
- ⚠️ 待明确:
- 导出格式SQL、JSON、文本的具体格式
- 导出内容:导出哪些信息?(字段、索引、注释等)
- 导出方式:下载文件还是复制到剪贴板?
**建议**OK
- MySQL导出为 CREATE TABLE 语句(包含字段、索引、注释)
- MongoDB导出为 JSON Schema 格式
- Redis导出为文本格式Key信息 FIXME: 不需要
- 支持下载文件和复制到剪贴板两种方式
---
### 4.2 编辑功能的撤销/重做
**问题**:编辑模式是否需要撤销/重做功能
**需要讨论**
- ⚠️ 待明确:
- 是否需要撤销/重做功能?
- 如果需要,如何实现?(历史记录、操作栈)
- 撤销范围:单次操作还是多次操作?
**建议**OK
- P2功能暂不实现
- 如果需要,使用操作栈记录每次修改
- 支持撤销最近10次操作
---
## 五、性能优化待明确
### 5.1 大数据集处理
**问题**:字段/索引很多时的性能优化
**需要讨论**
- ⚠️ 待明确:
- 分页加载:何时启用分页?(字段数 > 50
- 虚拟滚动:是否需要虚拟滚动?
- 懒加载Tab切换时是否懒加载内容
**建议**OK
- 字段数 > 50 时启用分页每页20条
- 使用 Arco Design Table 的内置分页
- Tab切换时懒加载使用 v-if
---
### 5.2 网络请求优化
**问题**:如何减少不必要的网络请求
**需要讨论**
- ⚠️ 待明确:
- 请求合并:是否可以合并多个请求?
- 请求取消:切换表时是否取消之前的请求?
- 请求去重:相同请求是否去重?
**建议**ok
- 使用 AbortController 取消之前的请求
- 相同请求使用缓存,不重复请求
- 字段和索引信息可以合并为一个请求(当前已实现)
---
## 六、总结
### 优先级分类
**P0必须明确**
1. ✅ MongoDB字段统计实现方式已确定采样10个文档
2. ⚠️ 连接树右键菜单实现方式 FIXME: 做系统性全局设计, 在部分优先功能区开始设计实现,如连接区右键
3. ⚠️ 事件名称和参数格式 FIXME: 做个系统性全局设计,简洁易于扩展各种事件都简洁强大,
4. ⚠️ 结构Tab显示/隐藏逻辑
5. ⚠️ 结构数据与查询结果的冲突处理
**P1重要**
1. ⚠️ 数据缓存策略
2. ⚠️ 权限检查实现
3. ⚠️ 确认对话框设计
4. ⚠️ 错误处理和重试
**P2优化**
1. ⚠️ 加载状态优化
2. ⚠️ 空状态设计
3. ⚠️ 导出功能实现
4. ⚠️ 大数据集处理
### 建议讨论顺序
1. **首先讨论 P0 问题**:这些是核心功能,必须明确
2. **然后讨论 P1 问题**:影响用户体验,需要仔细设计
3. **最后讨论 P2 问题**:优化功能,可以后续迭代
---
**下一步**:根据讨论结果更新设计文档,明确实现细节。

View File

@@ -0,0 +1,748 @@
# 表结构查看功能设计
**设计日期**2025-01-28
**设计范围**MySQL、Redis、MongoDB 表结构查看界面设计
**状态**:设计阶段
---
## 设计概览
表结构查看功能提供统一的界面查看不同数据库类型的结构信息,支持:
- **MySQL**:表字段详情、索引信息
- **MongoDB**:文档示例、字段统计、索引信息
- **Redis**Key 类型、TTL、值预览、长度统计
**核心特性**
- 统一的对话框界面
- 根据数据库类型自动适配展示内容
- 支持 Tab 切换不同信息视图
- 表格、JSON 等多种展示方式
- 响应式设计,适配不同屏幕尺寸
---
## 一、功能概述
表结构查看功能允许用户查看不同数据库类型的结构信息:
- **MySQL**:表字段信息、索引信息
- **MongoDB**:集合文档示例、字段统计、索引信息
- **Redis**Key 类型、TTL、值预览、长度统计
---
## 二、界面设计
### 2.1 触发方式
#### 方式一:连接树右键菜单(推荐)
- 在连接树中,右键点击表/集合/Key节点
- 显示上下文菜单,包含"查看结构"选项
- 点击后在结果面板的"结构"Tab中展示
#### 方式二:连接树节点操作按钮
- 在表/集合/Key节点上悬停显示操作按钮
- 点击"结构"图标按钮,在结果面板展示
#### 方式三:双击节点
- 双击表/集合/Key节点自动切换到"结构"Tab并加载结构信息
**推荐实现方式一**,用户体验最佳。
---
### 2.2 展示位置设计
#### 在结果面板中展示
表结构信息展示在现有的 `ResultPanel` 组件中,作为第三个 Tab
```
┌─────────────────────────────────────────────────────────┐
│ 结果面板 │
├─────────────────────────────────────────────────────────┤
│ [结果] [消息] [结构] │
├─────────────────────────────────────────────────────────┤
│ [查看模式] [编辑模式] [刷新] [导出] │
├─────────────────────────────────────────────────────────┤
│ │
│ [结构 Tab 内容区域] │
│ ┌─────────┬─────────┬─────────┐ │
│ │ 字段信息 │ 索引信息 │ 其他信息 │ │
│ └─────────┴─────────┴─────────┘ │
│ │
│ │
└─────────────────────────────────────────────────────────┘
```
#### 模式切换
- **查看模式**(默认):只读展示,显示表结构信息
- **编辑模式**:可编辑模式,支持修改字段、添加/删除索引等操作
- **切换方式**:通过模式切换按钮或 Tab 切换
#### 展示区域属性
- **位置**:结果面板(`ResultPanel`)的第三个 Tab
- **Tab 标题**:根据数据库类型显示
- MySQL: `结构 - ${database}.${table}`
- MongoDB: `结构 - ${database}.${collection}`
- Redis: `结构 - ${key}`
- **高度**:跟随结果面板高度(可调整,默认 300px
- **滚动**:内容超出时自动滚动
#### 优势
- ✅ 无需弹出窗口,界面更简洁
- ✅ 与查询结果、消息在同一区域,操作连贯
- ✅ 可以同时查看结构信息和查询结果
- ✅ 符合现有架构,无需新增组件
---
### 2.3 内容展示设计
#### MySQL 表结构
**Tab 1: 字段信息**
```
┌─────────────────────────────────────────────────────────────┐
│ 字段名 │ 类型 │ 是否NULL │ 键 │ 默认值 │ 额外信息 │
├─────────────────────────────────────────────────────────────┤
│ id │ int(11) │ NO │ PRI │ NULL │ auto_inc │
│ name │ varchar(50) │ YES │ │ NULL │ │
│ email │ varchar(100)│ NO │ UNI │ NULL │ │
│ created_at│ datetime │ NO │ │ NULL │ │
└─────────────────────────────────────────────────────────────┘
```
**字段说明**
- **字段名**:列名
- **类型**数据类型int, varchar, text, datetime 等)
- **是否NULL**YES/NO
- **键**PRI主键、UNI唯一键、MUL多键
- **默认值**:默认值或 NULL
- **额外信息**auto_increment、on update 等
**Tab 2: 索引信息**
```
┌─────────────────────────────────────────────────────────────┐
│ 索引名 │ 唯一 │ 字段 │ 排序 │ 索引类型 │
├─────────────────────────────────────────────────────────────┤
│ PRIMARY │ 是 │ id │ ASC │ BTREE │
│ idx_email │ 是 │ email │ ASC │ BTREE │
│ idx_name │ 否 │ name │ ASC │ BTREE │
└─────────────────────────────────────────────────────────────┘
```
**字段说明**
- **索引名**:索引名称
- **唯一**:是/否
- **字段**:索引字段(可能有多个,用逗号分隔)
- **排序**ASC/DESC
- **索引类型**BTREE、HASH 等
---
#### MongoDB 集合结构
**Tab 1: 文档示例**
```
┌─────────────────────────────────────────────────────────────┐
│ 文档 1 │
├─────────────────────────────────────────────────────────────┤
│ { │
│ "_id": ObjectId("..."), │
│ "name": "John", │
│ "email": "john@example.com", │
│ "age": 30, │
│ "created_at": ISODate("2025-01-01T00:00:00Z") │
│ } │
└─────────────────────────────────────────────────────────────┘
[显示最多 5 个文档示例JSON 格式,可折叠展开]
```
**Tab 2: 字段统计**
```
┌─────────────────────────────────────────────────────────────┐
│ 字段名 │ 出现次数 │ 占比 │
├─────────────────────────────────────────────────────────────┤
│ _id │ 5 │ 100% (基于5个文档示例) │
│ name │ 5 │ 100% │
│ email │ 4 │ 80% │
│ age │ 3 │ 60% │
│ created_at │ 2 │ 40% │
└─────────────────────────────────────────────────────────────┘
文档总数: 1000
⚠️ 字段统计基于文档示例最多5个仅供参考
```
**性能分析与优化建议**
#### 当前实现分析
1. **字段统计**(当前实现):
- **查询方式**基于文档示例最多5个进行统计
- **性能影响**:✅ **低** - 只查询5个文档几乎无性能影响
- **准确性**:⚠️ **不准确** - 仅基于5个文档不能代表全表字段分布
- **适用场景**:快速预览,了解集合可能包含的字段
2. **文档总数**(当前实现):
- **查询方式**`CountDocuments({})` - 全表扫描
- **性能影响**:⚠️ **中等** - 大数据集(百万级+)可能较慢
- **优化建议**:使用 `estimatedDocumentCount()` 获取估算值(更快)
#### 优化方案
**方案一:保持当前实现(推荐)**
-**优点**:性能好,响应快
- ⚠️ **缺点**:字段统计不准确
- **适用**:快速预览场景,不需要精确统计
**方案二:采样统计(已确定采用)** ✅ 默认采样 10个文档
- 使用 `$sample` 聚合管道随机采样10个文档进行统计
- **性能影响**:✅ **低** - 采样10个文档性能良好
- **准确性**:✅ **适中** - 比5个文档更准确比全表扫描性能更好
- **实现方式**:使用 MongoDB `$sample` 聚合管道(已实现)
- **异步加载**:✅ 全异步执行,不阻塞主流程
- **前端展示**:✅ 显示"基于10个文档采样统计仅供参考"
- **未来扩展**支持可配置采样数量P2
**方案三:全表统计(不推荐)**
- 扫描所有文档统计字段
- **性能影响**:❌ **高** - 大数据集可能非常慢
- **适用**:小数据集(< 10万文档
#### 推荐实现
```go
// 方案一:保持当前实现(快速预览)
// 字段统计基于文档示例5个性能好但准确性低
fieldStats := make(map[string]int)
for _, doc := range sampleDocs { // 5个文档
for key := range doc {
fieldStats[key]++
}
}
// 方案二:采样统计(可选,通过参数控制)
// 如果用户需要更准确的统计,可以采样更多文档
if needAccurateStats {
pipeline := []bson.M{
{"$sample": bson.M{"size": 1000}}, // 采样1000个文档
{"$project": bson.M{"keys": bson.M{"$objectToArray": "$$ROOT"}}},
{"$unwind": "$keys"},
{"$group": bson.M{
"_id": "$keys.k",
"count": bson.M{"$sum": 1},
}},
}
// 执行聚合查询...
}
```
#### 前端展示建议
1. **明确标注**:字段统计显示"基于X个文档示例仅供参考"
2. **可选刷新**:提供"精确统计"按钮,用户需要时再执行采样统计
3. **性能提示**:大数据集时提示"精确统计可能较慢"
4. **缓存策略**字段统计结果缓存5-10分钟避免重复查询
#### 最终建议(已确定)
- **默认实现**:✅ 使用采样统计默认采样10个文档性能好准确性适中
- **文档总数**:✅ 使用 `estimatedDocumentCount()` 替代 `CountDocuments()` 提升性能
- **前端展示**:明确标注"基于10个文档采样统计仅供参考"
- **后续优化**:可考虑提供"精确统计"按钮采样更多文档100-1000个作为P2功能
**Tab 3: 索引信息**
```
┌─────────────────────────────────────────────────────────────┐
│ 索引名 │ 唯一 │ 键定义 │
├─────────────────────────────────────────────────────────────┤
│ _id_ │ 是 │ {"_id": 1} │
│ idx_email │ 是 │ {"email": 1} │
│ idx_name │ 否 │ {"name": 1, "age": -1} │
└─────────────────────────────────────────────────────────────┘
```
---
#### Redis Key 信息
**单页展示(无 Tab**
```
┌─────────────────────────────────────────────────────────────┐
│ Key 信息 │
├─────────────────────────────────────────────────────────────┤
│ Key 名称: user:1001 │
│ Key 类型: hash │
│ TTL: 3600 秒 (1 小时) │
│ 长度: 5 个字段 │
├─────────────────────────────────────────────────────────────┤
│ 值预览: │
│ { │
│ "name": "John", │
│ "email": "john@example.com", │
│ "age": "30" │
│ } │
└─────────────────────────────────────────────────────────────┘
```
**字段说明**
- **Key 名称**:完整的 Key 名称
- **Key 类型**string、hash、list、set、zset 等
- **TTL**:过期时间(秒),-1 表示永不过期,-2 表示 Key 不存在
- **长度**根据类型显示string=字符数hash/list/set/zset=元素数)
- **值预览**:限制显示前 200 字符,过长时显示省略号
---
## 三、组件设计
### 3.1 组件结构
```
ResultPanel.vue (现有组件,扩展)
└── 新增 "结构" Tab
├── StructureContent.vue (结构内容组件)
│ ├── 模式切换(查看/编辑)
│ ├── MySQLStructure.vue (MySQL 专用)
│ │ ├── ViewMode.vue (查看模式)
│ │ │ ├── FieldsTab.vue (字段信息子Tab)
│ │ │ └── IndexesTab.vue (索引信息子Tab)
│ │ └── EditMode.vue (编辑模式)
│ │ ├── FieldsEditor.vue (字段编辑表格)
│ │ ├── IndexesEditor.vue (索引编辑表格)
│ │ └── EditToolbar.vue (保存/取消按钮)
│ ├── MongoStructure.vue (MongoDB 专用)
│ │ ├── ViewMode.vue (查看模式)
│ │ │ ├── SampleDocsTab.vue (文档示例子Tab)
│ │ │ ├── FieldStatsTab.vue (字段统计子Tab)
│ │ │ └── IndexesTab.vue (索引信息子Tab)
│ │ └── EditMode.vue (编辑模式)
│ │ └── IndexesEditor.vue (索引编辑MongoDB不支持字段编辑)
│ └── RedisStructure.vue (Redis 专用,仅查看模式)
└── 状态管理(通过 composable
```
### 3.2 组件接口
#### ResultPanel.vue Props扩展
```typescript
interface Props {
// ... 现有 props
structureData?: {
connectionId: number
database: string
tableName: string
dbType: 'mysql' | 'mongo' | 'redis'
} | null // 表结构数据null 表示不显示结构Tab
}
```
#### 新增 Composable: useStructureState.ts
```typescript
export function useStructureState() {
const structureLoading = ref(false)
const structureError = ref('')
const structureData = ref<any>(null)
const structureInfo = ref<{
connectionId: number
database: string
tableName: string
dbType: 'mysql' | 'mongo' | 'redis'
} | null>(null)
// 编辑模式相关
const editMode = ref<'view' | 'edit'>('view')
const editData = ref<any>(null) // 编辑中的数据(用于撤销)
const hasChanges = ref(false) // 是否有未保存的修改
const loadStructure = async (connectionId, database, tableName, dbType) => {
// 加载表结构数据
}
const clearStructure = () => {
structureData.value = null
structureInfo.value = null
editMode.value = 'view'
editData.value = null
hasChanges.value = false
}
const switchToEditMode = () => {
// 切换到编辑模式,复制数据到 editData
editData.value = JSON.parse(JSON.stringify(structureData.value))
editMode.value = 'edit'
hasChanges.value = false
}
const switchToViewMode = () => {
// 切换到查看模式
editMode.value = 'view'
editData.value = null
hasChanges.value = false
}
const saveStructure = async () => {
// 保存结构修改,生成 ALTER TABLE 语句并执行
}
return {
structureLoading,
structureError,
structureData,
structureInfo,
editMode,
editData,
hasChanges,
loadStructure,
clearStructure,
switchToEditMode,
switchToViewMode,
saveStructure
}
}
```
---
## 四、数据流程
### 4.1 数据获取流程
```
用户触发查看结构(右键菜单/操作按钮)
ConnectionTree 触发 'table-structure' 事件
index.vue 接收事件,调用 useStructureState.loadStructure()
根据 connectionId 获取连接信息(确定 dbType
调用 GetTableStructure API
后端根据 dbType 分发:
- MySQL → GetTableStructure (DESCRIBE 查询)
- MongoDB → GetCollectionStructure (文档分析)
- Redis → GetKeyInfo (命令查询)
返回结构数据
更新 structureData 和 structureInfo
ResultPanel 检测到 structureInfo 不为空,显示"结构"Tab
StructureContent 根据 dbType 渲染对应组件
```
### 4.2 API 调用
```typescript
// 获取表结构
const result = await window.go.main.App.GetTableStructure(
connectionId,
database,
tableName
)
// 返回数据结构
// MySQL:
{
type: 'mysql',
database: 'test',
table: 'users',
columns: [...], // 字段信息数组
}
// MongoDB:
{
type: 'mongo',
database: 'test',
collection: 'users',
structure: {
sampleDocs: [...], // 文档示例
fieldStats: {...}, // 字段统计
indexes: [...], // 索引信息
documentCount: 1000 // 文档总数
}
}
// Redis:
{
type: 'redis',
key: 'user:1001',
info: {
type: 'hash',
ttl: 3600,
length: 5,
value: {...} // 值预览
}
}
```
---
## 五、实现细节
### 5.1 表格展示
#### 使用 Arco Design Table 组件
- **分页**:字段/索引较多时,使用分页(每页 20 条)
- **排序**:支持按字段名、类型等排序
- **搜索**:字段信息表格支持搜索字段名
- **固定列**:字段名列固定,方便横向滚动查看
#### 样式优化
- **字体**:使用等宽字体显示类型信息
- **颜色**主键字段用特殊颜色标识NULL 字段用灰色
- **宽度**:列宽自适应,最小宽度 100px
### 5.2 JSON 展示
#### MongoDB 文档示例、Redis 值预览
- 使用 `<pre>` 标签展示格式化的 JSON
- 支持折叠/展开(使用 `a-collapse` 组件)
- 长文本自动换行,限制最大高度,超出部分滚动
- 支持复制功能(点击复制按钮)
### 5.3 加载状态
- **加载中**:显示 Spin 组件和"加载中..."提示
- **加载失败**:显示错误提示,提供重试按钮
- **空数据**:显示空状态提示
### 5.4 响应式设计
- **小屏幕**:对话框宽度自适应,最小 600px
- **表格**:横向滚动,固定关键列
- **Tab**内容过多时Tab 可滚动
---
## 六、交互设计
### 6.1 触发查看结构
1. **从连接树触发**
- 右键菜单 → "查看结构"
- 或点击节点操作按钮
- 或双击节点
2. **参数传递**
- 从节点数据获取 `connectionId``database``tableName``dbType`
- 通过事件传递给 `index.vue`
- `index.vue` 调用 `useStructureState.loadStructure()`
3. **Tab 切换**
- 自动切换到结果面板的"结构"Tab
- 如果结果面板隐藏,自动显示
### 6.2 结构Tab操作
- **切换Tab**:点击"结构"Tab查看点击其他Tab返回
- **刷新**在结构Tab中添加刷新按钮重新加载结构数据
- **复制**:字段信息、索引信息支持复制(选中文本或复制按钮)
- **关闭**切换到其他Tab或清空结构数据
### 6.3 数据更新
- **自动加载**:触发查看结构时自动加载数据
- **手动刷新**在结构Tab中提供刷新按钮
- **错误重试**:加载失败时显示错误提示和重试按钮
- **清空数据**切换连接或执行SQL时自动清空结构数据
---
## 七、技术实现要点
### 7.1 组件拆分
- **扩展组件**`ResultPanel.vue` 添加"结构"Tab
- **内容组件**`StructureContent.vue` 负责根据 `dbType` 路由到对应组件
- **专用组件**`MySQLStructure.vue``MongoStructure.vue``RedisStructure.vue`
- **复用组件**`IndexesTab.vue` 可被 MySQL 和 MongoDB 复用(需适配数据格式)
- **状态管理**`useStructureState.ts` composable 管理结构数据状态
### 7.2 数据格式化
- **MySQL 字段类型**:保持原样显示(如 `int(11)``varchar(50)`
- **MongoDB 文档**BSON 转换为 JSON 格式显示
- **Redis 值**根据类型格式化string 直接显示hash 显示为对象)
### 7.3 性能优化
- **懒加载**结构Tab切换时才加载对应内容使用 `v-if`
- **数据缓存**:同一表结构数据缓存 5 分钟,避免重复请求
- **分页加载**:字段/索引较多时使用分页,避免一次性加载过多数据
- **按需渲染**:只有在 structureInfo 不为空时才渲染结构Tab
---
## 八、扩展功能(可选)
### 8.1 导出功能
- **导出为 SQL**MySQL 表结构导出为 CREATE TABLE 语句
- **导出为 JSON**MongoDB 集合结构导出为 JSON Schema
- **导出为文本**:所有类型支持导出为文本格式
### 8.2 编辑功能(融入查看区域)
#### 设计原则
-**融入查看区域**:编辑功能直接在结构查看 Tab 中实现,通过模式切换
-**统一界面**:查看和编辑使用相同的布局和组件,减少界面切换
-**权限检查**编辑前检查用户权限ALTER TABLE、CREATE INDEX 等)
-**操作确认**:结构修改是危险操作,需要确认对话框
#### 编辑模式设计
**模式切换**
```
┌─────────────────────────────────────────────────────────┐
│ 结构 - database.table [查看] [编辑] │
├─────────────────────────────────────────────────────────┤
│ [字段信息] [索引信息] │
├─────────────────────────────────────────────────────────┤
│ │
│ [编辑模式内容] │
│ - 可编辑表格(字段信息) │
│ - 添加字段按钮 │
│ - 删除字段按钮 │
│ - 保存/取消按钮 │
│ │
└─────────────────────────────────────────────────────────┘
```
**编辑功能**
- **MySQL**
- 修改字段类型、是否NULL、默认值、注释
- 添加字段:在指定位置添加新字段
- 删除字段:删除不需要的字段(需确认)
- 修改索引:添加/删除索引
- **MongoDB**
- 添加索引:创建新索引
- 删除索引:删除不需要的索引(需确认)
- 注意MongoDB 字段是动态的,不支持字段编辑
- **Redis**
- 不支持编辑Redis 是键值存储,无结构概念)
#### 实现方式
**方式一Tab 切换(推荐)**
- 在结构 Tab 内部使用子 Tab 切换查看/编辑模式
- 查看 Tab只读展示
- 编辑 Tab可编辑表格带保存/取消按钮
**方式二:按钮切换**
- 在结构 Tab 顶部添加"编辑"按钮
- 点击后切换到编辑模式,按钮变为"查看"
- 编辑模式下显示保存/取消按钮
**推荐使用方式一**,界面更清晰,模式切换更明显。
#### 编辑操作流程
```
用户点击"编辑"Tab/按钮
检查权限ALTER TABLE、CREATE INDEX
加载当前结构数据到编辑表格
用户修改字段/索引
点击"保存"按钮
生成 ALTER TABLE 语句
显示确认对话框(显示将要执行的 SQL
用户确认
执行 ALTER TABLE 语句
刷新结构数据
切换回查看模式
```
#### 安全措施
1. **权限检查**:编辑前检查数据库用户权限
2. **确认对话框**:显示将要执行的 SQL用户必须确认
3. **操作日志**:记录所有结构修改操作
4. **撤销功能**支持撤销最近一次修改可选P2
5. **备份提示**重要表修改前提示备份可选P2
### 8.3 对比功能
- **结构对比**:对比两个表的结构差异
- **版本历史**:记录表结构变更历史(需要额外存储)
---
## 九、实现优先级
### P0必须实现
1. ✅ 在 ResultPanel 中添加"结构"Tab
2. ✅ useStructureState composable 实现
3. ✅ MySQL 字段信息展示
4. ✅ MySQL 索引信息展示
5. ✅ MongoDB 文档示例展示
6. ✅ MongoDB 字段统计展示
7. ✅ Redis Key 信息展示
8. ✅ 连接树右键菜单触发
### P0.5(查看功能完成后实现)
1. 查看/编辑模式切换
2. MySQL 字段编辑修改类型、NULL、默认值
3. MySQL 索引编辑(添加/删除索引)
4. MongoDB 索引编辑(添加/删除索引)
5. 权限检查
6. 确认对话框
### P1重要功能
1. 数据加载状态和错误处理
2. JSON 格式化显示
3. 表格搜索和排序
4. 自动切换到结构Tab
5. 清空结构数据逻辑切换连接、执行SQL时
### P2优化功能
1. 数据缓存
2. 复制功能
3. 导出功能
4. 响应式优化
5. 编辑模式撤销/重做
6. 修改前备份提示
---
## 十、总结
表结构查看功能设计遵循以下原则:
1. **统一接口**:不同数据库类型使用相同的触发方式和展示框架
2. **差异化展示**:根据数据库类型展示对应的结构信息
3. **集成设计**:在结果面板中展示,无需弹出窗口,界面更简洁
4. **用户体验**提供清晰的表格展示、JSON 格式化、搜索排序等功能
5. **性能优化**:懒加载、数据缓存、分页等优化措施
6. **可扩展性**:组件化设计,便于后续添加新功能
### 设计优势
-**无需弹出窗口**:在结果面板中展示,界面更简洁
-**操作连贯**:与查询结果、消息在同一区域,切换方便
-**符合现有架构**:扩展 ResultPanel 组件,无需新增复杂组件
-**状态管理清晰**:使用 composable 管理结构数据,易于维护
-**查看编辑融合**:编辑功能融入查看区域,通过模式切换,无需额外界面
-**统一体验**:查看和编辑使用相同布局,降低学习成本
### 编辑功能融入优势
-**无缝切换**:查看和编辑在同一区域,切换流畅
-**上下文保持**:编辑时可以看到原始结构,便于对比
-**操作连贯**:查看 → 编辑 → 保存 → 查看,流程顺畅
-**界面简洁**:不需要额外的编辑窗口或页面
通过以上设计,可以实现一个功能完善、用户体验良好的表结构查看和编辑功能。

View File

@@ -0,0 +1,368 @@
# 事件系统设计
**设计日期**2025-01-28
**设计范围**:数据库客户端全局事件系统
**状态**:设计阶段
---
## 一、设计概述
### 1.1 设计目标
- **简洁统一**:所有组件使用统一的事件命名和参数格式
- **易于扩展**:新增事件时,遵循统一规范,易于维护
- **类型安全**:使用 TypeScript 类型定义,确保类型安全
- **功能强大**:支持事件传递、事件拦截、事件日志等高级功能
### 1.2 设计原则
1. **命名规范**:事件名称使用 kebab-case语义清晰
2. **参数统一**:事件参数使用对象格式,包含必要上下文信息
3. **类型定义**:所有事件都有明确的 TypeScript 类型定义
4. **文档完善**:每个事件都有清晰的文档说明
---
## 二、事件分类
### 2.1 连接相关事件
```typescript
// 连接选择
'connection-select': {
connection: DbConnection
database?: string // 可选,选中的数据库
}
// 连接编辑
'connection-edit': {
connectionId: number
}
// 连接删除
'connection-delete': {
connectionId: number
}
// 连接刷新
'connection-refresh': {
connectionId?: number // 可选,不提供则刷新所有
}
```
### 2.2 表结构相关事件
```typescript
// 查看表结构
'table-structure': {
connectionId: number
database: string
tableName: string // 表名/集合名/Key名
dbType: 'mysql' | 'mongo' | 'redis'
nodeType: 'table' | 'collection' | 'key' | 'database' | 'connection'
}
// 表选择生成SQL
'table-select': {
connectionId: number
database: string
tableName: string
sql?: string // 可选预生成的SQL
}
```
### 2.3 SQL执行相关事件
```typescript
// SQL执行
'sql-execute': {
sql: string
connectionId: number
database?: string
}
// SQL执行完成
'sql-execute-complete': {
result: SqlResult
error?: string
}
```
### 2.4 编辑器相关事件
```typescript
// SQL插入
'sql-insert': {
sql: string
tabKey?: string // 可选指定Tab
}
// Tab切换
'tab-switch': {
tabKey: string
}
// Tab关闭
'tab-close': {
tabKey: string
}
```
---
## 三、事件系统架构
### 3.1 事件总线设计
```typescript
// 事件总线接口
interface EventBus {
// 注册事件监听器
on<T = any>(event: string, handler: (data: T) => void): () => void
// 注册一次性事件监听器
once<T = any>(event: string, handler: (data: T) => void): void
// 移除事件监听器
off(event: string, handler?: Function): void
// 触发事件
emit<T = any>(event: string, data: T): void
// 清除所有监听器
clear(): void
}
// 全局事件总线实例
export const eventBus = createEventBus()
```
### 3.2 组件事件映射
```typescript
// ConnectionTree 组件事件
interface ConnectionTreeEvents {
'connection-select': { connection: DbConnection; database?: string }
'connection-edit': { connectionId: number }
'connection-delete': { connectionId: number }
'table-select': { connectionId: number; database: string; tableName: string }
'table-structure': {
connectionId: number
database: string
tableName: string
dbType: 'mysql' | 'mongo' | 'redis'
nodeType: string
}
'new-connection': void
'show-bookmarks': void
'show-templates': void
}
// SqlEditor 组件事件
interface SqlEditorEvents {
'execute': { sql: string }
'execute-selected': { sql: string }
'sql-insert': { sql: string; tabKey?: string }
'tab-switch': { tabKey: string }
'tab-close': { tabKey: string }
'toggle-editor': void
}
```
---
## 四、事件命名规范
### 4.1 命名规则
- **格式**`<组件>-<动作>``<功能>-<动作>`
- **示例**
- `connection-select`:连接选择
- `table-structure`:表结构查看
- `sql-execute`SQL执行
### 4.2 动作词汇表
| 动作 | 说明 | 示例 |
|------|------|------|
| select | 选择 | `connection-select` |
| edit | 编辑 | `connection-edit` |
| delete | 删除 | `connection-delete` |
| create | 创建 | `tab-create` |
| close | 关闭 | `tab-close` |
| switch | 切换 | `tab-switch` |
| execute | 执行 | `sql-execute` |
| insert | 插入 | `sql-insert` |
| refresh | 刷新 | `connection-refresh` |
---
## 五、事件参数设计
### 5.1 参数原则
1. **对象格式**:所有事件参数使用对象,不使用多个参数
2. **必要信息**:包含事件处理所需的所有上下文信息
3. **可选字段**:使用可选字段(`?`)标记非必需信息
4. **类型明确**:所有字段都有明确的类型定义
### 5.2 参数示例
```typescript
// ✅ 好的设计:对象格式,类型明确
emit('table-structure', {
connectionId: 1,
database: 'test',
tableName: 'users',
dbType: 'mysql',
nodeType: 'table'
})
// ❌ 不好的设计:多个参数,类型不明确
emit('table-structure', 1, 'test', 'users', 'mysql', 'table')
```
---
## 六、事件处理流程
### 6.1 事件触发流程
```
组件内触发事件
emit('event-name', data)
父组件监听事件
调用处理函数
更新状态/执行操作
```
### 6.2 事件拦截机制(可选)
```typescript
// 事件拦截器接口
interface EventInterceptor {
beforeEmit?: (event: string, data: any) => boolean // 返回false阻止事件
afterEmit?: (event: string, data: any) => void // 事件触发后执行
}
// 注册拦截器
eventBus.addInterceptor(interceptor)
```
---
## 七、实现细节
### 7.1 事件类型定义
```typescript
// 事件类型定义文件types/events.ts
export interface ConnectionSelectEvent {
connection: DbConnection
database?: string
}
export interface TableStructureEvent {
connectionId: number
database: string
tableName: string
dbType: 'mysql' | 'mongo' | 'redis'
nodeType: 'table' | 'collection' | 'key' | 'database' | 'connection'
}
// ... 其他事件类型
```
### 7.2 组件事件声明
```typescript
// ConnectionTree.vue
const emit = defineEmits<{
'connection-select': [data: ConnectionSelectEvent]
'table-structure': [data: TableStructureEvent]
'table-select': [data: TableSelectEvent]
// ... 其他事件
}>()
```
### 7.3 事件处理
```typescript
// index.vue
const handleTableStructure = (data: TableStructureEvent) => {
// 加载表结构
structureState.loadStructure(
data.connectionId,
data.database,
data.tableName,
data.dbType
)
// 切换到结构Tab
resultTab.value = 'structure'
}
```
---
## 八、扩展性设计
### 8.1 事件日志(开发模式)
```typescript
// 开发模式下记录所有事件
if (import.meta.env.DEV) {
eventBus.on('*', (event, data) => {
console.log(`[Event] ${event}`, data)
})
}
```
### 8.2 事件统计(可选)
```typescript
// 统计事件触发次数
const eventStats = new Map<string, number>()
eventBus.on('*', (event) => {
eventStats.set(event, (eventStats.get(event) || 0) + 1)
})
```
---
## 九、实现优先级
### P0必须实现
1. ✅ 事件类型定义TypeScript
2. ✅ 连接相关事件
3. ✅ 表结构相关事件
4. ✅ SQL执行相关事件
### P1重要功能
1. 事件参数验证
2. 事件文档完善
3. 事件处理错误处理
### P2优化功能
1. 事件拦截机制
2. 事件日志(开发模式)
3. 事件统计
---
## 十、总结
事件系统设计遵循以下原则:
1. **简洁统一**:统一的事件命名和参数格式
2. **类型安全**:完整的 TypeScript 类型定义
3. **易于扩展**:清晰的事件分类和命名规范
4. **功能强大**:支持事件拦截、日志等高级功能
通过以上设计,可以实现一个简洁、强大、易扩展的事件系统。

View File

@@ -0,0 +1,312 @@
# 数据库客户端前端架构设计文档
**文档版本**v2.0
**维护者**JueChen
**更新日期**2025-01-28
**源码路径**`go-desk/web/src/views/db-cli/`
---
## 一、整体架构概览
### 1.1 分层架构
```
┌─────────────────────────────────────────────────────────────┐
│ 视图层Views
│ ┌──────────────────────────────────────────────────────┐ │
│ │ index.vue (主页面 - 布局和协调) │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 组件层Components
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ConnectionTree│ │ SqlEditor │ │ ResultPanel │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ConnectionForm│ │ResourceManager│ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 组合式函数层Composables
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │useDbConnection│ │useSqlExecution│ │useEditorState│ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │useResultState │ │useMessageLog │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ API 层Wails Bridge
│ ┌──────────────────────────────────────────────────────┐ │
│ │ window.go.main.App.* │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### 1.2 架构设计原则
1. **单一职责原则**:每个组件和 composable 只负责一个功能领域
2. **关注点分离**:视图、逻辑、状态分离
3. **可复用性**:通过 composables 抽取可复用逻辑
4. **可维护性**:清晰的目录结构和命名规范
5. **可测试性**composables 可以独立测试
---
## 二、目录结构
```
db-cli/
├── index.vue # 主页面(布局和协调)
├── components/ # 组件目录
│ ├── ConnectionTree.vue # 连接树组件
│ ├── ConnectionForm.vue # 连接表单组件
│ ├── SqlEditor.vue # SQL编辑器组件
│ ├── ResultPanel.vue # 结果展示组件
│ ├── ResourceManager.vue # 资源管理组件
│ └── ~~BookmarkManager.vue~~ # ❌ 已删除(书签功能已删除)
│ └── ~~TemplateManager.vue~~ # ❌ 已删除(模板功能已删除)
└── composables/ # 组合式函数目录
├── useDbConnection.ts # 连接管理逻辑
├── useSqlExecution.ts # SQL执行逻辑
├── useEditorState.ts # 编辑器状态管理
├── useResultState.ts # 结果状态管理
└── useMessageLog.ts # 消息日志管理
```
---
## 三、Composables 设计
### 3.1 useDbConnection.ts
**职责**:管理数据库连接相关的状态和逻辑
**状态**
- `currentConnection`: 当前选中的连接
- `selectedDatabase`: 当前选中的数据库MySQL
- `showConnectionForm`: 连接表单显示状态
- `editingConnectionId`: 正在编辑的连接ID
**方法**
- `selectConnection(conn, database)`: 选择连接
- `editConnection(connectionId)`: 编辑连接
- `deleteConnection(connectionId)`: 删除连接
- `newConnection()`: 新建连接
- `onConnectionSuccess()`: 连接操作成功回调
### 3.2 useSqlExecution.ts
**职责**管理SQL执行相关的逻辑
**方法**
- `executeSQL(sql, connection, database)`: 执行SQL
- `handleQueryResult(result)`: 处理查询结果
- `handleUpdateResult(result)`: 处理更新结果
- `handleCommandResult(result)`: 处理命令结果Redis
### 3.3 useEditorState.ts
**职责**:管理编辑器显示/隐藏状态
**状态**
- `editorVisible`: 编辑器是否可见
**方法**
- `toggleEditor()`: 切换编辑器显示/隐藏
- `loadEditorVisible()`: 从localStorage加载状态
- `saveEditorVisible()`: 保存状态到localStorage
### 3.4 useResultState.ts
**职责**:管理执行结果相关的状态
**状态**
- `resultLoading`: 加载状态
- `resultError`: 错误信息
- `resultData`: 结果数据
- `resultMode`: 展示模式table/json
- `resultStats`: 执行统计
- `resultColumns`: 表格列定义
**方法**
- `clearResults()`: 清空结果
- `setQueryResult(data, stats)`: 设置查询结果
- `setUpdateResult(stats)`: 设置更新结果
- `setCommandResult(data, stats)`: 设置命令结果
- `setError(error)`: 设置错误
### 3.5 useMessageLog.ts
**职责**:管理消息日志
**状态**
- `messages`: 消息列表
**方法**
- `addMessage(type, content)`: 添加消息
- `clearMessages()`: 清空消息
- `getMessages(limit)`: 获取消息(带限制)
---
## 四、组件通信设计
### 4.1 Props 向下传递
```
index.vue
├─ ConnectionTree
│ └─ currentConnectionId (prop)
├─ SqlEditor
│ └─ currentConnection (prop)
└─ ResultPanel
├─ loading (prop)
├─ error (prop)
├─ data (prop)
├─ mode (prop)
├─ stats (prop)
├─ columns (prop)
└─ messages (prop)
```
### 4.2 Events 向上传递
```
ConnectionTree
├─ @connection-select → index.vue
├─ @connection-edit → index.vue
├─ @connection-delete → index.vue
├─ @table-select → index.vue
├─ @new-connection → index.vue
└─ ~~@show-bookmarks, @show-templates~~ ❌ 已删除(功能已删除)
SqlEditor
├─ @execute → index.vue
├─ @execute-selected → index.vue
└─ @toggle-editor → index.vue
ResultPanel
└─ @toggle-editor → index.vue
```
### 4.3 Provide/Inject可选
对于深层嵌套的组件,可以使用 provide/inject
```typescript
// index.vue
provide('dbCliContext', {
currentConnection,
selectedDatabase,
executeSQL,
addMessage
})
// 深层组件
const { currentConnection, executeSQL } = inject('dbCliContext')
```
---
## 五、状态管理流程
### 5.1 连接选择流程
```
用户点击连接
→ ConnectionTree 触发 @connection-select
→ index.vue 调用 useDbConnection.selectConnection()
→ 更新 currentConnection 和 selectedDatabase
→ 清空结果useResultState.clearResults()
→ 添加消息useMessageLog.addMessage()
→ SqlEditor 接收新的 currentConnection prop
```
### 5.2 SQL执行流程
```
用户执行SQL
→ SqlEditor 触发 @execute
→ index.vue 调用 useSqlExecution.executeSQL()
→ 调用 window.go.main.App.ExecuteSQL()
→ 根据结果类型调用对应的处理方法
→ useResultState 更新结果状态
→ ResultPanel 接收新的 props 并展示
```
---
## 六、重构优势
### 6.1 代码组织
- **清晰的职责划分**:每个 composable 负责一个功能领域
- **易于维护**:修改某个功能只需修改对应的 composable
- **代码复用**composables 可以在其他页面复用
### 6.2 可测试性
- **独立测试**:每个 composable 可以独立测试
- **Mock 简单**:可以轻松 mock window.go API
- **测试覆盖**:逻辑集中在 composables测试更容易
### 6.3 可扩展性
- **新增功能**:只需添加新的 composable
- **功能组合**:可以组合多个 composables 实现复杂功能
- **向后兼容**:不影响现有组件结构
---
## 七、实施步骤
### 步骤1创建 composables 目录结构 ✅
- [x] 创建 `composables/` 目录
- [x] 创建 `useDbConnection.ts`
- [x] 创建 `useSqlExecution.ts`
- [x] 创建 `useEditorState.ts`
- [x] 创建 `useResultState.ts`
- [x] 创建 `useMessageLog.ts`
### 步骤2重构主页面 ✅
- [x] 将状态管理逻辑迁移到 composables
- [x] 将业务逻辑迁移到 composables
- [x] 简化 index.vue只保留布局和协调逻辑
### 步骤3优化组件通信 ✅
- [x] 评估是否需要使用 provide/inject当前不需要
- [x] 优化 props 传递
- [x] 优化事件处理
### 步骤4测试和验证 ⚠️
- [x] 功能测试(基本完成)
- [ ] 性能测试(待完成)
- [x] 代码审查(已完成)
---
## 八、后续优化方向
1. **状态管理库**:如果状态管理变得复杂,可以考虑引入 Pinia
2. **类型安全**:为 composables 添加完整的 TypeScript 类型定义
3. **错误处理**:统一错误处理机制
4. **性能优化**:使用 computed 和 watch 优化响应式更新
5. **单元测试**:为 composables 编写单元测试
---
## 九、参考文档
- [Vue 3 Composition API](https://vuejs.org/guide/extras/composition-api-faq.html)
- [Vue 3 Provide/Inject](https://vuejs.org/guide/components/provide-inject.html)
- [组件拆分方案](./组件拆分方案.md)

View File

@@ -0,0 +1,340 @@
# 右键菜单系统设计
**设计日期**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<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. **简洁强大**:菜单项精简但功能完整
通过以上设计,可以实现一个统一、易用、易扩展的右键菜单系统。

View File

@@ -0,0 +1,287 @@
# 数据库客户端后端架构设计文档
**文档版本**v2.0
**维护者**JueChen
**更新日期**2025-01-28
**源码路径**`go-desk/`
---
## 一、整体架构概览
### 1.1 分层架构
```
┌─────────────────────────────────────────────────────────────┐
│ 接口层API Layer
│ ┌──────────────────────────────────────────────────────┐ │
│ │ app.go (Wails App 接口) │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 服务层Service Layer
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ConnectionSvc │ │ SqlExecSvc │ │ ResourceSvc │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ TabSvc │ │ BookmarkSvc │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 数据访问层Data Access Layer
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Storage │ │ DBClient │ │ Models │ │
│ │ (SQLite) │ │ (Pool) │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 基础设施层Infrastructure Layer
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Crypto │ │ Filesystem │ │ System │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### 1.2 架构设计原则
1. **单一职责原则**:每个服务只负责一个业务领域
2. **依赖倒置原则**:接口定义在服务层,实现在数据访问层
3. **关注点分离**:接口、业务逻辑、数据访问分离
4. **可测试性**:通过接口抽象,便于单元测试
5. **可扩展性**:新增功能只需添加新的服务
---
## 二、目录结构
```
go-desk/
├── main.go # 应用入口
├── app.go # Wails App 接口(精简后)
├── internal/
│ ├── api/ # API 接口层(新增)
│ │ ├── connection_api.go # 连接管理接口
│ │ ├── sql_api.go # SQL执行接口
│ │ ├── resource_api.go # 资源管理接口
│ │ └── tab_api.go # 标签页接口
│ │
│ ├── service/ # 服务层(新增)
│ │ ├── connection_service.go # 连接管理服务
│ │ ├── sql_exec_service.go # SQL执行服务
│ │ ├── resource_service.go # 资源管理服务
│ │ └── tab_service.go # 标签页服务
│ │
│ ├── storage/ # 数据访问层
│ │ ├── sqlite.go # SQLite 初始化
│ │ ├── models/ # 数据模型
│ │ │ ├── connection.go
│ │ │ ├── sql_tab.go
│ │ │ ├── bookmark.go
│ │ │ └── template.go
│ │ └── repository/ # 数据仓库(新增)
│ │ ├── connection_repo.go
│ │ ├── tab_repo.go
│ │ ├── bookmark_repo.go
│ │ └── template_repo.go
│ │
│ ├── dbclient/ # 数据库客户端
│ │ ├── pool.go # 连接池管理
│ │ ├── mysql.go # MySQL 客户端
│ │ ├── redis.go # Redis 客户端
│ │ └── mongo.go # MongoDB 客户端
│ │
│ ├── crypto/ # 加密工具
│ ├── filesystem/ # 文件系统
│ └── system/ # 系统信息
```
---
## 三、服务层设计
### 3.1 ConnectionService
**职责**:管理数据库连接配置
**方法**
- `SaveConnection(conn *models.DbConnection) error`
- `ListConnections() ([]models.DbConnection, error)`
- `GetConnection(id uint) (*models.DbConnection, error)`
- `DeleteConnection(id uint) error`
- `TestConnection(conn *models.DbConnection) error`
**依赖**
- `ConnectionRepository`:数据访问接口
### 3.2 SqlExecService
**职责**:执行 SQL 语句
**方法**
- `ExecuteSQL(connectionId uint, sqlStr string, database string) (*SqlResult, error)`
- `GetDatabases(connectionId uint) ([]string, error)`
- `GetTables(connectionId uint, database string) ([]string, error)`
**依赖**
- `ConnectionService`:获取连接配置
- `ConnectionPool`:获取数据库客户端
### 3.3 ResourceService
**职责**:管理书签和模板
**方法**
- `SaveBookmark(bookmark *models.Bookmark) error`
- `ListBookmarks(connectionId uint) ([]models.Bookmark, error)`
- `DeleteBookmark(id uint) error`
- `SaveTemplate(template *models.Template) error`
- `ListTemplates() ([]models.Template, error)`
- `DeleteTemplate(id uint) error`
**依赖**
- `BookmarkRepository`:书签数据访问
- `TemplateRepository`:模板数据访问
### 3.4 TabService
**职责**:管理 SQL 标签页
**方法**
- `SaveTabs(tabs []models.SqlTab) error`
- `ListTabs() ([]models.SqlTab, error)`
- `DeleteTab(id uint) error`
**依赖**
- `TabRepository`:标签页数据访问
---
## 四、数据访问层设计
### 4.1 Repository 模式
使用 Repository 模式封装数据访问逻辑,提供统一的接口:
```go
type ConnectionRepository interface {
Save(conn *models.DbConnection) error
FindAll() ([]models.DbConnection, error)
FindByID(id uint) (*models.DbConnection, error)
Delete(id uint) error
}
```
### 4.2 实现方式
- `ConnectionRepository`:使用 GORM 实现
- `TabRepository`:使用 GORM 实现
- `BookmarkRepository`:使用 GORM 实现
- `TemplateRepository`:使用 GORM 实现
---
## 五、接口层设计
### 5.1 API 接口
`app.go` 中的方法按功能分组到不同的 API 文件中:
- `connection_api.go`:连接管理相关接口
- `sql_api.go`SQL 执行相关接口
- `resource_api.go`:资源管理相关接口
- `tab_api.go`:标签页相关接口
### 5.2 App 结构体
`app.go` 只负责:
- 初始化服务
- 委托调用到对应的 API 接口
---
## 六、重构优势
### 6.1 代码组织
- **清晰的职责划分**:每个服务只负责一个业务领域
- **易于维护**:修改某个功能只需修改对应的服务
- **代码复用**:服务可以在多个 API 中复用
### 6.2 可测试性
- **独立测试**:每个服务可以独立测试
- **Mock 简单**:可以轻松 mock Repository
- **测试覆盖**:逻辑集中在服务层,测试更容易
### 6.3 可扩展性
- **新增功能**:只需添加新的服务和 API
- **功能组合**:可以组合多个服务实现复杂功能
- **向后兼容**:不影响现有接口
---
## 七、实施步骤
### 步骤1创建目录结构 ✅
- [x] 创建 `internal/api/` 目录
- [x] 创建 `internal/service/` 目录
- [x] 创建 `internal/storage/repository/` 目录
### 步骤2实现 Repository 层 ✅
- [x] 定义 Repository 接口
- [x] 实现 ConnectionRepository
- [x] 实现 TabRepository
- [x] 实现 BookmarkRepository
- [x] 实现 TemplateRepository
### 步骤3实现 Service 层 ✅
- [x] 实现 ConnectionService
- [x] 实现 SqlExecService
- [x] 实现 ResourceService
- [x] 实现 TabService
### 步骤4实现 API 层 ✅
- [x] 实现 connection_api.go
- [x] 实现 sql_api.go
- [x] 实现 resource_api.go
- [x] 实现 tab_api.go
### 步骤5重构 app.go ✅
- [x] 连接管理方法迁移到 ConnectionAPI ✅
- [x] SQL执行方法迁移到 SqlAPI ✅
- [x] 书签管理方法迁移到 ResourceAPI ✅
- [x] 模板管理方法迁移到 ResourceAPI ✅
- [x] 标签页管理方法迁移到 TabAPI ✅
- [x] 表结构和索引查询方法迁移到 SqlAPI ✅
- [x] 删除重复代码parseRedisCommand
- [x] 简化 app.go只保留初始化逻辑 ✅
### 步骤6测试和验证 ⚠️
- [x] 功能测试(基本完成)
- [ ] 单元测试(待完成)
- [x] 代码审查(已完成)
---
## 八、后续优化方向
1. **依赖注入**:使用依赖注入框架管理服务依赖
2. **错误处理**:统一错误处理机制
3. **日志系统**:引入结构化日志
4. **配置管理**:统一配置管理
5. **中间件**:添加认证、限流等中间件
---
## 九、参考文档
- [Go 项目布局标准](https://github.com/golang-standards/project-layout)
- [Clean Architecture in Go](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)

View File

@@ -0,0 +1,429 @@
# 数据库类型功能差异分析
**分析日期**2025-01-28
**分析范围**MySQL、Redis、MongoDB 功能支持差异
---
## 一、功能支持对比表
| 功能模块 | MySQL | Redis | MongoDB | 说明 |
|---------|-------|-------|---------|------|
| **连接管理** |
| 连接配置 | ✅ | ✅ | ✅ | 都支持主机、端口、用户名、密码MySQL默认端口3306/用户rootRedis默认端口6379/DB0MongoDB默认端口27017/用户admin |
| 数据库选择 | ✅ | ✅ | ✅ | MySQL/MongoDB=数据库名Redis=DB编号(0-15)连接树中Redis显示为"DB 0"、"DB 1"等,支持切换 |
| 连接测试 | ✅ | ✅ | ✅ | 都支持连接测试 |
| **SQL/命令执行** |
| 查询执行 | ✅ | ✅ | ✅ | MySQL=SELECTRedis=GET等MongoDB=find |
| 更新执行 | ✅ | ✅ | ✅ | MySQL=INSERT/UPDATE/DELETERedis=SET等MongoDB=insert/update |
| 结果类型 | query/update | command | query/update | MySQL区分查询/更新Redis统一为command |
| 执行超时 | 30秒 | 30秒 | 30秒 | 统一超时时间 |
| **数据库列表** |
| 获取数据库列表 | ✅ | ⚠️ | ✅ | Redis返回0-15MySQL/MongoDB动态查询 |
| 数据库切换 | ✅ | ✅ | ✅ | 都支持切换数据库 |
| **表/集合/Key列表** |
| 获取表列表 | ✅ | ✅ | ✅ | MySQL=表Redis=KeyMongoDB=集合 |
| 懒加载 | ✅ | ✅ | ✅ | 都支持懒加载 |
| 模式匹配 | ❌ | ✅ | ❌ | Redis支持Key模式匹配 |
| **表结构查询** |
| 表结构查询 | ✅ | ✅ | ✅ | MySQL=列信息Redis=Key信息MongoDB=集合结构 |
| 列信息 | ✅ | ❌ | ⚠️ | MySQL显示列详情MongoDB显示字段统计 |
| 索引信息 | ✅ | ❌ | ✅ | MySQL/MongoDB支持Redis不支持 |
| 文档示例 | ❌ | ❌ | ✅ | 仅MongoDB显示文档示例 |
| **索引查询** |
| 索引列表 | ✅ | ❌ | ⚠️ | MySQL独立查询MongoDB包含在集合结构中 |
| 索引详情 | ✅ | ❌ | ✅ | MySQL/MongoDB显示索引详情 |
| **编辑器支持** |
| 语法高亮 | SQL | JavaScript | JavaScript | MySQL使用SQLRedis/MongoDB使用JS |
| 默认内容 | `select 1;` | `GET key\nSET key value` | `db.collection.find({})` | 根据类型自动设置 |
| 执行按钮文本 | "执行" | "执行命令" | "执行查询" | 根据类型自动设置 |
| **结果展示** |
| 表格展示 | ✅ | ⚠️ | ⚠️ | MySQL适合表格Redis/MongoDB适合JSON |
| JSON展示 | ⚠️ | ✅ | ✅ | Redis/MongoDB命令结果用JSON展示 |
| 统计信息 | ✅ | ✅ | ✅ | 都显示执行时间和影响行数 |
| **数据存储** |
| SQL编辑器内容关联 | ✅ | ✅ | ✅ | 都支持SQL编辑器内容关联连接ID |
| ~~标签页关联~~ | ⚠️ | ⚠️ | ⚠️ | ~~暂时移除多Tab支持仅保留一个编辑区~~ |
| ~~书签支持~~ | ❌ | ❌ | ❌ | ~~功能已删除~~ |
| ~~模板支持~~ | ❌ | ❌ | ❌ | ~~功能已删除~~ |
**图例**
- ✅ 完全支持
- ⚠️ 部分支持或需要特殊处理
- ❌ 不支持
---
## 快速对比摘要
### 核心差异
| 维度 | MySQL | Redis | MongoDB |
|------|-------|-------|---------|
| **执行方式** | SQL语句 | 命令字符串 | JSON格式命令 |
| **数据结构** | 关系型表格 | 键值对 | 文档型JSON |
| **数据库概念** | 逻辑数据库 | DB编号(0-15) | 逻辑数据库 |
| **查询方式** | SQL查询 | 命令查询 | JSON命令 |
| **结果格式** | 表格数据 | 命令返回值 | 文档数组 |
| **语法高亮** | SQL | JavaScript | JavaScript |
| **结果展示** | 表格为主 | JSON为主 | JSON为主 |
### 功能完整性
- **MySQL**:⭐⭐⭐⭐⭐ (100%) - 功能最完整
- **Redis**:⭐⭐⭐⭐☆ (90%) - 核心功能完整索引不支持Redis特性
- **MongoDB**:⭐⭐⭐⭐☆ (85%) - 核心功能完整需要JSON格式待优化
---
## 二、详细功能差异分析
### 2.1 连接管理差异
#### MySQL
- **连接参数**:主机、端口、用户名、密码、数据库名
- **数据库选择**:通过数据库名选择,支持切换
- **连接方式**TCP连接支持SSL待实现
- **连接池**:支持连接复用
#### Redis
- **连接参数**主机、端口、密码、DB编号0-15
- **数据库选择**通过DB编号选择0-15共16个数据库
- **连接方式**TCP连接
- **连接池**:支持连接复用
- **特殊说明**database字段存储DB编号字符串格式
#### MongoDB
- **连接参数**:主机、端口、用户名、密码、数据库名(认证数据库)
- **数据库选择**:通过数据库名选择,支持切换
- **连接方式**TCP连接支持认证
- **连接池**:支持连接复用
- **特殊说明**数据库名可作为认证数据库authSource
---
### 2.2 SQL/命令执行差异
#### MySQL
- **执行方式**标准SQL语句
- **语句类型**
- 查询SELECT、SHOW、DESCRIBE、DESC、EXPLAIN
- 更新INSERT、UPDATE、DELETE、CREATE、ALTER、DROP等
- **结果类型**
- `query`:查询结果,返回数据数组
- `update`:更新结果,返回影响行数
- **数据库参数**:支持指定数据库执行(覆盖连接配置)
- **多语句支持**支持多条SQL语句multiStatements
#### Redis
- **执行方式**Redis命令字符串解析
- **命令格式**`命令名 参数1 参数2 ...`(支持引号)
- **命令类型**所有Redis命令GET、SET、HGET、HSET、DEL等
- **结果类型**
- `command`:统一为命令结果,返回命令返回值
- **数据库参数**不支持使用连接配置的DB编号
- **命令解析**:支持带引号的参数(单引号/双引号)
#### MongoDB
- **执行方式**JSON格式命令当前实现
- **命令格式**JSON对象包含 `op`(操作类型)和操作参数
- **语句类型**
- 查询:`{"op": "find", "collection": "users", "filter": {}}`
- 更新:`{"op": "insertOne", "collection": "users", "document": {}}`
- **结果类型**
- `command`:统一为命令结果,根据操作类型确定影响行数
- **数据库参数**:支持指定数据库执行(覆盖连接配置)
- **特殊说明**当前使用JSON格式前端编辑器显示JavaScript语法MongoDB Shell风格但实际执行需要转换为JSON格式
---
### 2.3 数据库列表差异
#### MySQL
- **获取方式**`SHOW DATABASES`
- **返回结果**:数据库名称数组
- **动态查询**:实时查询服务器上的数据库
- **权限控制**:根据用户权限显示可见数据库
#### Redis
- **获取方式**固定返回0-15
- **返回结果**`["0", "1", "2", ..., "15"]`
- **特殊说明**Redis有16个逻辑数据库编号0-15
- **实现方式**:不查询服务器,直接返回固定列表
#### MongoDB
- **获取方式**`client.ListDatabases()`
- **返回结果**:数据库名称数组
- **动态查询**:实时查询服务器上的数据库
- **权限控制**:根据用户权限显示可见数据库
---
### 2.4 表/集合/Key列表差异
#### MySQL
- **获取方式**`SHOW TABLES`
- **返回结果**:表名数组
- **数据库参数**:必须指定数据库
- **懒加载**:展开数据库节点时加载
#### Redis
- **获取方式**`KEYS *` 或模式匹配
- **返回结果**Key名数组
- **数据库参数**使用连接配置的DB编号
- **模式匹配**:支持 `KEYS pattern`(如 `KEYS user:*`
- **性能注意**大量Key时可能较慢
#### MongoDB
- **获取方式**`db.ListCollectionNames()`
- **返回结果**:集合名数组
- **数据库参数**:必须指定数据库
- **懒加载**:展开数据库节点时加载
---
### 2.5 表结构查询差异
#### MySQL
- **获取方式**`DESCRIBE table_name``SHOW COLUMNS FROM table_name`
- **返回内容**
- 字段名Field
- 类型Type
- 是否为空Null
- 键信息Key
- 默认值Default
- 额外信息Extra
- **数据格式**:结构化列信息数组
#### Redis
- **获取方式**`TYPE key``TTL key``MEMORY USAGE key`
- **返回内容**
- Key类型string、hash、list、set、zset等
- TTL过期时间
- 值大小(内存占用)
- **数据格式**Key信息对象
#### MongoDB
- **获取方式**`db.collection.find().limit(5)` + 统计信息
- **返回内容**
- 文档示例最多5个
- 字段统计信息
- 索引信息(索引名、唯一性、键定义)
- 文档总数
- **数据格式**:集合结构对象(包含多个子对象)
---
### 2.6 索引查询差异
#### MySQL
- **获取方式**`SHOW INDEX FROM table_name`
- **返回内容**
- 索引名Key_name
- 列名Column_name
- 唯一性Non_unique
- 索引类型Index_type
- 排序方式Collation
- **数据格式**:索引信息数组
#### Redis
- **支持情况**:❌ 不支持索引
- **返回结果**:空数组 `[]`
- **说明**Redis是键值存储没有索引概念
#### MongoDB
- **获取方式**:包含在集合结构中(`GetCollectionStructure`
- **返回内容**
- 索引名
- 唯一性
- 键定义(字段和排序方向)
- **数据格式**:索引信息数组(从集合结构中提取)
- **特殊说明**:不提供独立的索引查询接口,索引信息包含在表结构查询中
---
### 2.7 编辑器支持差异
#### MySQL
- **语言模式**SQL语法高亮
- **默认内容**`select 1;`
- **执行按钮**`执行`
- **语法特性**标准SQL语法支持多语句
#### Redis
- **语言模式**JavaScript语法高亮用于命令编辑
- **默认内容**
```
GET key
SET key value
HGET hash field
```
- **执行按钮**`执行命令`
- **语法特性**:命令格式,支持引号参数
#### MongoDB
- **语言模式**JavaScript语法高亮MongoDB Shell语法用于编辑
- **默认内容**
```
db.collection.find({})
// 示例db.users.find({name: "John"})
```
- **执行按钮**`执行查询`
- **语法特性**编辑器显示MongoDB Shell语法但实际执行需要转换为JSON格式待实现自动转换
- **当前限制**需要手动输入JSON格式命令不支持直接执行Shell语法
---
### 2.8 结果展示差异
#### MySQL
- **展示模式**:主要使用表格模式
- **数据格式**:二维数组(行×列)
- **列定义**:自动从查询结果生成
- **统计信息**:行数、执行时间
- **JSON模式**:可选,用于特殊查询结果
#### Redis
- **展示模式**主要使用JSON模式
- **数据格式**:命令返回值(可能是字符串、数字、数组等)
- **统计信息**执行时间RowsAffected固定为1
- **表格模式**不适用Redis结果不是表格结构
#### MongoDB
- **展示模式**JSON模式为主表格模式可选
- **数据格式**文档数组BSON转换为JSON
- **列定义**:查询结果为空时无列定义
- **统计信息**:文档数、执行时间
- **表格模式**:适用于简单查询结果
---
## 三、实现差异总结
### 3.1 核心差异点
1. **执行方式**
- MySQL标准SQL语句
- Redis命令字符串解析
- MongoDBJavaScript代码执行待完善
2. **数据库概念**
- MySQL逻辑数据库包含表
- Redis逻辑数据库0-15包含Key
- MongoDB逻辑数据库包含集合
3. **数据结构**
- MySQL关系型表格结构
- Redis键值对无固定结构
- MongoDB文档型JSON结构
4. **查询方式**
- MySQLSQL查询
- Redis命令查询
- MongoDB查询表达式
5. **结果格式**
- MySQL表格数据
- Redis命令返回值
- MongoDB文档数组
### 3.2 统一处理策略
1. **结果类型统一**
- MySQL`query`/`update`
- Redis`command`
- MongoDB`query`/`update`
2. **展示模式统一**
- 表格模式适用于MySQL查询结果
- JSON模式适用于Redis命令结果和MongoDB查询结果
3. **编辑器统一**
- 根据数据库类型自动切换语言模式
- 自动设置默认内容和按钮文本
4. **API接口统一**
- 所有数据库类型使用相同的API接口
- 内部根据类型分发到不同的实现
---
## 四、功能完整性评估
### 4.1 MySQL功能完整性⭐⭐⭐⭐⭐ (100%)
- ✅ 所有核心功能已实现
- ✅ 查询、更新、表结构、索引查询完整
- ✅ 编辑器支持完善
### 4.2 Redis功能完整性⭐⭐⭐⭐☆ (90%)
- ✅ 核心功能已实现
- ⚠️ 索引查询不支持Redis本身不支持
- ✅ 命令执行、Key列表、Key信息查询完整
### 4.3 MongoDB功能完整性⭐⭐⭐⭐☆ (85%)
- ✅ 核心功能已实现
- ⚠️ 查询执行需要JSON格式不支持直接执行Shell语法
- ✅ 集合列表、集合结构查询完整
- ⚠️ 索引查询包含在集合结构中(非独立接口)
- ⚠️ 需要实现Shell语法到JSON的自动转换
---
## 五、优化建议
### 5.1 短期优化
1. **MongoDB查询执行优化**(高优先级)
- 当前需要JSON格式用户体验不佳
- 建议实现MongoDB Shell语法到JSON的自动转换
- 方案1集成JavaScript引擎如goja解析Shell语法
- 方案2实现简单的语法解析器支持常用操作
2. **Redis命令补全**
- 添加Redis命令自动补全功能
- 建议在编辑器中集成Redis命令提示
3. **MongoDB查询补全**
- 添加MongoDB Shell语法补全
- 建议在编辑器中集成MongoDB方法提示
### 5.2 长期优化
1. **统一查询接口**
- 考虑设计统一的查询语言或抽象层
- 当前各数据库使用不同的执行方式
2. **结果格式标准化**
- 进一步统一结果格式,便于前端处理
- 当前已有统一的结果类型,但数据格式仍有差异
3. **性能优化**
- Redis Key列表查询大量Key时
- MongoDB集合结构查询大量文档时
---
## 六、总结
### 6.1 功能支持情况
- **MySQL**:功能最完整,所有功能都已实现
- **Redis**核心功能完整索引查询不支持Redis特性
- **MongoDB**:核心功能完整,查询执行待完善
### 6.2 差异处理策略
- **统一接口**所有数据库类型使用相同的API接口
- **类型分发**:内部根据数据库类型分发到不同实现
- **结果统一**:统一结果类型和展示模式
- **编辑器适配**:根据数据库类型自动适配编辑器
### 6.3 后续工作
1. 完善MongoDB查询执行功能
2. 优化Redis大量Key查询性能
3. 添加命令/语法补全功能
4. 统一结果格式处理
---
**结论**不同数据库类型的功能差异主要体现在执行方式、数据结构、查询方式等方面但通过统一的接口设计和类型分发实现了良好的功能支持。MySQL功能最完整Redis和MongoDB核心功能已实现部分功能待完善。

View File

@@ -0,0 +1,106 @@
# 数据库客户端需求
基于 go-desk 实现数据库连接客户端工具,简单易用,易用性超过 dbeaver。
## 支持数据库
- 当前支持MySQL、Redis、MongoDB
- 计划支持Oracle、ES、ClickHouse、PostgreSQL、SQLite
## **升级-优化-Bug**
```
--- 以下内容AI只可读取不要修改人工维护 ---
FIXME: 当前考虑重要(一定会尝试,提前预留或推进)
1、增加功能区左侧功能区分上下两部分下面增加一个 效果参考数据库连接的效果 ,把 历史的sql编辑器书签sql 模板列表 都放到这个地方;
2、当前最小化 mvp 需要做到 能用好用, 现在还有诸多bug ,使用不便利, 这个我们还要逐一整理出来, 也可以通过网络获取一个最小化版本的数据库客户端用户最关心的核心点,然后有针对性的迭代改进
3、精细控制文档内容 不要 随性创建过多过量低质量文档,这样根本不利于阅读维护,
4、实现我们的 go-desk 升级更新 方便后续做迭代分发,
FIXME: 当前考虑预留,但是不要破环当前主要的设计,破环性太大就不要做实质性的编码预留,未来可能会走的方向
1、为未来service-client 部署做预留扩展希望做最少的代码逻辑精准实现本地桌面与远端机器的联动类似于bs->bcs混合版本
2、文本编辑区支持不止 sql 一种类型文本内容默认sql其他支持 txthtmljs/tscssmd 的语法高亮编辑及高效的结果渲染预览
3、模板文件 支持加密本密码本概念,存储的 content 需要做加密存储,必须输入作者密钥才可解密数据
FIXME: 优化及 BUG 修复:
全局:
1、sql编辑区与结果区支持调整动态拖拽调整比例
2、未看到右键菜单
sql编辑区(文本编辑区):
1、第二个sql编辑区的 输入框未正常展示,添加后不能输入内容
2、sql 编辑区高度当内容超过区域能展示范围的时候, 没有滚动条导致不能展示出其他超出的内容,
3、编辑区所选择的数据库连接及database, 选中后下次加载默认选中,
4、选中数据连接或database 的时候 sql编辑区 不用整个区域刷新,现在看到 sql输入框也 reload这个不必要
5、表结构区点击表的时候 未展示
--- 以上内容AI只可读取不要修改人工维护 ---
```
## 页面布局
1. **数据库列表视图区域**:左侧,树形结构展示连接、数据库、表
2. **执行语句编辑区域**中间SQL编辑器暂时只保留一个编辑区
3. **结果展示区域**:底部,结果表格/JSON + 消息日志
## 数据库连接区
- **连接列表**:树形结构,按类型分组,懒加载数据库/表列表,显示连接状态和类型图标
- **连接管理**:新建/编辑/删除连接支持MySQL/Redis/MongoDB密码加密存储测试连接
- **快捷功能**~~书签管理入口、SQL模板入口~~(已删除)
- **数据存储**SQLite存储密码AES加密自动加载
## SQL编辑器
- **编辑器功能**SQL/JS语法高亮根据数据库类型行号自动换行F5执行完整Ctrl+Enter执行选中
- **内容自动存储**SQLite存储内容自动保存防抖1秒关联连接ID
- **执行功能**:执行前检查连接,结果在结果区域显示
- **工具栏**:执行按钮、执行选中按钮、折叠/展开按钮,显示当前连接信息
- **界面布局**:编辑器占据主要空间,支持折叠/展开
- ⚠️ **多Tab支持**暂时移除仅保留一个SQL编辑区
## 结果区域
- **结果tab**:表格/JSON展示显示统计信息行数、执行时间自动生成列定义
- **消息tab**记录执行事件SQL、时间、结果消息类型info/success/error/warning最多保留100条
- **区域控制**:支持折叠/展开编辑器结果区域高度可调200-600px编辑器隐藏时结果区域全屏
## ~~书签管理~~ ❌ 已删除
- **状态**:功能已删除
## ~~SQL模板管理~~ ❌ 已删除
- **状态**:功能已删除
## 表结构查询
- **MySQL**显示列信息字段名、类型、是否为空、默认值、注释通过DESCRIBE获取
- **MongoDB**:显示文档示例、字段统计、索引信息、文档总数
- **Redis**显示Key类型、TTL、值大小等信息
- **查询方式**:点击连接树节点(待实现界面展示)
## 索引查询
- **MySQL**显示索引信息索引名、列名、唯一性、类型通过SHOW INDEX获取
- **MongoDB**:索引信息包含在集合结构中
- **Redis**:不支持索引
- **查询方式**通过API接口查询待实现界面展示
## 多数据库类型支持
- **MySQL**SQL执行SELECT/INSERT/UPDATE/DELETE/DDL数据库/表列表,表结构,索引查询
- **Redis**命令执行GET/SET/HGET/HSET等Key列表模式匹配Key信息TYPE/TTL/SIZE数据库选择0-15
- **MongoDB**查询执行find/aggregate数据库/集合列表,集合结构(文档示例、字段统计、索引)
- **类型识别**根据连接类型自动切换编辑器语言MySQL=SQL高亮Redis/MongoDB=JS高亮自动设置默认内容和按钮文本
## 数据存储
- **SQLite存储**连接配置加密密码、SQL编辑器内容~~书签数据、模板数据~~(已删除),自动迁移表结构
- **数据加密**连接密码AES加密存储解密后用于连接测试和执行
- **数据持久化**连接配置立即生效SQL编辑器内容防抖保存1秒编辑器显示状态保存到localStorage
## 快捷键
- **编辑器**F5执行完整Ctrl+Enter执行选中CodeMirror默认快捷键
- **界面**:折叠/展开编辑器
## 待实现功能
1. SQL格式化
2. 代码补全(表名、列名、关键字提示)
3. 多Tab支持暂时移除后续版本恢复
4. 数据导出CSV/SQL/JSON
5. 消息历史清空
6. 表结构界面展示
7. 索引界面展示
8. 右键菜单(连接树节点)
9. 智能SQL接入大模型
10. 文件/SQL文件管理导入/导出)