182 lines
5.6 KiB
Markdown
182 lines
5.6 KiB
Markdown
# 启动问题修复总结
|
|
|
|
## 问题描述
|
|
|
|
用户反馈应用无法启动,窗口未渲染,没有明显错误信息。
|
|
|
|
## 问题分析
|
|
|
|
### 1. 前端问题
|
|
|
|
#### 问题 A: Wails 绑定未准备好
|
|
- **原因**: `onMounted` 钩子中立即调用 `window.go.main.App.GetAppConfig()`,但 Wails 绑定可能还未完全初始化
|
|
- **影响**: 导致配置加载失败,界面无法正常渲染
|
|
|
|
#### 问题 B: 未使用的导入
|
|
- **原因**: `IconSync` 导入但未使用
|
|
- **影响**: 可能导致打包或运行时错误
|
|
|
|
#### 问题 C: 错误处理不足
|
|
- **原因**: 配置加载失败时没有降级到默认配置
|
|
- **影响**: 任何配置 API 错误都会导致应用无法显示
|
|
|
|
### 2. 后端问题
|
|
|
|
#### 问题 A: 不安全的类型断言
|
|
- **原因**: 多处直接类型断言(如 `config["success"].(bool)`)可能导致 panic
|
|
- **位置**:
|
|
- `getVisibleTabs()` 函数中的类型断言
|
|
- `SaveAppConfig()` 函数中的类型断言
|
|
- **影响**: 如果配置数据格式不符合预期,整个应用崩溃
|
|
|
|
#### 问题 B: `visibleTabs` 类型转换错误
|
|
- **原因**: JSON 反序列化后 `visibleTabs` 是 `[]interface{}`,不能直接断言为 `[]string`
|
|
- **影响**: 类型断言失败导致 panic
|
|
|
|
## 修复方案
|
|
|
|
### 1. 前端修复 (`frontend/src/App.vue`)
|
|
|
|
#### 添加 Wails 绑定检查和重试机制
|
|
```javascript
|
|
const loadConfig = async () => {
|
|
try {
|
|
// 检查 Wails 绑定是否准备好
|
|
if (!window.go || !window.go.main || !window.go.main.App) {
|
|
console.warn('Wails 绑定未准备好,等待重试...')
|
|
setTimeout(() => loadConfig(), 100)
|
|
return
|
|
}
|
|
|
|
const result = await window.go.main.App.GetAppConfig()
|
|
// ... 处理结果
|
|
} catch (error) {
|
|
console.error('加载配置失败:', error)
|
|
// 降级到默认配置
|
|
useDefaultConfig()
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 添加默认配置降级
|
|
```javascript
|
|
const useDefaultConfig = () => {
|
|
appConfig.value = {
|
|
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'
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 移除未使用的导入
|
|
```javascript
|
|
// 修复前
|
|
import { IconSync, IconSettings } from '@arco-design/web-vue/es/icon'
|
|
|
|
// 修复后
|
|
import { IconSettings } from '@arco-design/web-vue/es/icon'
|
|
```
|
|
|
|
### 2. 后端修复 (`app.go`)
|
|
|
|
#### 安全的类型断言
|
|
```go
|
|
// 修复前 - 不安全
|
|
if !config["success"].(bool) {
|
|
return defaultConfig
|
|
}
|
|
data := config["data"].(map[string]interface{})
|
|
visibleTabs := data["visibleTabs"].([]string)
|
|
|
|
// 修复后 - 安全
|
|
success, ok := config["success"].(bool)
|
|
if !ok || !success {
|
|
return defaultConfig
|
|
}
|
|
data, ok := config["data"].(map[string]interface{})
|
|
if !ok {
|
|
return defaultConfig
|
|
}
|
|
visibleTabsInterface, ok := data["visibleTabs"].([]interface{})
|
|
if !ok {
|
|
return defaultConfig
|
|
}
|
|
// 安全转换 []interface{} 到 []string
|
|
visibleTabs := make([]string, 0, len(visibleTabsInterface))
|
|
for _, v := range visibleTabsInterface {
|
|
if tabStr, ok := v.(string); ok {
|
|
visibleTabs = append(visibleTabs, tabStr)
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 在 `SaveAppConfig` 中应用同样的安全模式
|
|
```go
|
|
oldConfig, _ := a.configAPI.GetAppConfig()
|
|
var oldVisibleTabs []string
|
|
if success, ok := oldConfig["success"].(bool); ok && success {
|
|
if data, ok := oldConfig["data"].(map[string]interface{}); ok {
|
|
if vtInterface, ok := data["visibleTabs"].([]interface{}); ok {
|
|
oldVisibleTabs = make([]string, 0, len(vtInterface))
|
|
for _, v := range vtInterface {
|
|
if tabStr, ok := v.(string); ok {
|
|
oldVisibleTabs = append(oldVisibleTabs, tabStr)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## 修复效果
|
|
|
|
### 前端改进
|
|
1. **容错性提升**: 配置加载失败时自动降级到默认配置,应用始终可显示
|
|
2. **初始化更稳定**: Wails 绑定未准备好时自动重试,避免启动失败
|
|
3. **代码更简洁**: 移除未使用的导入
|
|
|
|
### 后端改进
|
|
1. **消除 Panic 风险**: 所有类型断言都使用安全的 `ok` 模式
|
|
2. **类型转换正确**: 正确处理 JSON 反序列化后的 `[]interface{}` 类型
|
|
3. **降级机制**: 任何步骤失败都会安全降级到默认配置
|
|
|
|
## 测试建议
|
|
|
|
### 启动测试
|
|
1. **首次启动** - 没有配置文件,应使用默认配置正常启动
|
|
2. **配置损坏** - 手动破坏配置文件,应降级到默认配置
|
|
3. **正常启动** - 有有效配置,应正常加载并显示
|
|
|
|
### 运行时测试
|
|
1. **保存配置** - 设置中修改配置并保存,应立即生效
|
|
2. **启用模块** - 启用之前禁用的模块,应动态初始化
|
|
3. **禁用模块** - 禁用已启用的模块,应正常隐藏
|
|
|
|
## 修改的文件
|
|
|
|
1. `frontend/src/App.vue`
|
|
- 添加 Wails 绑定检查和重试机制
|
|
- 添加 `useDefaultConfig()` 函数
|
|
- 移除未使用的 `IconSync` 导入
|
|
|
|
2. `app.go`
|
|
- 重写 `getVisibleTabs()` 函数,使用安全类型断言
|
|
- 重写 `SaveAppConfig()` 函数,使用安全类型断言
|
|
- 正确处理 `[]interface{}` 到 `[]string` 的转换
|
|
|
|
## 总结
|
|
|
|
通过添加完善的错误处理和降级机制,解决了应用启动时的潜在崩溃问题。现在即使配置 API 出现问题或数据格式不符合预期,应用也能正常启动并显示默认界面。
|
|
|
|
主要改进点:
|
|
- ✅ 前端添加 Wails 绑定就绪检查和自动重试
|
|
- ✅ 前端添加配置加载失败的降级机制
|
|
- ✅ 后端所有类型断言都使用安全模式
|
|
- ✅ 正确处理 JSON 反序列化后的类型转换
|
|
- ✅ 移除未使用的导入
|