5.0 KiB
5.0 KiB
实现方案 — 2026-04-19-02-48-25
1. 方案概述
基于 OpenAI 兼容协议进行标准化抽象。将 4 个散装字段收敛为 activeAiProvider + aiProviders 字典结构。UI 改为"选择器 + 动态表单",调用端完全配置驱动。通过初始化时的数据迁移保证旧用户无损升级。
2. 详细步骤
步骤 1:src/types.ts — 数据结构重构
目标文件:src/types.ts
修改内容:
- 新增
AiProviderConfig接口:export interface AiProviderConfig { endpoint: string; apiKey: string; modelName: string; } - 重构
SystemSettings:- 删除:
apiEndpoint,apiKey,kimiApiKey,kimiApiEndpoint - 新增:
activeAiProvider: string - 新增:
aiProviders: Record<string, AiProviderConfig>
- 删除:
- 新增默认预设常量:
export const DEFAULT_AI_PROVIDERS: Record<string, AiProviderConfig> = { kimi: { endpoint: 'https://api.moonshot.cn/v1', apiKey: '', modelName: 'kimi-k2-5' }, deepseek: { endpoint: 'https://api.deepseek.com/v1', apiKey: '', modelName: 'deepseek-chat' }, openai: { endpoint: 'https://api.openai.com/v1', apiKey: '', modelName: 'gpt-4o' }, custom: { endpoint: '', apiKey: '', modelName: '' } };
步骤 2:src/pages/SystemSettings.tsx — UI 重构 + 数据迁移
目标文件:src/pages/SystemSettings.tsx
修改内容:
- 初始化数据迁移(在
useEffect读取 settings 后):const migrateOldAiSettings = (saved: any) => { if (!saved.aiProviders) { const providers = { ...DEFAULT_AI_PROVIDERS }; if (saved.kimiApiKey || saved.kimiApiEndpoint) { providers.kimi = { endpoint: saved.kimiApiEndpoint || providers.kimi.endpoint, apiKey: saved.kimiApiKey || '', modelName: 'kimi-k2-5' }; } saved.aiProviders = providers; saved.activeAiProvider = 'kimi'; // 清理旧字段(可选,保留 localStorage 中不删除,但代码不再读取) storage.set('systemSettings', saved); } return saved; }; - 状态初始化:
const [settings, setSettings] = useState<SystemSettings>({ frameCount: 12, framePositions: [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60], defaultTemplate: '', frameMode: 'uniform', activeAiProvider: 'kimi', aiProviders: { ...DEFAULT_AI_PROVIDERS } }); - UI 改造:
- 用一个
<select>选择activeAiProvider(kimi / deepseek / openai / custom) - 下方动态展示 3 个输入框:
- Base URL(type="url")
- API Key(type="password")
- Model Name(type="text")
- 输入框的
onChange更新aiProviders[activeAiProvider]的对应字段
- 用一个
testApi重构:- 读取当前
activeAiProvider对应的endpoint和apiKey - 发起
GET {endpoint}/models测试连通性 - 若失败,fallback 到发一个极简的 chat completion(
{"messages":[{"role":"user","content":"hi"}]})
- 读取当前
resetToDefault:使用新的数据结构,包含activeAiProvider: 'kimi'和DEFAULT_AI_PROVIDERS
步骤 3:src/pages/ReportEditor.tsx — 调用逻辑解耦
目标文件:src/pages/ReportEditor.tsx
修改内容:
handleAIGenerate中:const settings = storage.get<SystemSettings>('systemSettings', {} as SystemSettings); const provider = settings.aiProviders?.[settings.activeAiProvider || 'kimi']; const apiKey = provider?.apiKey || ''; const apiEndpoint = provider?.endpoint || 'https://api.moonshot.cn/v1'; const modelName = provider?.modelName || 'kimi-k2-5';- Fetch body 中:
model: modelName, - 错误提示文案从"尚未配置 Kimi API Key"改为"尚未配置 AI API Key"
步骤 4:src/pages/Login.tsx — 默认初始化更新(检查)
目标文件:src/pages/Login.tsx
修改内容:
- 检查
initData()或defaultSettings中是否硬编码了旧的apiKey/apiEndpoint - 若有,替换为新的
activeAiProvider+aiProviders结构 - 由于 Login.tsx 的初始化是全局唯一入口,必须确保新用户首次使用时
systemSettings包含正确的默认 AI 配置
步骤 5:CSS / 其他清理
index.css无需修改(本次不涉及新样式)tsconfig.json无需修改
3. 依赖关系
- 步骤 1(types)必须先完成
- 步骤 2(SystemSettings)和步骤 3(ReportEditor)可并行
- 步骤 4(Login)在步骤 1 之后即可进行
- 步骤 5 在最后
4. 风险预案
- 数据迁移失败:若
localStorage中旧 settings 读取异常,使用try/catch包裹迁移逻辑,失败时回退到DEFAULT_AI_PROVIDERS - 类型不匹配:旧代码中可能还有未清理的
settings.apiKey引用,build/lint 阶段会暴露,逐一修复 - Provider 配置为空:在 ReportEditor 调用时增加
provider?.apiKey的判空保护,避免 undefined 报错