这是一个基于 Wails + Arco-Vue 的最小 Demo
+{{ message }}
+{{ structure.info.value }}
+ ` 标签展示格式化的 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 管理结构数据,易于维护
+- ✅ **查看编辑融合**:编辑功能融入查看区域,通过模式切换,无需额外界面
+- ✅ **统一体验**:查看和编辑使用相同布局,降低学习成本
+
+### 编辑功能融入优势
+
+- ✅ **无缝切换**:查看和编辑在同一区域,切换流畅
+- ✅ **上下文保持**:编辑时可以看到原始结构,便于对比
+- ✅ **操作连贯**:查看 → 编辑 → 保存 → 查看,流程顺畅
+- ✅ **界面简洁**:不需要额外的编辑窗口或页面
+
+通过以上设计,可以实现一个功能完善、用户体验良好的表结构查看和编辑功能。
+
diff --git a/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/事件系统设计.md b/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/事件系统设计.md
new file mode 100644
index 0000000..43805b9
--- /dev/null
+++ b/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/事件系统设计.md
@@ -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(event: string, handler: (data: T) => void): () => void
+
+ // 注册一次性事件监听器
+ once(event: string, handler: (data: T) => void): void
+
+ // 移除事件监听器
+ off(event: string, handler?: Function): void
+
+ // 触发事件
+ emit(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()
+
+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. **功能强大**:支持事件拦截、日志等高级功能
+
+通过以上设计,可以实现一个简洁、强大、易扩展的事件系统。
+
diff --git a/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/前端架构设计.md b/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/前端架构设计.md
new file mode 100644
index 0000000..385a354
--- /dev/null
+++ b/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/前端架构设计.md
@@ -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)
+
diff --git a/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/右键菜单系统设计.md b/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/右键菜单系统设计.md
new file mode 100644
index 0000000..b70c6fc
--- /dev/null
+++ b/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/右键菜单系统设计.md
@@ -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
+}
+
+// 事件映射表
+const eventHandlers: Record = {
+ 'view-structure': (nodeData) => {
+ // 触发查看结构事件
+ emit('table-structure', {
+ connectionId: nodeData.connectionId,
+ database: nodeData.database,
+ tableName: nodeData.tableName || nodeData.title,
+ dbType: nodeData.dbType,
+ nodeType: nodeData.type
+ })
+ },
+ 'edit': (nodeData) => {
+ emit('connection-edit', nodeData.connectionId)
+ },
+ 'delete': (nodeData) => {
+ emit('connection-delete', nodeData.connectionId)
+ },
+ 'generate-sql': (nodeData) => {
+ // 生成SQL语句
+ const sql = generateSQL(nodeData)
+ emit('table-select', { ...nodeData, sql })
+ },
+ 'copy-name': (nodeData) => {
+ // 复制名称到剪贴板
+ copyToClipboard(nodeData.tableName || nodeData.title)
+ },
+ 'refresh': (nodeData) => {
+ // 刷新节点数据
+ refreshNode(nodeData)
+ }
+}
+```
+
+---
+
+## 四、实现细节
+
+### 4.1 菜单显示位置
+
+- **定位方式**:使用鼠标事件坐标定位
+- **边界处理**:菜单超出视口时自动调整位置
+- **层级管理**:使用 z-index 确保菜单在最上层
+
+### 4.2 菜单交互
+
+- **点击外部关闭**:点击菜单外部区域自动关闭
+- **ESC键关闭**:按ESC键关闭菜单
+- **键盘导航**:支持方向键导航菜单项(可选,P2)
+
+### 4.3 菜单样式
+
+- **使用 Arco Design Dropdown**:保持与系统风格一致
+- **图标支持**:菜单项支持图标显示
+- **禁用状态**:禁用项显示为灰色,不可点击
+- **分隔线**:使用分隔线区分功能组
+
+---
+
+## 五、扩展性设计
+
+### 5.1 插件化菜单项
+
+```typescript
+// 菜单项插件接口
+interface MenuItemPlugin {
+ name: string
+ condition: (nodeData: TreeNodeData) => boolean // 显示条件
+ getMenuItem: (nodeData: TreeNodeData) => MenuItem // 生成菜单项
+ handler: (nodeData: TreeNodeData) => void // 处理函数
+}
+
+// 注册插件
+function registerMenuItemPlugin(plugin: MenuItemPlugin) {
+ // 注册逻辑
+}
+```
+
+### 5.2 动态菜单项
+
+- **权限控制**:根据用户权限动态显示/隐藏菜单项
+- **上下文感知**:根据当前状态动态调整菜单项
+- **条件显示**:某些菜单项只在特定条件下显示
+
+---
+
+## 六、实现优先级
+
+### P0(必须实现)
+1. ✅ 连接节点右键菜单(查看结构、编辑、删除、刷新)
+2. ✅ 数据库节点右键菜单(查看结构、生成SQL、刷新)
+3. ✅ 表节点右键菜单(查看结构、生成SQL、复制表名、刷新)
+4. ✅ Key节点右键菜单(查看结构、生成命令、复制Key名、刷新)
+
+### P1(重要功能)
+1. 菜单定位和边界处理
+2. 菜单项图标支持
+3. 复制功能实现
+
+### P2(优化功能)
+1. 键盘导航支持
+2. 菜单项插件化
+3. 权限控制
+
+---
+
+## 七、总结
+
+右键菜单系统设计遵循以下原则:
+
+1. **统一设计**:所有区域的右键菜单使用统一的设计和交互
+2. **易于扩展**:通过配置和插件机制,易于添加新功能
+3. **上下文感知**:根据节点类型和状态,显示相关菜单项
+4. **简洁强大**:菜单项精简但功能完整
+
+通过以上设计,可以实现一个统一、易用、易扩展的右键菜单系统。
+
diff --git a/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/后端架构设计.md b/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/后端架构设计.md
new file mode 100644
index 0000000..44c3a8b
--- /dev/null
+++ b/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/架构设计/后端架构设计.md
@@ -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)
+
diff --git a/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/需求设计/前端布局样式系统设计.md b/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/需求设计/前端布局样式系统设计.md
new file mode 100644
index 0000000..3d87321
--- /dev/null
+++ b/docs/04-功能迭代/GO-DESK-2.数据库客户端/设计文档/需求设计/前端布局样式系统设计.md
@@ -0,0 +1,1285 @@
+# 前端布局样式系统设计
+
+**创建日期**:2026-01-01
+**最后更新**:2025-01-09
+**目标**:建立系统化的前端布局和样式规范,确保一致性和可维护性
+**原则**:统一规范、可扩展、易维护、主题兼容
+**状态**:✅ 已完成 Arco Design 规范优化
+
+---
+
+## 📋 快速导航
+
+- [一、设计目标](#一设计目标)
+- [二、布局系统](#二布局系统)
+ - [2.1 Arco Design Layout 组件使用规范](#21-arco-design-layout-组件使用规范)
+ - [2.2 整体布局结构](#22-整体布局结构)
+ - [2.3 布局层次](#23-布局层次)
+- [三、样式系统](#三样式系统)
+- [十二、Arco Design 规范对照总结](#十二arco-design-规范对照总结)
+- [优化总结](#优化总结)
+
+---
+
+---
+
+## 一、设计目标
+
+### 核心目标
+- **一致性**:统一的布局和样式规范
+- **可维护性**:清晰的样式组织结构
+- **可扩展性**:支持主题切换、响应式布局、功能扩展
+- **性能**:优化样式性能,减少重复代码
+
+### 设计原则
+- 使用 Arco Design 基础样式(优先使用样式变量)
+- 避免硬编码样式(使用 CSS 变量和设计令牌)
+- 组件化样式(每个组件管理自己的样式)
+- 响应式优先(支持不同屏幕尺寸)
+
+---
+
+## 二、布局系统
+
+### 2.1 Arco Design Layout 组件使用规范
+
+#### 2.1.1 Arco Layout 组件结构
+
+Arco Design 提供了以下 Layout 组件:
+- `a-layout`: 布局容器
+- `a-layout-header`: 顶部导航栏
+- `a-layout-sider`: 侧边栏
+- `a-layout-content`: 内容区域
+- `a-layout-footer`: 底部栏
+
+#### 2.1.2 我们的实现方式
+
+**顶层布局(App.vue)** - ✅ 符合 Arco 规范
+```vue
+
+ 顶部导航
+ 内容区域
+
+```
+
+**数据库客户端布局(db-cli/index.vue)** - ✅ 已优化为使用 Arco Layout 组件
+```vue
+
+ 侧边栏
+
+ 编辑器
+ 结果
+
+
+```
+
+**优化说明**:
+- ✅ 使用嵌套的 `a-layout` 替代自定义 `div.main-content`
+- ✅ 使用 `a-layout-content` 作为编辑器和结果区域
+- ✅ 完全符合 Arco Design 规范
+- ✅ 保持了原有的灵活性和功能(拖拽调整、百分比高度等)
+
+### 2.2 整体布局结构
+
+```
+┌─────────────────────────────────────────────────────────┐
+│ db-cli-layout (Arco Layout, 100vh) │
+│ ┌──────────────┐ ┌─────────────────────────────────┐ │
+│ │ sidebar │ │ main-content (flex:1) │ │
+│ │ (280px) │ │ ┌───────────────────────────┐ │ │
+│ │ │ │ │ editor-area │ │ │
+│ │ sidebar- │ │ │ (height: %, 可隐藏) │ │ │
+│ │ container │ │ │ └─ SqlEditor │ │ │
+│ │ │ │ └───────────────────────────┘ │ │
+│ │ Connection- │ │ ┌───────────────────────────┐ │ │
+│ │ Tree │ │ │ editor-result-divider (4px)│ │ │
+│ └──────────────┘ │ └───────────────────────────┘ │ │
+│ │ ┌───────────────────────────┐ │ │
+│ │ │ result-area (flex:1) │ │ │
+│ │ │ └─ ResultPanel │ │ │
+│ │ │ └─ Tabs │ │ │
+│ │ │ ├─ result │ │ │
+│ │ │ ├─ messages │ │ │
+│ │ │ ├─ structure │ │ │
+│ │ │ ├─ history │ │ │
+│ │ │ └─ create │ │ │
+│ │ └───────────────────────────┘ │ │
+│ └─────────────────────────────────┘ │
+└─────────────────────────────────────────────────────────┘
+```
+
+### 2.3 布局层次
+
+| 层级 | 元素 | Arco 组件 | 类型 | 说明 |
+|------|------|-----------|------|------|
+| **顶层(App.vue)** |||||
+| 0 | layout | `a-layout` | Arco Layout | 应用主容器(100vh,垂直 Flex) |
+| 0.1 | header | `a-layout-header` | Arco Header | 顶部导航栏(固定高度) |
+| 0.2 | content | `a-layout-content` | Arco Content | 主内容区域(flex:1,可滚动) |
+| **数据库客户端(db-cli/index.vue)** |||||
+| 1 | db-cli-layout | `a-layout` | Arco Layout | 数据库客户端容器(100%,水平 Flex) |
+| 2 | sidebar | `a-layout-sider` | Arco Sider | 侧边栏(280px,flex-shrink: 0) |
+| 2.1 | sidebar-container | - | 自定义 div | 侧边栏容器(100%高度,Flex 列) |
+| 3 | main-layout | `a-layout` | Arco Layout | 主布局容器(flex:1,垂直 Flex)✅ 已优化 |
+| 4 | editor-area | `a-layout-content` | Arco Content | 编辑器区域(百分比高度,可隐藏)✅ 已优化 |
+| 4.1 | editor-result-divider | - | 自定义 div | 分隔条(4px,可调整大小) |
+| 5 | result-area | `a-layout-content` | Arco Content | 结果区域(flex:1,min-height: 150px)✅ 已优化 |
+| 5.1 | result-panel-wrapper | - | 自定义 div | 结果面板容器(Flex 列) |
+| 5.2 | result-tabs | `a-tabs` | Arco Tabs | Tabs 容器(flex:1) |
+| 5.3 | tab-content | - | 自定义 div | 各 Tab 内容区域(height:100%) |
+
+**Arco 组件使用情况**(已优化):
+- ✅ 使用了 `a-layout` 作为容器
+- ✅ 使用了 `a-layout-sider` 作为侧边栏
+- ✅ 使用嵌套 `a-layout` 作为主内容区容器 ✅ **已优化**
+- ✅ 使用 `a-layout-content` 作为编辑器和结果区域 ✅ **已优化**
+- ✅ 使用了 `a-tabs` 作为结果面板的标签页
+
+### 2.4 Arco Layout 组件的样式特性
+
+#### 2.4.1 Arco Layout 默认样式
+
+Arco Design 的 Layout 组件具有以下默认样式特性:
+
+```css
+/* a-layout */
+.arco-layout {
+ display: flex;
+ flex: auto;
+ flex-direction: column;
+ box-sizing: border-box;
+}
+
+/* a-layout-header / a-layout-footer */
+.arco-layout-header,
+.arco-layout-footer {
+ flex: 0 0 auto;
+}
+
+/* a-layout-sider */
+.arco-layout-sider {
+ position: relative;
+ min-width: 0;
+ transition: all 0.2s;
+}
+
+/* a-layout-content */
+.arco-layout-content {
+ flex: auto;
+}
+```
+
+#### 2.4.2 我们的样式覆盖
+
+我们为 `db-cli-layout` 覆盖了部分样式,使其适配水平布局:
+
+```css
+.db-cli-layout {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: row; /* 覆盖默认的 column,改为水平布局 */
+ overflow: hidden;
+}
+
+.sidebar {
+ flex-shrink: 0;
+ width: 280px;
+ /* Arco 的 a-layout-sider 会应用默认样式,我们通过 class 覆盖特定样式 */
+}
+```
+
+**注意事项**:
+- `a-layout` 默认是垂直 Flex(`flex-direction: column`),我们在 `.db-cli-layout` 中覆盖为水平(`row`)
+- `a-layout-sider` 的宽度通过 `:width="280"` prop 设置,符合 Arco 规范 ✅
+- ✅ **已优化**:使用嵌套 `a-layout` 和 `a-layout-content` 替代自定义 `div.main-content`
+- ✅ **已优化**:所有样式使用 Arco 设计令牌,简化写法
+
+### 2.5 布局样式规范
+
+#### 主布局容器
+```css
+.db-cli-layout {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ overflow: hidden;
+}
+
+.sidebar {
+ flex-shrink: 0;
+ width: 280px;
+ border-right: 1px solid var(--color-border-2); /* ✅ 已优化:简化边框写法 */
+ overflow: hidden;
+}
+
+.sidebar-container {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+}
+
+/* 主布局容器 - 使用 Arco Layout */
+.main-layout {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ min-width: 0;
+}
+```
+
+#### 编辑器区域 - 使用 Arco Layout Content
+```css
+.editor-area {
+ flex-shrink: 0;
+ min-height: 150px;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ position: relative;
+ padding: 0; /* 移除 Arco Layout Content 的默认 padding */
+ /* 高度通过 :style="{ height: editorAreaHeight + '%' }" 动态设置 */
+}
+
+.editor-result-divider {
+ flex-shrink: 0;
+ height: 4px;
+ background: var(--color-border-2);
+ cursor: row-resize;
+ position: relative;
+ transition: background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1); /* 使用 Arco 过渡函数 */
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.editor-result-divider:hover {
+ background: var(--color-border-3);
+}
+
+.editor-result-divider.collapsed {
+ cursor: pointer;
+ height: 6px;
+}
+```
+
+#### 分隔条按钮 - 使用 Arco 设计令牌
+```css
+.divider-toggle-btn {
+ position: absolute;
+ z-index: 10;
+ background: var(--color-bg-1);
+ border: 1px solid var(--color-border-2);
+ border-radius: var(--border-radius-small, 2px); /* 使用 Arco 圆角变量 */
+ box-shadow: var(--shadow-1-down, 0 2px 4px rgba(0, 0, 0, 0.06)); /* 使用 Arco 阴影变量 */
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+ padding: 0;
+ min-width: 30px;
+ height: 15px;
+}
+
+.divider-toggle-btn:hover {
+ background: var(--color-bg-2);
+ border-color: var(--color-primary-light-2);
+ box-shadow: var(--shadow-2-down, 0 4px 8px rgba(0, 0, 0, 0.1));
+ transform: translateY(-1px);
+}
+```
+
+#### 结果区域 - 使用 Arco Layout Content
+```css
+.result-area {
+ flex: 1;
+ min-height: 150px;
+ display: flex;
+ flex-direction: column;
+ border-top: 1px solid var(--color-border-2); /* 简化边框样式 */
+ overflow: hidden;
+ position: relative;
+ height: 100%;
+ padding: 0; /* 移除 Arco Layout Content 的默认 padding */
+}
+
+.result-panel-wrapper {
+ height: 100%;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ min-height: 0;
+}
+```
+
+### 2.6 Arco Tabs 组件使用规范
+
+#### 2.6.1 Arco Tabs 组件结构
+
+Arco Design 的 Tabs 组件结构:
+```
+arco-tabs
+├── arco-tabs-header (标签头部,flex-shrink: 0)
+│ └── arco-tabs-nav
+│ └── arco-tabs-tab (各个标签页)
+└── arco-tabs-content (标签内容区域,flex: 1)
+ └── arco-tabs-content-list
+ └── arco-tabs-content-item (各个内容项)
+```
+
+#### 2.6.2 我们的实现方式
+
+```vue
+
+ ...
+ ...
+
+
+```
+
+**使用规范核对**:
+- ✅ 使用 `v-model:active-key` 控制激活标签 - 符合 Arco 规范
+- ✅ 使用 `type="line"` 设置标签样式 - 符合 Arco 规范
+- ✅ 使用 `a-tab-pane` 定义各个标签页 - 符合 Arco 规范
+- ✅ 使用 `key` 和 `title` 属性 - 符合 Arco 规范
+
+#### 2.6.3 Tabs 内容区域布局
+
+#### Arco Tabs 深度样式设置
+
+**Arco Tabs 默认样式特性**:
+- `arco-tabs`: 默认 `display: flex; flex-direction: column`
+- `arco-tabs-header`: 默认 `flex-shrink: 0`(固定高度)
+- `arco-tabs-content`: 默认 `flex: 1`(占据剩余空间)
+
+**我们的样式覆盖**(确保高度计算正确):
+```css
+.result-tabs {
+ flex: 1;
+ min-height: 0;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+}
+
+/* 确保 arco-tabs 容器高度正确 */
+.result-tabs :deep(.arco-tabs) {
+ height: 100%; /* ✅ 关键:设置高度为 100% */
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+}
+
+/* 内容区域占据剩余空间 */
+.result-tabs :deep(.arco-tabs-content) {
+ flex: 1; /* ✅ 符合 Arco 默认样式 */
+ min-height: 0; /* ✅ 关键:允许收缩 */
+ overflow: hidden;
+}
+
+/* 内容列表高度设置 */
+.result-tabs :deep(.arco-tabs-content-list) {
+ height: 100%; /* ✅ 关键:确保列表高度正确 */
+}
+
+/* 各个内容项高度设置 */
+.result-tabs :deep(.arco-tabs-content-item) {
+ height: 100%; /* ✅ 关键:每个内容项高度 100% */
+ display: flex; /* ✅ 添加 Flex 布局支持 */
+ flex-direction: column;
+ overflow: hidden;
+}
+```
+
+**关键点**:
+1. ✅ `arco-tabs-content` 使用 `flex: 1` - 符合 Arco 默认样式
+2. ✅ `arco-tabs-content-item` 使用 `height: 100%` - 确保内容项高度正确
+3. ✅ 添加 `min-height: 0` - 允许 Flex 子元素正确收缩
+4. ✅ 使用 `:deep()` 深度选择器覆盖 Arco 内部样式 - Vue 3 标准做法
+
+#### Tab Content 通用样式
+所有 Tab 内容都遵循相同的布局模式:
+```css
+.tab-content {
+ height: 100%; /* 使用 height: 100% 而非 flex: 1 */
+ display: flex;
+ flex-direction: column;
+ padding: var(--spacing-md, 12px);
+ overflow: hidden;
+ min-height: 0;
+}
+```
+
+#### 具体 Tab 内容结构
+
+**结果 Tab (result-content)**
+```
+result-content (height: 100%)
+├── result-loading / result-empty (flex: 1, 居中)
+└── result-data-wrapper (flex: 1, overflow: hidden)
+ ├── result-stats (flex-shrink: 0)
+ └── result-table-container / result-json-container (flex: 1)
+```
+
+**消息 Tab (messages-content)**
+```
+messages-content (height: 100%)
+└── messages-list (flex: 1, overflow-y: auto)
+ ├── message-item (列表项)
+ └── messages-empty (flex: 1, 居中)
+```
+
+**结构 Tab (structure-content)**
+```
+structure-content (height: 100%)
+└── structure-data (flex: 1, overflow-y: auto)
+ └── structure-section
+ ├── structure-section-header (flex-shrink: 0)
+ └── structure-table-container (flex: 1)
+```
+
+**历史 Tab (history-content)**
+```
+history-content (height: 100%)
+├── history-toolbar (flex-shrink: 0)
+├── history-loading / history-empty (flex: 1, 居中)
+└── history-timeline-wrapper (flex: 1, overflow: hidden)
+ ├── history-timeline (flex: 1, overflow-y: auto)
+ └── history-pagination-wrapper (flex-shrink: 0)
+```
+
+**创建 Tab (create-content)**
+```
+create-content (height: 100%)
+└── create-content > div (flex: 1)
+ ├── MySQLCreate / 其他组件
+ └── create-actions (flex-shrink: 0)
+```
+
+---
+
+## 三、样式系统
+
+### 3.1 设计令牌(Design Tokens)- Arco Design 标准
+
+#### 间距系统 ✅ 已统一使用
+```css
+/* Arco Design 间距变量(优先使用) */
+--spacing-xs: 4px;
+--spacing-sm: 8px;
+--spacing-md: 12px;
+--spacing-lg: 16px;
+--spacing-xl: 20px;
+--spacing-xxl: 24px;
+```
+
+**使用规范**:
+- ✅ 所有 padding 和 margin 都应使用这些变量
+- ✅ 避免硬编码数值(如 `padding: 8px` → `padding: var(--spacing-sm, 8px)`)
+
+#### 颜色系统 ✅ 已统一使用
+```css
+/* 边框颜色 */
+--color-border-1, --color-border-2, --color-border-3, --color-border-4
+
+/* 背景颜色 */
+--color-bg-1, --color-bg-2, --color-bg-3, --color-bg-4
+
+/* 文本颜色 */
+--color-text-1, --color-text-2, --color-text-3, --color-text-4
+
+/* 主题色 */
+--color-primary, --color-primary-light-1 到 light-5
+```
+
+**使用规范**:
+- ✅ 简化边框写法:`1px solid var(--color-border-2)`(已优化)
+- ✅ 避免使用 `var(--color-border-2, var(--color-border))` 这种多层 fallback
+- ✅ 主题色使用 `--color-primary-light-*` 系列
+
+#### 字体系统 ✅ 已统一使用
+```css
+/* Arco Design 字体大小变量 */
+--font-size-xs: 12px;
+--font-size-sm: 13px; /* 注意:不是 14px */
+--font-size-md: 14px;
+--font-size-lg: 16px;
+
+/* 字体族 */
+--font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, ...;
+--font-family-mono: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
+```
+
+**使用规范**:
+- ✅ 所有文本大小使用这些变量
+- ✅ 代码/等宽字体使用 `--font-family-mono`
+
+#### 边框系统 ✅ 已统一使用
+```css
+/* 圆角 */
+--border-radius-small: 2px;
+--border-radius-medium: 4px;
+--border-radius-large: 6px;
+
+/* 边框 */
+border: 1px solid var(--color-border-2); /* ✅ 简化写法 */
+```
+
+**使用规范**:
+- ✅ 使用 `--border-radius-small`, `--border-radius-medium`, `--border-radius-large`
+- ✅ 边框统一使用 `1px solid var(--color-border-2)` 简化写法
+
+#### 阴影系统 ✅ 已统一使用
+```css
+/* Arco Design 阴影变量 */
+--shadow-1-down: 0 2px 4px rgba(0, 0, 0, 0.06);
+--shadow-2-down: 0 4px 8px rgba(0, 0, 0, 0.1);
+--shadow-3-down: 0 8px 16px rgba(0, 0, 0, 0.12);
+```
+
+**使用规范**:
+- ✅ 使用 Arco 阴影变量替代硬编码 `rgba()`
+- ✅ hover 状态使用 `--shadow-2-down`,默认使用 `--shadow-1-down`
+
+#### 过渡函数 ✅ 已统一使用
+```css
+/* Arco Design 标准过渡函数 */
+transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+
+/* 或者更精确地指定属性 */
+transition: border-color 0.2s cubic-bezier(0.4, 0, 0.2, 1),
+ box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+```
+
+**使用规范**:
+- ✅ 所有过渡动画使用 `cubic-bezier(0.4, 0, 0.2, 1)`
+- ✅ 过渡时间统一使用 `0.2s`
+
+### 3.2 Flex 布局规范
+
+#### Flex 容器基础规范
+```css
+.flex-container {
+ display: flex;
+ overflow: hidden;
+ min-width: 0; /* 关键:允许 flex 子元素收缩 */
+ min-height: 0; /* 关键:允许 flex 子元素收缩 */
+}
+```
+
+#### 高度计算关键点
+
+**1. Flex 容器中的高度计算**
+- 使用 `height: 100%` 而非 `flex: 1` 作为子元素高度设置
+- 必须设置 `min-height: 0` 允许 flex 子元素正确收缩
+- 滚动容器应该使用 `overflow-y: auto` 而非 `overflow: hidden`
+
+**2. Arco Tabs 内容区域高度设置**
+```css
+/* Arco Tabs 内容项必须使用 height: 100% */
+.arco-tabs-content-item {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+}
+
+/* Tab Content 使用 height: 100% 而非 flex: 1 */
+.tab-content {
+ height: 100%; /* ✅ 正确 */
+ /* flex: 1; ❌ 错误,会导致高度计算不准确 */
+}
+```
+
+**3. 滚动容器的正确设置**
+```css
+/* 滚动容器应该设置在内容区域,而非外层容器 */
+.scroll-container {
+ flex: 1;
+ overflow-y: auto; /* 滚动设置在内容层 */
+ overflow-x: hidden;
+ min-height: 0; /* 必须设置 */
+}
+
+/* 外层容器隐藏溢出 */
+.outer-container {
+ overflow: hidden; /* 外层隐藏溢出 */
+ min-height: 0;
+}
+```
+
+### 3.3 组件样式规范(BEM 命名)
+
+```css
+.component-wrapper { }
+.component-header { }
+.component-content { }
+.component-item--active { }
+.component-item--disabled { }
+```
+
+**样式组织顺序**:容器样式 → 布局样式 → 功能样式 → 状态样式 → 深度选择器
+
+---
+
+## 四、响应式设计
+
+### 4.1 断点定义
+```css
+--breakpoint-xs: 480px; --breakpoint-sm: 768px; --breakpoint-md: 992px;
+--breakpoint-lg: 1200px; --breakpoint-xl: 1600px;
+```
+
+### 4.2 响应式策略
+
+| 屏幕尺寸 | 策略 |
+|---------|------|
+| < 768px | 侧边栏折叠/隐藏,编辑器/结果区域垂直堆叠 |
+| 768px - 1200px | 保持当前布局,适当调整比例 |
+| > 1200px | 保持当前布局,可增加侧边栏宽度 |
+
+---
+
+## 五、主题支持
+
+- **优先使用 Arco Design 主题变量**:`var(--color-*)`、`var(--spacing-*)`
+- **避免硬编码颜色**:确保主题切换时样式正确
+- **测试主题兼容性**:在明暗主题下测试样式
+
+---
+
+## 六、样式最佳实践
+
+### 推荐做法 ✅
+1. 使用 Arco Design 变量:`padding: var(--spacing-md); color: var(--color-text-1);`
+2. 使用 Flex 布局:`display: flex; flex-direction: column; overflow: hidden; min-height: 0;`
+3. 使用 scoped 样式:`
+
+
+
diff --git a/web/src/api/system.ts b/web/src/api/system.ts
index 785347a..7cea360 100644
--- a/web/src/api/system.ts
+++ b/web/src/api/system.ts
@@ -71,7 +71,11 @@ export async function writeFile(path: string, content: string): Promise {
if (!window.go?.main?.App?.WriteFile) {
throw new Error('WriteFile API 不可用')
}
- await window.go.main.App.WriteFile(path, content)
+ // 确保传递的是字符串类型
+ await window.go.main.App.WriteFile({
+ path: String(path),
+ content: String(content)
+ })
}
/**
@@ -84,6 +88,26 @@ export async function deletePath(path: string): Promise {
await window.go.main.App.DeletePath(path)
}
+/**
+ * 创建目录
+ */
+export async function createDir(path: string): Promise {
+ if (!window.go?.main?.App?.CreateDir) {
+ throw new Error('CreateDir API 不可用')
+ }
+ await window.go.main.App.CreateDir(path)
+}
+
+/**
+ * 创建文件
+ */
+export async function createFile(path: string): Promise {
+ if (!window.go?.main?.App?.CreateFile) {
+ throw new Error('CreateFile API 不可用')
+ }
+ await window.go.main.App.CreateFile(path)
+}
+
/**
* 获取环境变量
*/
@@ -93,3 +117,103 @@ export async function getEnvVars(): Promise> {
}
return await window.go.main.App.GetEnvVars()
}
+
+/**
+ * 列出 zip 文件内容
+ */
+export async function listZipContents(zipPath: string): Promise {
+ console.log('[API] listZipContents 调用:', zipPath)
+ if (!window.go?.main?.App?.ListZipContents) {
+ throw new Error('ListZipContents API 不可用')
+ }
+ try {
+ const result = await window.go.main.App.ListZipContents(zipPath)
+ console.log('[API] listZipContents 结果:', result?.length || 0, '个文件')
+ return result
+ } catch (error) {
+ console.error('[API] listZipContents 错误:', error)
+ throw error
+ }
+}
+
+/**
+ * 从 zip 文件中提取单个文件内容
+ */
+export async function extractFileFromZip(zipPath: string, filePath: string): Promise {
+ console.log('[API] extractFileFromZip 调用:', { zipPath, filePath })
+ if (!window.go?.main?.App?.ExtractFileFromZip) {
+ throw new Error('ExtractFileFromZip API 不可用')
+ }
+ try {
+ const result = await window.go.main.App.ExtractFileFromZip(zipPath, filePath)
+ console.log('[API] extractFileFromZip 成功, 内容长度:', result?.length || 0)
+ return result
+ } catch (error) {
+ console.error('[API] extractFileFromZip 错误:', error)
+ throw error
+ }
+}
+
+/**
+ * 从 zip 文件中提取单个文件到临时目录
+ * 返回临时文件的完整路径,适用于图片等二进制文件
+ */
+export async function extractFileFromZipToTemp(zipPath: string, filePath: string): Promise {
+ console.log('[API] extractFileFromZipToTemp 调用:', { zipPath, filePath })
+ if (!window.go?.main?.App?.ExtractFileFromZipToTemp) {
+ throw new Error('ExtractFileFromZipToTemp API 不可用')
+ }
+ try {
+ const result = await window.go.main.App.ExtractFileFromZipToTemp(zipPath, filePath)
+ console.log('[API] extractFileFromZipToTemp 成功, 临时文件路径:', result)
+ return result
+ } catch (error) {
+ console.error('[API] extractFileFromZipToTemp 错误:', error)
+ throw error
+ }
+}
+
+/**
+ * 获取 zip 文件中特定文件的信息
+ */
+export async function getZipFileInfo(zipPath: string, filePath: string): Promise {
+ console.log('[API] getZipFileInfo 调用:', { zipPath, filePath })
+ if (!window.go?.main?.App?.GetZipFileInfo) {
+ throw new Error('GetZipFileInfo API 不可用')
+ }
+ try {
+ const result = await window.go.main.App.GetZipFileInfo(zipPath, filePath)
+ console.log('[API] getZipFileInfo 结果:', result)
+ return result
+ } catch (error) {
+ console.error('[API] getZipFileInfo 错误:', error)
+ throw error
+ }
+}
+
+/**
+ * 使用系统默认程序打开文件或目录
+ */
+export async function openPath(path: string): Promise {
+ console.log('[API] openPath 调用:', path)
+ if (!window.go?.main?.App?.OpenPath) {
+ throw new Error('OpenPath API 不可用')
+ }
+ try {
+ await window.go.main.App.OpenPath(path)
+ console.log('[API] openPath 成功')
+ } catch (error) {
+ console.error('[API] openPath 错误:', error)
+ throw error
+ }
+}
+
+/**
+ * 获取本地文件服务器URL
+ */
+export async function getFileServerURL(): Promise {
+ if (!window.go?.main?.App?.GetFileServerURL) {
+ throw new Error('GetFileServerURL API 不可用')
+ }
+ return await window.go.main.App.GetFileServerURL()
+}
diff --git a/web/src/components/CodeEditor.vue b/web/src/components/CodeEditor.vue
new file mode 100644
index 0000000..ba8226c
--- /dev/null
+++ b/web/src/components/CodeEditor.vue
@@ -0,0 +1,287 @@
+
+
+
+
+
+
+
+
+
diff --git a/web/src/components/DeviceTest.vue b/web/src/components/DeviceTest.vue
index b652b56..f183e83 100644
--- a/web/src/components/DeviceTest.vue
+++ b/web/src/components/DeviceTest.vue
@@ -83,9 +83,19 @@