# 实现方案 — 2026-04-17-19-26-17 ## 变更文件 1. `src/types.ts` 2. `src/utils/defaultContent.ts` 3. `src/pages/TemplateManage.tsx` 4. `src/pages/ReportEditor.tsx` --- ## 一、types.ts 修改 从 `DEFAULT_FORM_FIELDS` 中移除以下两个字段: - `surgeonSignature` - `hospitalLogo` 同时从 `FieldType` 中移除 `'image'`(因为图片不再作为可插入的字段类型,仅作为占位符存在)。若移除 `'image'` 会导致大量类型错误,也可保留类型但不在 UI 中暴露。为最小侵入,保留 `'image'` 类型但不再在 `DEFAULT_FORM_FIELDS` 中使用。 实际执行:删除 `DEFAULT_FORM_FIELDS` 中的最后两项(`surgeonSignature` 和 `hospitalLogo`)。 --- ## 二、defaultContent.ts 修改 ### 2.1 医院Logo 将原有的 `div.image-placeholder` 替换为 `span.image-placeholder`(保持居中): ```html
×
``` ### 2.2 手术者签名 将 `手术者签名:${smartField('surgeonSignature')}` 替换为: ```html手术者签名:×
``` --- ## 三、TemplateManage.tsx 修改 ### 3.1 移除"图片"分类暴露 - `expandedCategories` 初始值从 `['填空','单选','多选','时间','图片']` 改为 `['填空','单选','多选','时间']`。 - "插入字段"Tab 的遍历数组从 `['填空','单选','多选','时间','图片']` 改为 `['填空','单选','多选','时间']`。 - "字段管理"Tab 的遍历数组同样移除 `'图片'`。 - 新增字段表单的 category select 中移除 ``。 - type select 的条件渲染中移除图片相关的 option。 ### 3.2 改造 insertImage() 将现有的 `insertImage()` 替换为: ```typescript const insertImage = () => { const widthStr = prompt('请输入占位符最大宽度 (px),留空无限制:\n(提示:正文一行文字高度约为 20 像素左右)', ''); const heightStr = prompt('请输入占位符最大高度 (px),留空无限制:', ''); const width = parseInt(widthStr || '0'); const height = parseInt(heightStr || '0'); let styleStr = 'display:inline-flex;align-items:center;justify-content:center;border:1px dashed #cbd5e1;background:#f8fafc;vertical-align:middle;margin:0 4px;cursor:pointer;'; if (width > 0) styleStr += ` max-width:${width}px;`; if (height > 0) styleStr += ` max-height:${height}px;`; if (!width && !height) styleStr += ' padding:8px 16px;'; const showShortText = width > 0 && width < 80; const hintText = showShortText ? '插入图片' : '插入/点击放置图片'; const id = 'ph_' + Date.now(); const html = `×`; editorRef.current?.focus(); restoreSelection(); pushHistory(); execCmd('insertHTML', html); }; ``` ### 3.3 统一图片源选择弹窗 从 `ReportEditor.tsx` 复用以下逻辑到 `TemplateManage.tsx`: - 新增状态:`imagePickerOpen`、`imagePickerTarget`、`imageAssets`(已存在)。 - 新增 `fillPlaceholderSrc` 函数。 - 修改 `handleEditorClick` 中的 placeholder 点击逻辑: ```typescript if (!placeholder.classList.contains('has-image')) { e.preventDefault(); e.stopPropagation(); setImagePickerTarget(placeholder); setImagePickerOpen(true); } ``` - 删除原有的 `triggerPlaceholderUpload` 函数及其直接调用。 - 在 JSX 底部(`isModalOpen` 弹窗之后)新增 `imagePickerOpen` 弹窗组件(与 ReportEditor 完全一致)。 ### 3.4 清理删除后的重置逻辑 当 placeholder 被删除(点击 × 后)时,重置为: ```html × ``` 同时保留原有内联样式(避免把 `inline-flex` 等样式清掉)。 --- ## 四、ReportEditor.tsx 修改 ### 4.1 改造 insertImage() 与 TemplateManage 保持一致: ```typescript const insertImage = () => { editorRef.current?.focus(); const widthStr = prompt('请输入占位符最大宽度 (px),留空无限制:\n(提示:正文一行文字高度约为 20 像素左右)', ''); const heightStr = prompt('请输入占位符最大高度 (px),留空无限制:', ''); const width = parseInt(widthStr || '0'); const height = parseInt(heightStr || '0'); let styleStr = 'display:inline-flex;align-items:center;justify-content:center;border:1px dashed #cbd5e1;background:#f8fafc;vertical-align:middle;margin:0 4px;cursor:pointer;'; if (width > 0) styleStr += ` max-width:${width}px;`; if (height > 0) styleStr += ` max-height:${height}px;`; if (!width && !height) styleStr += ' padding:8px 16px;'; const showShortText = width > 0 && width < 80; const hintText = showShortText ? '插入图片' : '插入/点击放置图片'; const id = 'ph_' + Date.now(); const html = `×`; execCmd('insertHTML', html); }; ``` ### 4.2 删除后重置逻辑 在 `handleEditorClick` 中,placeholder 删除后重置的 HTML 改为使用 `` 结构并保留内联样式: ```typescript placeholder.innerHTML = ` × `; ``` ### 4.3 fillPlaceholderSrc 保持兼容 已有 `fillPlaceholderSrc` 可继续使用,但建议填充的图片增加 `max-width: 100%; max-height: 100%; object-fit: contain;`。 --- ## 回滚策略 修改前最新提交为 `0c57409`。若失败可 `git reset --hard 0c57409`。 ## 无新增 npm 依赖