Files
Mdeical_Sur_Report/工程分析/实现方案-2026-04-19-02-48-25.md

118 lines
5.0 KiB
Markdown
Raw 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.
# 实现方案 — 2026-04-19-02-48-25
## 1. 方案概述
基于 OpenAI 兼容协议进行标准化抽象。将 4 个散装字段收敛为 `activeAiProvider` + `aiProviders` 字典结构。UI 改为"选择器 + 动态表单",调用端完全配置驱动。通过初始化时的数据迁移保证旧用户无损升级。
## 2. 详细步骤
### 步骤 1`src/types.ts` — 数据结构重构
**目标文件**`src/types.ts`
**修改内容**
1. 新增 `AiProviderConfig` 接口:
```ts
export interface AiProviderConfig {
endpoint: string;
apiKey: string;
modelName: string;
}
```
2. 重构 `SystemSettings`
- 删除:`apiEndpoint`, `apiKey`, `kimiApiKey`, `kimiApiEndpoint`
- 新增:`activeAiProvider: string`
- 新增:`aiProviders: Record<string, AiProviderConfig>`
3. 新增默认预设常量:
```ts
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`
**修改内容**
1. **初始化数据迁移**(在 `useEffect` 读取 settings 后):
```ts
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;
};
```
2. **状态初始化**
```ts
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 }
});
```
3. **UI 改造**
- 用一个 `<select>` 选择 `activeAiProvider`kimi / deepseek / openai / custom
- 下方动态展示 3 个输入框:
- Base URLtype="url"
- API Keytype="password"
- Model Nametype="text"
- 输入框的 `onChange` 更新 `aiProviders[activeAiProvider]` 的对应字段
4. **`testApi` 重构**
- 读取当前 `activeAiProvider` 对应的 `endpoint` 和 `apiKey`
- 发起 `GET {endpoint}/models` 测试连通性
- 若失败fallback 到发一个极简的 chat completion`{"messages":[{"role":"user","content":"hi"}]}`
5. **`resetToDefault`**:使用新的数据结构,包含 `activeAiProvider: 'kimi'` 和 `DEFAULT_AI_PROVIDERS`
### 步骤 3`src/pages/ReportEditor.tsx` — 调用逻辑解耦
**目标文件**`src/pages/ReportEditor.tsx`
**修改内容**
1. `handleAIGenerate` 中:
```ts
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';
```
2. Fetch body 中:
```ts
model: modelName,
```
3. 错误提示文案从"尚未配置 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 配置
### 步骤 5CSS / 其他清理
- `index.css` 无需修改(本次不涉及新样式)
- `tsconfig.json` 无需修改
## 3. 依赖关系
- 步骤 1types必须先完成
- 步骤 2SystemSettings和步骤 3ReportEditor可并行
- 步骤 4Login在步骤 1 之后即可进行
- 步骤 5 在最后
## 4. 风险预案
- **数据迁移失败**:若 `localStorage` 中旧 settings 读取异常,使用 `try/catch` 包裹迁移逻辑,失败时回退到 `DEFAULT_AI_PROVIDERS`
- **类型不匹配**:旧代码中可能还有未清理的 `settings.apiKey` 引用build/lint 阶段会暴露,逐一修复
- **Provider 配置为空**:在 ReportEditor 调用时增加 `provider?.apiKey` 的判空保护,避免 undefined 报错