# 实现方案 —— 2026-04-18-17-27-51
## 方案目标
修复 TemplateManage 静态占位符插入 Bug,重构默认报告模板顶部排版,修复 Logo 删除按钮交互。
## 需求 1:修复静态图片占位符插入不显示
### 问题根因
`TemplateManage.tsx` 中 `insertImage()` 使用 `document.execCommand('insertHTML', false, html)`。现代浏览器对含 `contenteditable="false"` 的复杂嵌套标签会自动修正/拍平,导致外层 `.image-placeholder` 容器丢失,DOM 仅剩零散子元素,视觉上不可见。
### 解决步骤
1. **定位 `insertImage` 函数**:找到 `TemplateManage.tsx` 中通过 `document.execCommand('insertHTML')` 插入占位符的逻辑。
2. **替换为 `Range.insertNode`**:
- 创建临时 `div`,将 HTML 字符串写入 `innerHTML`。
- 将子节点逐个移入 `DocumentFragment`。
- 获取当前 `Selection` 的 `RangeAt(0)`。
- 调用 `range.deleteContents()` 清空当前选区。
- 调用 `range.insertNode(fragment)` 精确插入。
- 将光标移动到插入内容之后。
3. **保持原有弹窗逻辑不变**:Modal 中的模式选择(frame/manual)、宽高输入等逻辑不受影响。
## 需求 2:重构默认报告模板排版
### 排版设计
#### 页眉(Logo + 医院名 + 标题)
使用 3 列 `
`(左 20%、中 60%、右 20%),中间列绝对居中:
- 左列:Logo 占位符(65×65,`data-mode="manual"`,`position:relative`)
- 中列:
- 第一行:14pt SimSun「西 安 交 通 大 学 第 一 附 属 医 院」(带 `border-bottom: 1px solid #000` 下划线,使用 `display: inline-block`)
- 第二行:16pt SimSun「手术记录」
- 右列:留空
#### 基本信息栏(下划线贯穿)
使用 `` 包裹一行:
- 11pt SimSun,不加粗
- 姓名、性别、年龄、科别、床号、住院号,用 ` ` 间隔
#### 诊断/手术信息(单行加粗)
每项独立 `
`:
- 12pt SimSun,`font-weight: bold`
- 手术日期、术前诊断、术中诊断、手术名称
#### 双列信息(两项一行,不加粗)
使用 `
`:
- 三行两列,每列 50%
- 12pt SimSun,不加粗
- 手术开始/终止时间、手术者/助手、麻醉师/麻醉方式
#### 手术步骤标题
- 12pt SimSun,`font-weight: bold`
- 「手术步骤、术中出现的情况及处理:」
#### 保留内容
- 5 条手术步骤段落文字(不变)
- 手术图片说明表格(需求 3 中已替换的最新 6 图格表格)
- 手术后情况段落(术后诊断、标本描述、病理检查、冰冻病理)
- 手术者签名占位符 + 撰写时间字段
### 涉及文件
`src/utils/defaultContent.ts` —— 完全重写 `defaultReportContent` 变量。
## 需求 3:修复顶部 Logo 删除按钮
### 解决步骤
在 `defaultContent.ts` 中 Logo 占位符的 `style` 属性中增加 `position: relative;`,使绝对定位的 `.delete-btn` 相对于占位符自身定位,而非向外层逃逸。
```html
```
## 涉及文件及修改点
| 文件 | 修改点 |
|------|--------|
| `src/pages/TemplateManage.tsx` | `insertImage` 中 `execCommand('insertHTML')` → `Range.insertNode` |
| `src/utils/defaultContent.ts` | 完全重写顶部排版;Logo 增加 `position:relative`;保留手术步骤/表格/底部段落 |
## 风险与注意事项
1. `Range.insertNode` 要求编辑器有有效光标/选区。若编辑器未聚焦或选区不在编辑器内,需增加保护逻辑(fallback 到 `editorRef.current.appendChild`)。
2. 默认模板重写后,需验证 `smartField()` 生成的所有字段占位符在新排版中是否正确渲染。
3. 打印时需确认新排版的下划线、表格边框在 `@media print` 中正常显示。
4. ` ` 分隔的基本信息栏在打印时可能换行,需测试实际打印效果。