79 lines
4.2 KiB
Markdown
79 lines
4.2 KiB
Markdown
# 实现方案 — 2026-04-19-02-26-05
|
||
|
||
## 1. 方案概述
|
||
基于现有 `contentEditable` 架构,引入 `ai-region` DOM 区块作为 AI 的"手术锚点"。通过标准 Fetch API 接入 Kimi 多模态接口,采用 JSON Schema 约束输出。所有 AI 状态集中在 ReportEditor 管理,TemplateManage 仅负责区域插入。
|
||
|
||
## 2. 详细步骤
|
||
|
||
### 步骤 1:`src/types.ts` — 扩展 SystemSettings
|
||
**目标文件**:`src/types.ts`
|
||
**修改内容**:
|
||
- `SystemSettings` 接口新增 `kimiApiKey?: string` 和 `kimiApiEndpoint?: string`
|
||
- 默认值兜底在 `SystemSettings.tsx` 中处理
|
||
|
||
### 步骤 2:`src/pages/SystemSettings.tsx` — 完善 AI 接口配置
|
||
**目标文件**:`src/pages/SystemSettings.tsx`
|
||
**修改内容**:
|
||
- AI 接口集成卡片中,将现有的 `apiEndpoint` / `apiKey` 的 placeholder 和 label 改为明确指向 Kimi
|
||
- `testApi` 函数改为真实调用 Kimi `/v1/models` 或简单 chat completion 进行连通性测试
|
||
- `resetToDefault` 中保留新字段的默认空值
|
||
|
||
### 步骤 3:`src/pages/TemplateManage.tsx` — 工具栏新增 AI 区域按钮
|
||
**目标文件**:`src/pages/TemplateManage.tsx`
|
||
**修改内容**:
|
||
- import 中增加 `Bot` from `lucide-react`
|
||
- 新增 `insertAiRegion` 函数:prompt 输入名称 → 重名检查(`querySelector([data-ai-id="..."])`)→ `execCommand('insertHTML')` 插入标准 `ai-region` DOM
|
||
- 工具栏 JSX 中在 `ImageIcon` 右侧新增蓝色 `Bot` 按钮
|
||
- 插入后调用 `saveTemplateContent()`
|
||
|
||
### 步骤 4:`src/pages/ReportEditor.tsx` — 工具栏 + activeTab 扩展
|
||
**目标文件**:`src/pages/ReportEditor.tsx`
|
||
**修改内容**:
|
||
- import 中增加 `Bot`, `Mic`, `MicOff`, `ImagePlus`, `Sparkles`, `Send` 等图标
|
||
- `activeTab` 类型扩展为 `'info' | 'video' | 'ai'`
|
||
- 工具栏 JSX 中在 `ImageIcon` 右侧新增蓝色 `Bot` 按钮及 `insertAiRegion` 函数
|
||
- 右侧 Tab 按钮区新增 "AI撰写" 切换按钮
|
||
|
||
### 步骤 5:`src/pages/ReportEditor.tsx` — AI 核心状态与逻辑
|
||
**目标文件**:`src/pages/ReportEditor.tsx`
|
||
**修改内容**:
|
||
- 新增 State:
|
||
- `chatInput`, `chatMessages`, `isGenerating`
|
||
- `aiSelectedFrames`, `aiTargetRegion`, `aiModifyEnabled`
|
||
- `isListening`, `aiUploadedImages`, `speechRecognitionRef`
|
||
- `quickPrompts`, `isEditingPrompts`
|
||
- `diffModal`
|
||
- 新增函数:
|
||
- `checkAiRegions()`: 扫描编辑器内所有 `.ai-region` 返回 id/title 列表
|
||
- `toggleListening()`: Web Speech API 语音识别
|
||
- `handleAIGenerate(text)`: 组装多模态 message → Fetch 调用 Kimi → 解析 JSON → 更新聊天 → 触发 Diff
|
||
- `confirmAiInjection(newHtml, regionId)`: 注入 HTML → 视觉高亮动画 → saveDraft
|
||
- 注意:所有 DOM 修改后必须同步 `contentRef.current = editorRef.current.innerHTML` 并 `saveDraftToStorage()`
|
||
|
||
### 步骤 6:`src/pages/ReportEditor.tsx` — AI 面板 UI
|
||
**目标文件**:`src/pages/ReportEditor.tsx`
|
||
**修改内容**:
|
||
- 在 `activeTab === 'ai'` 分支中渲染完整面板:
|
||
- 顶部:聊天气泡区(user 右蓝 / model 左白)
|
||
- 中部:区域锚定下拉 + "允许修改正文" checkbox
|
||
- 中下部:关键帧缩略图多选 + 本地图片预览
|
||
- 底部:快捷指令胶囊 + 多行输入框(带 Mic / ImagePlus / Send 按钮)
|
||
- 在最外层新增 `diffModal` 弹窗 DOM(左右对比、可编辑右侧、确认/放弃按钮)
|
||
|
||
### 步骤 7:`src/index.css` — AI 区域打印样式
|
||
**目标文件**:`src/index.css`
|
||
**修改内容**:
|
||
- `@media print` 中隐藏 `.ai-region` 的蓝色边框和标签,或将其设为透明/灰色,避免打印时显示编辑态样式
|
||
|
||
## 3. 依赖关系
|
||
- 步骤 1(types)必须在步骤 2/3/4/5/6 之前
|
||
- 步骤 3(TemplateManage)和步骤 4-6(ReportEditor)可并行
|
||
- 步骤 2(SystemSettings)可独立并行
|
||
- 步骤 7(CSS)在最后执行
|
||
|
||
## 4. 风险预案
|
||
- 若 Kimi API 调用失败,catch 中向聊天列表追加 `[系统错误]` 消息,不阻断页面
|
||
- 若 `JSON.parse` 失败,尝试用正则提取 JSON 子串后再解析,仍失败则展示原始文本
|
||
- 若用户浏览器不支持 Web Speech API,点击麦克风时 alert 提示并优雅降级
|
||
- 若 `ai-region` 被用户手动删除,下拉选择器实时扫描会同步更新为空
|