# 功能变更实现方案文档(20260419_2316) ## 实现方案 A:模板手术步骤 AI 区域化 ### 变更点 `src/utils/defaultContent.ts` line 54-76。 ### 具体实现 将原有的: ```html

手术步骤、术中出现的情况及处理:

1.患者仰卧位...

2.腹腔镜探查...

... ``` 替换为: ```html

手术步骤、术中出现的情况及处理:

手术步骤、术中出现的情况及处理-AI可编辑区域

1.患者仰卧位...

2.腹腔镜探查...

...
``` --- ## 实现方案 B:API 密钥安全增强 ### 变更点 1:默认值预设 `src/types.ts` line 92: ```ts kimi: { endpoint: 'https://api.moonshot.cn/v1', apiKey: 'sk-2IAFn8ORoSdUcCxYX6DmXJWbH7BxftSSA8kN88mD1KUDTmkv', modelName: 'moonshot-v1-auto' } ``` ### 变更点 2:前端防复制 `src/pages/SystemSettings.tsx` API Key input 添加事件拦截: ```tsx onCopy={(e) => e.preventDefault()} onCut={(e) => e.preventDefault()} ``` ### 变更点 3:轻度加密存储 `src/utils/storage.ts` 增加透明加密层: - 使用 XOR + Base64 对 `systemSettings` key 的数据进行加解密 - 加密密钥固定为 `'MedicalReportSys2024'` - 完全透明:所有调用方无需改动,`get`/`set` 自动处理 ```ts const CRYPTO_KEY = 'MedicalReportSys2024'; function xorEncrypt(text: string, key: string): string { let result = ''; for (let i = 0; i < text.length; i++) { result += String.fromCharCode(text.charCodeAt(i) ^ key.charCodeAt(i % key.length)); } return btoa(result); } function xorDecrypt(encrypted: string, key: string): string { const text = atob(encrypted); let result = ''; for (let i = 0; i < text.length; i++) { result += String.fromCharCode(text.charCodeAt(i) ^ key.charCodeAt(i % key.length)); } return result; } ``` 在 `get` 和 `set` 中: ```ts if (key === 'systemSettings') { data = xorEncrypt(JSON.stringify(value), CRYPTO_KEY); // 存储时加一个前缀标记以便区分 } ``` 为保持向后兼容(旧数据是明文 JSON),解密时先尝试 `JSON.parse`,如果失败再尝试 XOR 解密: ```ts get(key: string, fallback: T): T { try { const raw = localStorage.getItem(key); if (!raw) return fallback; if (key === 'systemSettings') { // 先尝试直接 JSON.parse(兼容旧明文数据) try { return JSON.parse(raw) as T; } catch { // 旧数据解析失败,尝试解密 return JSON.parse(xorDecrypt(raw, CRYPTO_KEY)) as T; } } return JSON.parse(raw) as T; } catch { return fallback; } } ``` --- ## 实现方案 C:默认模型名切换 ### 变更点 - `src/types.ts` line 92:`modelName: 'moonshot-v1-auto'` - `src/pages/SystemSettings.tsx` migration fallback line 41:`modelName: 'moonshot-v1-auto'` - `src/pages/ReportEditor.tsx` fallback line 901:`modelName = provider?.modelName || 'moonshot-v1-auto'` --- ## 实现方案 D:抽帧百分比 + 模式默认值 ### 硬编码数组 ```ts const DEFAULT_FRAME_POSITIONS = [7.9, 9.3, 46.2, 49.1, 63.9, 64.8, 68.8, 73.7, 80.2, 85.0, 96.3, 98.6]; ``` ### 变更点 | 文件 | 位置 | 变更 | |------|------|------| | `src/pages/Login.tsx` | `initData()` framePositions | 从均匀计算改为硬编码数组 | | `src/pages/Login.tsx` | `initData()` frameMode | `'uniform'` → `'keep'` | | `src/pages/SystemSettings.tsx` | `useState` framePositions | `[5,10,...]` → 硬编码数组 | | `src/pages/SystemSettings.tsx` | `useState` frameMode | `'uniform'` → `'keep'` | | `src/pages/SystemSettings.tsx` | loaded settings fallback | `'uniform'` → `'keep'` | | `src/pages/SystemSettings.tsx` | `resetToDefault()` | framePositions + frameMode | | `src/pages/ReportEditor.tsx` | fallback framePositions | `[5,10,...]` → 硬编码数组 | --- ## 依赖与兼容性 - 无新增 npm 依赖 - storage 加密保持向后兼容:旧明文数据可正常读取,新写入的数据自动加密 - 所有变更均为默认值修改,不影响已有用户配置(除非手动重置)