3.3 KiB
3.3 KiB
实现方案 —— 2026-04-18-16-55-47
方案目标
实现 report-editor 中正文与侧边栏的点击联动、字段动态排序、以及默认模板的手术图片表格替换。
需求 1:点击 field-value 联动右侧基本信息
实现步骤
- 修改
handleEditorClick:在ReportEditor.tsx的handleEditorClick函数中,增加对.field-value的点击捕获。- 通过
e.target.closest('.field-value')获取被点击的 field-value 元素。 - 读取其
data-bind属性值(如patientName)。
- 通过
- 切换 Tab:调用
setActiveTab('info')将右侧面板切回「基本信息」。 - 聚焦与滚动:
- 为右侧表单中的每个输入组件增加
id={\input-${field.key}`}`。 - 使用
setTimeout等待 React DOM 渲染完成后,通过document.getElementById(\input-${bindKey}`)` 获取对应元素。 - 调用
scrollIntoView({ behavior: 'smooth', block: 'center' })并focus()。
- 为右侧表单中的每个输入组件增加
需求 2:右侧基本信息字段按正文出现顺序动态排序
实现步骤
- 提取正文字段顺序:
- 使用
contentRef.current(当前编辑器 HTML 字符串)或editorRef.current?.innerHTML。 - 对
formFields.filter(f => f.visibleInForm)中的每个非置顶字段,计算data-bind="${field.key}"在 HTML 中的首次出现位置(indexOf)。
- 使用
- 排序策略:
- 置顶组:
const topKeys = ['patientName', 'hospitalId', 'title'];,按此固定顺序排列。 - 正文组:非置顶字段,按
indexOf升序排列(越早出现越靠前)。 - 末尾组:正文中未出现的字段(
indexOf === -1),统一排在最后,保持原有相对顺序。
- 置顶组:
- 渲染表单:将排序后的字段数组直接用于右侧表单
.map()渲染。
性能优化
- 使用
useMemo缓存排序结果,仅在formFields或编辑器内容变化时重新计算。 - 排序逻辑放在
useMemo中,避免每次渲染重复计算。
需求 3:替换默认手术图片说明表格
实现步骤
- 定位
src/utils/defaultContent.ts中的defaultReportContent。 - 找到
<!-- 手术图片说明表格 -->注释所在的<table>区域。 - 替换为用户提供的 HTML 代码:
- 2 行 × 3 列布局
- 每格包含
.image-placeholder(表格内模式:<div>块级容器,width:100%; height:100%; max-width:200px; max-height:200px;) - 每格底部含图注(图A~图F)
- 保留
data-placeholder="true"和contenteditable="false"
- 清理复制时产生的冗余内联样式(如
background-image: initial等),保留功能必需的样式。
涉及文件及修改点
| 文件 | 修改点 |
|---|---|
src/pages/ReportEditor.tsx |
handleEditorClick 增加 field-value 点击捕获;表单渲染增加 id;右侧字段排序逻辑 |
src/utils/defaultContent.ts |
替换手术图片说明表格 HTML |
风险与注意事项
contentRef.current在组件首次挂载前可能为空,排序逻辑需做空值保护。setActiveTab后 DOM 切换有短暂延迟,scrollIntoView需包裹在setTimeout中。- 默认模板替换后,需验证新建报告时表格渲染是否正常、占位符点击事件是否生效。
- 置顶字段的
key名称需与DEFAULT_FORM_FIELDS中严格一致。