Files
Mdeical_Sur_Report/工程分析/20260419_0333/实现方案.md
admin 854a00c2fa fix(editor): Checkbox点击失效 + AI全局上下文注入
- 将'允许修改正文'复选框从id/htmlFor绑定改为label直接包裹input,增加e.stopPropagation防止事件冒泡被拦截
- handleAIGenerate中新增editorRef.current.innerText作为全局上下文注入prompt
- currentHtml增加过滤​零宽字符
- 优化systemPrompt,明确告知大模型全局参考内容+目标区域源码的双信息源结构
2026-04-19 03:35:52 +08:00

98 lines
4.6 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.
# 实现方案
## 修改文件
- `src/pages/ReportEditor.tsx`
## 修改位置 1Checkbox 包裹结构(约 line 2258-2268
**原代码**
```tsx
<div className="flex items-center gap-1.5 shrink-0 pl-2 border-l border-slate-300">
<input
type="checkbox" id="aiModifyEnabled"
checked={aiModifyEnabled}
onChange={(e) => setAiModifyEnabled(e.target.checked)}
className="w-3.5 h-3.5 text-blue-600 rounded border-slate-300 focus:ring-blue-500 cursor-pointer"
/>
<label htmlFor="aiModifyEnabled" className="text-[11px] text-slate-600 cursor-pointer font-bold">
</label>
</div>
```
**新代码**
```tsx
<label className="flex items-center gap-1.5 shrink-0 pl-2 border-l border-slate-300 cursor-pointer">
<input
type="checkbox"
checked={aiModifyEnabled}
onChange={(e) => {
e.stopPropagation();
setAiModifyEnabled(e.target.checked);
}}
className="w-3.5 h-3.5 text-blue-600 rounded border-slate-300 focus:ring-blue-500 cursor-pointer"
/>
<span className="text-[11px] text-slate-600 font-bold">
</span>
</label>
```
**变更点**
1. 外层 `div` 改为 `label`,直接包裹 `input`
2. 移除 `id`/`htmlFor`,避免绑定冲突
3. `onChange` 增加 `e.stopPropagation()` 防止事件冒泡被拦截
4. `label` 文本改为 `span`
## 修改位置 2handleAIGenerate Prompt 构建(约 line 877-897
**原代码**
```tsx
const targetRegionEl = editorRef.current?.querySelector(`.ai-region[data-ai-id="${aiTargetRegion}"] .ai-content`) as HTMLElement | null;
const currentHtml = targetRegionEl ? targetRegionEl.innerHTML : '';
// ...
let promptText = `【医生指令】: ${text}`;
if (aiModifyEnabled && targetRegionEl) {
promptText = `【当前区域 HTML 源码】:\n${currentHtml}\n\n${promptText}`;
}
```
**新代码**
```tsx
const targetRegionEl = editorRef.current?.querySelector(`.ai-region[data-ai-id="${aiTargetRegion}"] .ai-content`) as HTMLElement | null;
const currentHtml = targetRegionEl ? targetRegionEl.innerHTML.replace(/&#8203;/g, '').trim() : '';
const globalContextText = editorRef.current?.innerText || '';
// ...
let promptText = `【全局手术报告参考内容】:\n${globalContextText}\n\n`;
if (aiModifyEnabled && targetRegionEl) {
promptText += `【你需要进行修改的目标区域 HTML 源码】:\n${currentHtml || '(当前区域为空)'}\n\n`;
}
promptText += `【医生指令】: ${text}`;
```
**变更点**
1. `currentHtml` 增加 `.replace(/&#8203;/g, '').trim()` 过滤零宽字符
2. 新增 `globalContextText` 读取整个编辑器的纯文本
3. `promptText` 重构:先放全局上下文,再放目标区域(如果存在),最后放医生指令
4. 目标区域为空时显示 `(当前区域为空)` 提示
## 修改位置 3System Prompt 优化(约 line 895-897
**原代码**
```tsx
const systemPrompt = aiModifyEnabled && targetRegionEl
? '你是一名专业的外科医生助理。你需要根据用户的指令及可能提供的截图,修改给定的 HTML 源码。\n重要指令你必须严格返回合法的 JSON 对象,绝对不要包含任何 Markdown 标记(如 ```json。\nJSON 格式如下:\n{ "reply": "简短的回复话术", "updatedHtml": "修改后的完整内部 HTML 代码" }'
: '你是一名专业的外科医生助理。请根据用户的指令和截图进行分析解答。\n重要指令你必须严格返回合法的 JSON 对象,绝对不要包含任何 Markdown 标记。\nJSON 格式如下:\n{ "reply": "你的分析和回答" }';
```
**新代码**
```tsx
const systemPrompt = aiModifyEnabled && targetRegionEl
? '你是一名专业的外科医生助理。我为你提供了当前手术报告的【全局参考内容】作为背景知识,以及你需要修改的【目标区域 HTML 源码】。\n请根据全局内容和用户的【医生指令】直接重写并输出目标区域的 HTML。\n重要指令你必须严格返回合法的 JSON 对象,绝对不要包含任何 Markdown 标记(如 ```json。\nJSON 格式如下:\n{ "reply": "简短的回复话术", "updatedHtml": "修改后的完整内部 HTML 代码" }'
: '你是一名专业的外科医生助理。请仔细阅读我提供的【全局手术报告参考内容】,并根据【医生指令】进行专业解答。\n重要指令严格返回合法的 JSON 对象。\nJSON 格式如下:\n{ "reply": "你的分析和回答" }';
```
**变更点**
1. 修改模式 systemPrompt 明确告知大模型有两个信息源:全局参考内容 + 目标区域源码
2. 非修改模式 systemPrompt 明确提到「全局手术报告参考内容」