Files
Mdeical_Sur_Report/工程分析/实现方案-2026-04-16-18-51-06.md

119 lines
4.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-16-18-51-06
## 根因分析
`ReportEditor.tsx` 中使用了 `stateRef.current` 作为「草稿自动保存」的数据来源。组件卸载时,`saveDraftToStorage()` 会将 `stateRef.current` 写入 `localStorage`
但在页面初始化(`useEffect``useLayoutEffect`)从已保存报告或 draft 恢复数据时,仅通过 `setState` 更新了 React state**没有同步更新 `stateRef.current` 中的 `videos``capturedFrames` 字段**。
这导致:
1. 用户首次进入 `/report-editor` 时,数据从 localStorage 正确恢复;
2. 用户离开页面时,`stateRef.current` 仍保存着初始的空数组;
3. 组件卸载触发的 `saveDraftToStorage()` 用空数组覆盖了 draft
4. 用户再次返回 `/report-editor` 时,系统优先读取被覆盖后的 draft导致视频分析数据全部丢失。
## 修改文件清单
| 文件 | 修改类型 | 说明 |
|------|---------|------|
| `src/pages/ReportEditor.tsx` | 修改 | 在 4 处数据恢复逻辑后追加 `stateRef.current` 同步赋值 |
## 具体代码变更
### 修改点 1初始化 useEffect — 从 draft 恢复已有报告(约第 128 行后)
在已有代码:
```tsx
setLoadedTemplateId(draft.loadedTemplateId || '');
stateRef.current = { ...stateRef.current, loadedTemplateId: draft.loadedTemplateId || '' };
```
**追加同步**
```tsx
stateRef.current = {
...stateRef.current,
reportData: draft.reportData,
videos: draft.videos,
capturedFrames: draft.capturedFrames,
loadedTemplateId: draft.loadedTemplateId || ''
};
```
### 修改点 2初始化 useEffect — 从已保存报告found恢复约第 146 行后)
在设置完 `contentLoadedRef.current = true;` 之后,**追加同步**
```tsx
stateRef.current = {
...stateRef.current,
reportData: found,
videos: found.videos || [],
capturedFrames: found.capturedFrames || []
};
```
### 修改点 3初始化 useEffect — 从 draft 恢复新建报告(约第 176 行后)
与修改点 1 类似,在 `setLoadedTemplateId(draft.loadedTemplateId || '');` 之后,**追加同步**
```tsx
stateRef.current = {
...stateRef.current,
reportData: draft.reportData,
videos: draft.videos,
capturedFrames: draft.capturedFrames,
loadedTemplateId: draft.loadedTemplateId || ''
};
```
### 修改点 4useLayoutEffect 安全网 — 从 draft 恢复已有报告(约第 677 行后)
`setLoadedTemplateId(draft.loadedTemplateId || '');` 之后,**追加同步**
```tsx
stateRef.current = {
...stateRef.current,
reportData: draft.reportData,
videos: draft.videos,
capturedFrames: draft.capturedFrames,
loadedTemplateId: draft.loadedTemplateId || ''
};
```
### 修改点 5useLayoutEffect 安全网 — 从已保存报告found恢复约第 692 行后)
`contentLoadedRef.current = true;` 之后,**追加同步**
```tsx
stateRef.current = {
...stateRef.current,
reportData: found,
videos: found.videos || [],
capturedFrames: found.capturedFrames || []
};
```
### 修改点 6useLayoutEffect 安全网 — 从 draft 恢复新建报告(约第 701 行后)
`setLoadedTemplateId(draft.loadedTemplateId || '');` 之后,**追加同步**
```tsx
stateRef.current = {
...stateRef.current,
reportData: draft.reportData,
videos: draft.videos,
capturedFrames: draft.capturedFrames,
loadedTemplateId: draft.loadedTemplateId || ''
};
```
## 风险点
| 风险 | 级别 | 应对措施 |
|------|------|---------|
| `stateRef` 仍可能在其他未覆盖路径中不同步 | 低 | 已检查所有数据恢复入口init effect + layout effect后续若新增恢复逻辑需保持同步习惯 |
| `found.videos` / `found.capturedFrames` 为 undefined | 低 | 代码中使用 `|| []` 做防御性处理 |
## 回滚策略
本次修改仅增加 `stateRef.current` 的同步赋值语句,不涉及删除或重构现有逻辑。如出现异常,可直接 `git revert` 回滚。
---
**⚠️ 请审核以上方案,确认无误后回复「确认」或提出修改意见,我将进入测试方案编写阶段。**