245 lines
8.1 KiB
Markdown
245 lines
8.1 KiB
Markdown
# U-Desk 设置功能重构实现总结
|
||
|
||
## 实施概览
|
||
|
||
本次实施完成了 U-Desk 的设置功能重构,将"版本更新"功能改为"设置"按钮,并实现了完整的 Tab 配置管理功能。
|
||
|
||
## 已完成功能
|
||
|
||
### ✅ 阶段一:Go 后端基础设施
|
||
|
||
#### 1. 数据模型 (`internal/storage/models/app_config.go`)
|
||
- 创建了 `AppConfig` 模型用于存储应用配置
|
||
- 支持键值对存储,使用 JSON 序列化复杂配置
|
||
- 包含时间戳和描述字段
|
||
|
||
#### 2. 数据库迁移 (`internal/storage/sqlite.go`)
|
||
- 已将 `AppConfig` 模型添加到 `AutoMigrate`
|
||
- 数据库表名:`app_config`
|
||
|
||
#### 3. 配置服务层 (`internal/service/config_service.go`)
|
||
- `GetTabConfig()`: 获取 Tab 配置,返回默认配置(如果不存在)
|
||
- `SaveTabConfig()`: 保存 Tab 配置到数据库
|
||
- 定义了 `TabConfig` 和 `TabDefinition` 结构体
|
||
- 实现了配置验证和默认值处理
|
||
|
||
#### 4. 配置 API 层 (`internal/api/config_api.go`)
|
||
- `GetAppConfig()`: 转换为前端需要的格式
|
||
- `SaveAppConfig()`: 接收前端格式,验证并保存
|
||
- 实现了前后端数据格式转换
|
||
- 包含完整的验证逻辑(至少保留一个 Tab,默认 Tab 必须可见)
|
||
|
||
#### 5. App 集成 (`app.go`)
|
||
- 在 `App` 结构体中添加了 `configAPI *api.ConfigAPI`
|
||
- 在 `initCoreAPIs()` 中初始化 ConfigAPI
|
||
- 添加了 `GetAppConfig()` 和 `SaveAppConfig()` 方法供前端调用
|
||
|
||
### ✅ 阶段二:前端设置面板
|
||
|
||
#### 1. SettingsPanel 组件 (`frontend/src/components/SettingsPanel.vue`)
|
||
|
||
**核心功能:**
|
||
- ✅ 使用 Arco Design 的 `<a-drawer>` 组件实现侧边抽屉
|
||
- ✅ 使用 `<a-tabs>` 组织设置内容:
|
||
- "Tab 配置" tab
|
||
- "版本更新" tab(嵌入 UpdatePanel 组件)
|
||
- ✅ Tab 显示控制:使用 `<a-checkbox-group>` 实现多选
|
||
- ✅ 默认 Tab 选择:使用 `<a-select>` 实现
|
||
- ✅ Tab 拖拽排序:使用原生 HTML5 Drag & Drop API 实现
|
||
|
||
**拖拽实现特点:**
|
||
- 无需额外依赖,使用原生 HTML5 API
|
||
- 拖拽时显示视觉反馈(透明度、缩放)
|
||
- 支持拖拽重新排序
|
||
- 平滑的过渡动画
|
||
|
||
#### 2. App.vue 修改
|
||
|
||
**关键修改:**
|
||
- ✅ 替换"版本更新"按钮为"设置"按钮(IconSettings)
|
||
- ✅ 动态渲染 Tabs(根据配置动态生成)
|
||
- ✅ 动态渲染组件(使用 `<component>` 标签)
|
||
- ✅ 添加设置抽屉组件
|
||
- ✅ 实现配置管理逻辑:
|
||
- `loadConfig()`: 从后端加载配置
|
||
- `handleSaveConfig()`: 保存配置到后端
|
||
- `visibleTabs` 计算属性:根据配置动态生成可见 Tab 列表
|
||
- ✅ 监听 `activeTab` 变化,自动处理 Tab 被隐藏的情况
|
||
|
||
### ✅ 阶段三:配置数据结构
|
||
|
||
#### 前端配置格式
|
||
```typescript
|
||
interface AppTab {
|
||
key: string // Tab 唯一标识
|
||
title: string // Tab 显示标题
|
||
visible: boolean // 是否显示
|
||
enabled: boolean // 是否启用(用于验证)
|
||
}
|
||
|
||
interface AppConfig {
|
||
tabs: AppTab[] // 所有可用 Tab 定义
|
||
visibleTabs: string[] // 当前显示的 Tab key 列表(按顺序)
|
||
defaultTab: string // 默认打开的 Tab
|
||
}
|
||
```
|
||
|
||
#### 后端配置格式
|
||
```go
|
||
type TabConfig struct {
|
||
AvailableTabs []TabDefinition `json:"available_tabs"`
|
||
VisibleTabs []string `json:"visible_tabs"`
|
||
DefaultTab string `json:"default_tab"`
|
||
}
|
||
|
||
type TabDefinition struct {
|
||
Key string `json:"key"`
|
||
Title string `json:"title"`
|
||
Enabled bool `json:"enabled"`
|
||
}
|
||
```
|
||
|
||
#### 默认配置
|
||
```javascript
|
||
{
|
||
tabs: [
|
||
{ key: 'db-cli', title: '数据库', visible: true, enabled: true },
|
||
{ key: 'file-system', title: '文件管理', visible: true, enabled: true },
|
||
{ key: 'device', title: '设备调用测试', visible: true, enabled: true }
|
||
],
|
||
visibleTabs: ['db-cli', 'file-system', 'device'],
|
||
defaultTab: 'db-cli'
|
||
}
|
||
```
|
||
|
||
### ✅ 阶段四:验证和错误处理
|
||
|
||
#### 前端验证
|
||
- ✅ 至少保留一个可见 Tab(`visibleTabs.length >= 1`)
|
||
- ✅ 默认 Tab 必须可见(`defaultTab` 在 `visibleTabs` 中)
|
||
- ✅ Tab key 不重复(由结构保证)
|
||
- ✅ 禁用状态下的 Tab 不可取消选中
|
||
|
||
#### 后端验证
|
||
- ✅ 配置 JSON 格式验证
|
||
- ✅ 数据库操作错误处理
|
||
- ✅ 返回统一的响应格式(success/data/message)
|
||
- ✅ 配置损坏时自动返回默认配置
|
||
|
||
#### 兼容性处理
|
||
- ✅ 首次加载:如果数据库中没有配置,返回默认配置
|
||
- ✅ 配置损坏:如果解析失败,记录错误并返回默认配置
|
||
- ✅ 当前 Tab 不可见:保存配置后,如果当前激活的 Tab 被隐藏,自动切换到默认 Tab
|
||
|
||
## 配置存储
|
||
|
||
### 数据库
|
||
- **类型**: SQLite
|
||
- **位置**: `~/.u-desk/app.db`(Windows: `C:\Users\你的用户名\.u-desk\app.db`)
|
||
- **表名**: `app_config`
|
||
- **配置键**: `tab_config`
|
||
|
||
### LocalStorage
|
||
- **键名**: `app-active-tab`
|
||
- **用途**: 临时保存当前激活的 Tab(不持久化到后端)
|
||
|
||
## 文件清单
|
||
|
||
### 新增文件
|
||
1. `E:\wk-lab\go-desk\internal\storage\models\app_config.go` - 配置数据模型
|
||
2. `E:\wk-lab\go-desk\internal\service\config_service.go` - 配置服务层
|
||
3. `E:\wk-lab\go-desk\internal\api\config_api.go` - 配置 API 层
|
||
4. `E:\wk-lab\go-desk\web\src\components\SettingsPanel.vue` - 设置面板组件
|
||
|
||
### 修改文件
|
||
1. `E:\wk-lab\go-desk\internal\storage\sqlite.go` - 添加 AppConfig 到数据库迁移
|
||
2. `E:\wk-lab\go-desk\app.go` - 集成 ConfigAPI
|
||
3. `E:\wk-lab\go-desk\web\src\App.vue` - 替换版本更新按钮,实现动态 Tabs
|
||
|
||
## 功能特性
|
||
|
||
### P0(必须)- 已完成 ✅
|
||
- ✅ Go 后端配置 API
|
||
- ✅ 前端 SettingsPanel 基础 UI
|
||
- ✅ Tab 显示/隐藏功能
|
||
- ✅ 拖拽排序功能
|
||
- ✅ App.vue 动态 Tabs
|
||
|
||
### P1(重要)- 已完成 ✅
|
||
- ✅ 默认 Tab 选择
|
||
- ✅ 配置验证和错误处理
|
||
- ✅ 版本更新集成到设置面板
|
||
|
||
### P2(可选)- 未实现
|
||
- ❌ 键盘辅助(上移/下移按钮)
|
||
- ❌ 配置导出/导入
|
||
- ⚠️ 拖拽动画优化(基础版本已实现)
|
||
|
||
## 测试建议
|
||
|
||
### 后端测试
|
||
1. ✅ 测试 `GetAppConfig()` 返回默认配置
|
||
2. ⏳ 测试 `SaveAppConfig()` 保存和读取
|
||
3. ⏳ 测试配置 JSON 序列化/反序列化
|
||
4. ⏳ 测试数据库连接和错误处理
|
||
|
||
### 前端测试
|
||
1. ⏳ 测试拖拽排序功能
|
||
2. ⏳ 测试 Tab 显示/隐藏切换
|
||
3. ⏳ 测试默认 Tab 选择
|
||
4. ⏳ 测试至少保留一个 Tab 的验证
|
||
5. ⏳ 测试配置保存和恢复
|
||
6. ⏳ 测试版本更新功能在设置面板中的显示
|
||
|
||
### 集成测试
|
||
1. ⏳ 测试配置保存后 Tab 的动态更新
|
||
2. ⏳ 测试刷新页面后配置保持
|
||
3. ⏳ 测试当前 Tab 被隐藏时的自动切换
|
||
4. ⏳ 测试窗口控制按钮与设置的交互
|
||
|
||
## UX 优化建议
|
||
|
||
### 已实现
|
||
- ✅ 拖拽反馈(透明度、缩放效果)
|
||
- ✅ 保存提示(Message 提示)
|
||
- ✅ 加载状态(按钮 loading 状态)
|
||
|
||
### 可选优化
|
||
- ⏳ 拖拽时显示虚线框指示放置位置
|
||
- ⏳ 首次加载配置时显示 Loading
|
||
- ⏳ 键盘辅助(上移/下移按钮)作为拖拽的替代方式
|
||
- ⏳ 配置预览(在保存前预览 Tab 的最终顺序和可见性)
|
||
|
||
## 构建状态
|
||
|
||
### Go 后端
|
||
- ✅ 构建成功,无编译错误
|
||
- ✅ 所有依赖正确导入
|
||
- ✅ 数据库迁移正常
|
||
|
||
### 前端
|
||
- ⏳ 需要运行 `npm install` 安装依赖
|
||
- ⏳ 需要运行 `npm run dev` 测试前端功能
|
||
|
||
## 下一步
|
||
|
||
1. **测试功能**: 运行应用并测试所有功能
|
||
2. **修复 bug**: 根据测试结果修复可能出现的问题
|
||
3. **优化体验**: 根据实际使用情况优化 UX
|
||
4. **添加文档**: 更新用户文档说明新功能
|
||
|
||
## 技术亮点
|
||
|
||
1. **无依赖拖拽**: 使用原生 HTML5 Drag & Drop API,无需额外依赖
|
||
2. **类型安全**: Go 后端和 TypeScript 前端都有完整的类型定义
|
||
3. **数据验证**: 前后端双重验证,确保数据一致性
|
||
4. **优雅降级**: 配置损坏时自动回退到默认配置
|
||
5. **动态渲染**: 使用 Vue 的 `<component>` 标签实现真正的动态组件渲染
|
||
|
||
## 注意事项
|
||
|
||
1. **数据库迁移**: 首次运行时会自动创建 `app_config` 表
|
||
2. **配置持久化**: 配置保存在 SQLite 数据库中,重启应用后保持
|
||
3. **Tab 状态**: 当前激活的 Tab 保存在 LocalStorage 中,不持久化到后端
|
||
4. **兼容性**: 如果旧版本没有配置,会自动使用默认配置
|