Files
linshen d1f6c62390 feat: 重构UI层状态持久化架构,增强Electron API交互与Prompt服务
- 导出偏好设置服务类型和实现,增强服务可用性。
- 实现`ElectronPreferenceServiceProxy`和`PreferenceService`,提供偏好设置管理功能。
- 更新组件,使用偏好设置服务替代原有存储逻辑,提升代码可维护性和一致性。
- 集成偏好设置服务的IPC处理逻辑,确保主进程正确处理相关请求。
- 新增重构UI层状态持久化架构任务,目标是将UI层对`useStorage`的直接依赖替换为`PreferenceService`。
- 优化IPC通信,新增对流式处理的支持,增强Prompt服务功能。
- 集成Prompt服务的IPC处理逻辑,并新增成功和错误响应辅助函数,简化IPC处理逻辑,提升代码可读性和一致性;同时优化多个IPC处理函数,确保在发生错误时能够统一返回错误信息,增强错误管理。
- 新增对`iteratePrompt`、`testPrompt`、`getHistory`、`getIterationChain`等方法的支持,暴露Prompt服务接口,方便前端调用,扩展前端与主进程的交互能力。
- 删除不再使用的Markdown输出规则和AI开发工作流程文档,提升项目的可维护性和文档的清晰度。
2025-06-29 17:02:33 +08:00

215 lines
6.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 技术实现详解
## 🔧 架构设计
### 整体架构
```
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ UI Components │ │ PreferenceService │ │ Storage Layer │
│ │ │ │ │ │
│ - TemplateManager│───▶│ - IPreferenceService│───▶│ - Web: useStorage│
│ - ThemeToggle │ │ - ElectronProxy │ │ - Electron: IPC │
│ - LanguageSwitch│ │ - usePreferences │ │ - Main: fs │
└─────────────────┘ └──────────────────┘ └─────────────────┘
```
### 关键组件
#### 1. IPreferenceService接口
```typescript
interface IPreferenceService {
get<T>(key: string, defaultValue: T): Promise<T>;
set<T>(key: string, value: T): Promise<void>;
delete(key: string): Promise<void>;
keys(): Promise<string[]>;
clear(): Promise<void>;
}
```
#### 2. 环境检测机制
```typescript
// 检测Electron API完整可用性
export function isElectronApiReady(): boolean {
const window_any = window as any;
const hasElectronAPI = typeof window_any.electronAPI !== 'undefined';
const hasPreferenceApi = hasElectronAPI &&
typeof window_any.electronAPI.preference !== 'undefined';
return hasElectronAPI && hasPreferenceApi;
}
// 异步等待API就绪
export function waitForElectronApi(timeout = 5000): Promise<boolean> {
return new Promise((resolve) => {
if (isElectronApiReady()) {
resolve(true);
return;
}
const startTime = Date.now();
const checkInterval = setInterval(() => {
if (isElectronApiReady()) {
clearInterval(checkInterval);
resolve(true);
} else if (Date.now() - startTime > timeout) {
clearInterval(checkInterval);
resolve(false);
}
}, 50);
});
}
```
## 🐛 问题诊断与解决
### 问题1: 竞态条件错误
**错误信息**: `Cannot read properties of undefined (reading 'preference')`
**根本原因**:
- Vue组件初始化时调用useTemplateManager
- useTemplateManager立即尝试访问preferenceService
- 但此时window.electronAPI.preference尚未完全就绪
**解决方案**:
1. **延迟初始化检查**: 在useAppInitializer中等待API就绪
2. **运行时保护**: 在代理服务中添加API可用性检查
### 问题2: API路径不匹配
**错误现象**: `hasApi: false, hasPreferenceApi: false`
**根本原因**:
- preload.js暴露API在: `window.electronAPI.preference`
- 代码尝试访问: `window.api.preference`
**解决方案**: 统一API路径为`window.electronAPI.preference`
## 📝 实施步骤
### 步骤1: 环境检测增强
**文件**: `packages/core/src/utils/environment.ts`
**修改内容**:
- 新增`isElectronApiReady()`函数
- 新增`waitForElectronApi()`函数
- 增强API可用性检测逻辑
### 步骤2: 应用初始化优化
**文件**: `packages/ui/src/composables/useAppInitializer.ts`
**修改内容**:
```typescript
if (isRunningInElectron()) {
console.log('[AppInitializer] 检测到Electron环境等待API就绪...');
// 等待 Electron API 完全就绪
const apiReady = await waitForElectronApi();
if (!apiReady) {
throw new Error('Electron API 初始化超时请检查preload脚本是否正确加载');
}
console.log('[AppInitializer] Electron API 就绪,初始化代理服务...');
// ... 继续初始化
}
```
### 步骤3: 代理服务保护
**文件**: `packages/core/src/services/preference/electron-proxy.ts`
**修改内容**:
```typescript
export class ElectronPreferenceServiceProxy implements IPreferenceService {
private ensureApiAvailable() {
const windowAny = window as any;
if (!windowAny?.electronAPI?.preference) {
throw new Error('Electron API not available. Please ensure preload script is loaded and window.electronAPI.preference is accessible.');
}
}
async get<T>(key: string, defaultValue: T): Promise<T> {
this.ensureApiAvailable();
return window.electronAPI.preference.get(key, defaultValue);
}
// ... 其他方法
}
```
### 步骤4: 导出更新
**文件**:
- `packages/core/src/index.ts`
- `packages/ui/src/index.ts`
**修改内容**: 导出新的环境检测函数
### 步骤5: 构建与测试
```bash
# 构建core包
cd packages/core && pnpm run build
# 构建ui包
cd packages/ui && pnpm run build
# 运行测试
pnpm run test
```
## 🔍 调试过程
### 调试日志分析
```
[isRunningInElectron] Verdict: true (via electronAPI)
[isElectronApiReady] API readiness check: {hasElectronAPI: true, hasPreferenceApi: true}
[waitForElectronApi] API already ready
[AppInitializer] Electron API 就绪,初始化代理服务...
[AppInitializer] 所有服务初始化完成
```
### 关键时序
1. **环境检测****API等待****服务初始化****组件挂载**
2. 确保每个步骤都完成后才进行下一步
3. 添加超时保护防止无限等待
## ⚡ 性能优化
### 1. 快速检测
- API就绪时立即返回无需等待
- 50ms检查间隔平衡响应性和性能
### 2. 超时保护
- 5秒超时防止无限等待
- 明确的错误信息指导问题排查
### 3. 缓存机制
- 环境检测结果可以缓存
- 避免重复的DOM查询
## 🧪 测试验证
### 测试结果
- **总测试数**: 262个
- **通过数**: 252个
- **跳过数**: 9个
- **失败数**: 1个(网络相关,非功能问题)
### 关键测试场景
1. **Electron环境启动**
2. **API初始化时序**
3. **代理服务调用**
4. **错误处理机制**
5. **超时保护**
## 🔗 相关代码文件
### 核心修改文件
1. `packages/core/src/utils/environment.ts` - 环境检测增强
2. `packages/ui/src/composables/useAppInitializer.ts` - 初始化优化
3. `packages/core/src/services/preference/electron-proxy.ts` - 代理服务保护
4. `packages/core/src/index.ts` - 导出更新
5. `packages/ui/src/index.ts` - 导出更新
### 相关配置文件
- `packages/desktop/preload.js` - API暴露配置
- `packages/desktop/main.js` - 主进程IPC处理
---
**实施完成日期**: 2025-01-01
**验证状态**: ✅ 完全通过