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

3.3 KiB
Raw Blame History

实现方案 —— 2026-04-18-16-55-47

方案目标

实现 report-editor 中正文与侧边栏的点击联动、字段动态排序、以及默认模板的手术图片表格替换。

需求 1点击 field-value 联动右侧基本信息

实现步骤

  1. 修改 handleEditorClick:在 ReportEditor.tsxhandleEditorClick 函数中,增加对 .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. 找到 <!-- 手术图片说明表格 --> 注释所在的 <table> 区域。
  3. 替换为用户提供的 HTML 代码:
    • 2 行 × 3 列布局
    • 每格包含 .image-placeholder(表格内模式:<div> 块级容器,width:100%; height:100%; max-width:200px; max-height:200px;
    • 每格底部含图注图A~图F
    • 保留 data-placeholder="true"contenteditable="false"
  4. 清理复制时产生的冗余内联样式(如 background-image: initial 等),保留功能必需的样式。

涉及文件及修改点

文件 修改点
src/pages/ReportEditor.tsx handleEditorClick 增加 field-value 点击捕获;表单渲染增加 id;右侧字段排序逻辑
src/utils/defaultContent.ts 替换手术图片说明表格 HTML

风险与注意事项

  1. contentRef.current 在组件首次挂载前可能为空,排序逻辑需做空值保护。
  2. setActiveTab 后 DOM 切换有短暂延迟,scrollIntoView 需包裹在 setTimeout 中。
  3. 默认模板替换后,需验证新建报告时表格渲染是否正常、占位符点击事件是否生效。
  4. 置顶字段的 key 名称需与 DEFAULT_FORM_FIELDS 中严格一致。