重构:文件系统模块化架构,优化应用启动流程
This commit is contained in:
368
docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/事件系统设计.md
Normal file
368
docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/事件系统设计.md
Normal 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. **功能强大**:支持事件拦截、日志等高级功能
|
||||
|
||||
通过以上设计,可以实现一个简洁、强大、易扩展的事件系统。
|
||||
|
||||
312
docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/前端架构设计.md
Normal file
312
docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/前端架构设计.md
Normal 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)
|
||||
|
||||
340
docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/右键菜单系统设计.md
Normal file
340
docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/右键菜单系统设计.md
Normal 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. **简洁强大**:菜单项精简但功能完整
|
||||
|
||||
通过以上设计,可以实现一个统一、易用、易扩展的右键菜单系统。
|
||||
|
||||
287
docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/后端架构设计.md
Normal file
287
docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/后端架构设计.md
Normal 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)
|
||||
|
||||
Reference in New Issue
Block a user