refactor: unify image-placeholder across editors and remove image field type

- Remove surgeonSignature and hospitalLogo from DEFAULT_FORM_FIELDS.
- Replace logo and signature in default template with inline image-placeholder spans.
- Enhance insertImage() in both editors with prompt for max-width/height (px).
- Abbreviate placeholder text to '插入图片' when width < 80px.
- Force inline insertion using display:inline-flex + vertical-align:middle.
- Port image-source picker modal from ReportEditor to TemplateManage.
- Remove legacy triggerPlaceholderUpload direct upload logic.
This commit is contained in:
2026-04-17 19:34:03 +08:00
parent 0c57409c59
commit 5fee3352c1
8 changed files with 432 additions and 57 deletions

View File

@@ -610,3 +610,35 @@ ange.insertNode(fragment) 精确插入到 Range 位置;
- 图片字段与普通文本字段的 DOM 结构差异大,插入逻辑需要按 type 分支。
- 编辑器与侧边栏联动建议使用 `scrollIntoView` + 临时 CSS 类,避免复杂的状态同步。
- 新增 localStorage key 时应提供合理的默认值或降级处理。
---
## 记录 23图片占位符体系重构与双端统一
**A. 具体问题**
1. `template-manage` 的"插入字段"中仍存在"图片"分类手术者签名、医院Logo用户认为不再需要。
2. 插入图片占位符时无法自定义默认宽高,且使用 `<div>` 导致强制换行。
3. 占位符框太小时"插入/点击放置图片"文字显示不全。
4. 默认模板中签名和 Logo 的结构不统一(一个是 `smartField`,一个是 `div.image-placeholder`)。
5. `template-manage` 点击图片占位符直接调起本地文件选择器,与 `report-editor` 的三选一弹窗行为不一致。
**B. 问题产生原因**
1. `DEFAULT_FORM_FIELDS` 仍包含 `surgeonSignature` 和 `hospitalLogo`。
2. 两端编辑器的 `insertImage()` 使用块级 `<div>` 插入,未提供尺寸 prompt。
3. 占位符提示文本固定为长文本,未根据容器宽度做缩写适配。
4. `TemplateManage` 的 placeholder 点击事件直接调用 `triggerPlaceholderUpload()`,缺少与 `ReportEditor` 一致的弹窗组件。
**C. 解决问题方法**
1. **清理图片字段**:从 `DEFAULT_FORM_FIELDS` 和 `types.ts` 中移除 `surgeonSignature` 和 `hospitalLogo`;在 `TemplateManage.tsx` 的插入字段/字段管理/新增字段表单中彻底移除"图片"分类。
2. **统一默认模板**:在 `defaultContent.ts` 中将 Logo 和签名均替换为 `<span class="image-placeholder" style="display:inline-flex;...">`。
3. **改造 insertImage()**:在 `TemplateManage.tsx` 和 `ReportEditor.tsx` 中,插入前通过 `prompt` 获取最大宽度/高度px生成带 `max-width/max-height` 的 `<span>` 行内占位符;提示文字中附加"正文一行文字高度约为 20 像素左右"。
4. **文本自适应**:根据 prompt 输入的宽度决定提示文字:宽度 < 80px 时显示"插入图片",否则显示"插入/点击放置图片"。
5. **统一弹窗行为**:将 `ReportEditor` 的 `imagePickerOpen` / `imagePickerTarget` / `fillPlaceholderSrc` 逻辑完整移植到 `TemplateManage`;删除旧的 `triggerPlaceholderUpload` 直接上传逻辑;两端点击图片占位符均弹出"本地上传 / 我的签名 / 系统素材"三选一弹窗。
6. **优化填充样式**`fillPlaceholderSrc` 中给 `<img>` 增加 `max-width:100%; max-height:100%; object-fit:contain;`,避免撑破设置了固定尺寸的占位符。
**D. 经验与教训总结**
- 当从字段体系中彻底移除某一分类时,需要同时清理:`DEFAULT_FORM_FIELDS`、UI 渲染数组、新增表单 options、以及可能残留的分类判断逻辑如编辑字段时显示 options 输入框的条件)。
- 在 `contentEditable` 中实现"同行插入"必须使用行内元素(`<span>`)并显式设置 `display:inline-flex` + `vertical-align:middle`;块级 `<div>` 即使通过 CSS 改 display 也可能因浏览器 execCommand 修正导致换行。
- 跨页面/跨编辑器的一致交互(如图片选择弹窗)应抽取为可复用逻辑或至少保持代码结构一致,避免用户在不同页面产生认知割裂。
- `prompt` 虽不是最优雅的用户交互,但在工具栏快捷操作中是一种零依赖、快速落地的方案;若后续需要更复杂交互,可再替换为 Modal 组件。