Files
Mdeical_Sur_Report/过往经验/实现方案-2026-04-16-20-33-12.md

91 lines
3.7 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-16-20-33-12
## 根因分析
`autoCaptureFrames``for` 循环内部,自动插入逻辑使用了:
```tsx
if ((settings.autoInsertDelay || 0) > 0) {
await new Promise<void>(r => setTimeout(r, (settings.autoInsertDelay || 0) * 1000));
}
```
`await` 会暂停整个 `for` 循环的执行,导致:
1. 关键帧摘取被强制暂停,等待延迟结束;
2. 所有帧必须一张一张串行处理,整体耗时 = 摘取时间 + 插入延迟 × 插入帧数;
3. 用户体验上感觉"卡顿"或"慢"。
## 修改文件清单
| 文件 | 修改类型 | 说明 |
|------|---------|------|
| `src/pages/ReportEditor.tsx` | 修改 | `autoCaptureFrames` 中自动插入逻辑改为 `setTimeout` 非阻塞执行 |
## 具体代码变更
### 变更:`autoCaptureFrames` 中的插入逻辑(约第 523-535 行)
**当前代码:**
```tsx
if (settings.autoInsertFrames && settings.autoInsertFrameIndices?.includes(i) && editorRef.current) {
if ((settings.autoInsertDelay || 0) > 0) {
await new Promise<void>(r => setTimeout(r, (settings.autoInsertDelay || 0) * 1000));
}
const emptyPlaceholder = editorRef.current.querySelector('.image-placeholder:not(.has-image)') as HTMLElement | null;
if (emptyPlaceholder) {
emptyPlaceholder.innerHTML = `...`;
emptyPlaceholder.classList.add('has-image');
}
}
```
**修改为:**
```tsx
if (settings.autoInsertFrames && settings.autoInsertFrameIndices?.includes(i)) {
const baseDelay = (settings.autoInsertDelay || 0) * 1000;
const insertOrderIndex = settings.autoInsertFrameIndices.indexOf(i);
const actualDelay = baseDelay > 0 ? baseDelay * (insertOrderIndex + 1) : 0;
setTimeout(() => {
if (!editorRef.current) return;
const emptyPlaceholder = editorRef.current.querySelector('.image-placeholder:not(.has-image)') as HTMLElement | null;
if (emptyPlaceholder) {
emptyPlaceholder.innerHTML = `
<span class="delete-btn" contenteditable="false">×</span>
<img src="${newFrame.dataUrl}" style="max-width: 100%; height: auto; display: block; margin: 0 auto;" draggable="false">
`;
emptyPlaceholder.classList.add('has-image');
contentRef.current = editorRef.current.innerHTML;
saveDraftToStorage();
}
}, actualDelay);
}
```
**效果:**
- `for` 循环全速运行,不再被插入延迟阻塞;
- 每张需要插入的帧按顺序延迟(第 1 张 delay第 2 张 2×delay...),避免同时插入;
- `setTimeout` 回调中实时查询 DOM 获取最新的空 placeholder
- 插入后同步 `contentRef.current` 并保存草稿。
### 附加变更:移除循环后的批量 `contentRef` 更新
当前代码在循环结束后:
```tsx
if (settings.autoInsertFrames && editorRef.current) {
contentRef.current = editorRef.current.innerHTML;
}
```
由于每个 `setTimeout` 回调内部已经单独更新 `contentRef` 和保存草稿,且循环结束时可能 `setTimeout` 尚未执行,这句批量更新既不及时也可能遗漏。建议**移除或保留不影响功能**。为简化逻辑,选择保留但无实质影响,因为非阻塞的 `setTimeout` 回调会各自负责自己的保存。
## 风险点
| 风险 | 级别 | 应对措施 |
|------|------|---------|
| `setTimeout` 回调执行时 placeholder 已被用户手动填充 | 低 | 回调中实时查询 `.image-placeholder:not(.has-image)`,找不到则跳过,不会覆盖用户内容 |
| 多张图片按顺序延迟插入时,用户快速离开页面 | 低 | 每次插入后都调用 `saveDraftToStorage()`,已插入的图片会被保存;未执行的 `setTimeout` 自然丢弃 |
## 回滚策略
修改范围极小,仅涉及 `autoCaptureFrames` 中的几行代码。如有异常可直接 revert。