# 实现方案 —— 2026-04-18-16-55-47 ## 方案目标 实现 report-editor 中正文与侧边栏的点击联动、字段动态排序、以及默认模板的手术图片表格替换。 ## 需求 1:点击 field-value 联动右侧基本信息 ### 实现步骤 1. **修改 `handleEditorClick`**:在 `ReportEditor.tsx` 的 `handleEditorClick` 函数中,增加对 `.field-value` 的点击捕获。 - 通过 `e.target.closest('.field-value')` 获取被点击的 field-value 元素。 - 读取其 `data-bind` 属性值(如 `patientName`)。 2. **切换 Tab**:调用 `setActiveTab('info')` 将右侧面板切回「基本信息」。 3. **聚焦与滚动**: - 为右侧表单中的每个输入组件增加 `id={\`input-\${field.key}\`}`。 - 使用 `setTimeout` 等待 React DOM 渲染完成后,通过 `document.getElementById(\`input-\${bindKey}\`)` 获取对应元素。 - 调用 `scrollIntoView({ behavior: 'smooth', block: 'center' })` 并 `focus()`。 ## 需求 2:右侧基本信息字段按正文出现顺序动态排序 ### 实现步骤 1. **提取正文字段顺序**: - 使用 `contentRef.current`(当前编辑器 HTML 字符串)或 `editorRef.current?.innerHTML`。 - 对 `formFields.filter(f => f.visibleInForm)` 中的每个非置顶字段,计算 `data-bind="${field.key}"` 在 HTML 中的首次出现位置(`indexOf`)。 2. **排序策略**: - **置顶组**:`const topKeys = ['patientName', 'hospitalId', 'title'];`,按此固定顺序排列。 - **正文组**:非置顶字段,按 `indexOf` 升序排列(越早出现越靠前)。 - **末尾组**:正文中未出现的字段(`indexOf === -1`),统一排在最后,保持原有相对顺序。 3. **渲染表单**:将排序后的字段数组直接用于右侧表单 `.map()` 渲染。 ### 性能优化 - 使用 `useMemo` 缓存排序结果,仅在 `formFields` 或编辑器内容变化时重新计算。 - 排序逻辑放在 `useMemo` 中,避免每次渲染重复计算。 ## 需求 3:替换默认手术图片说明表格 ### 实现步骤 1. 定位 `src/utils/defaultContent.ts` 中的 `defaultReportContent`。 2. 找到 `` 注释所在的 `