From d5529a4998779dd175fbf612a4864013e04f156b Mon Sep 17 00:00:00 2001 From: Administrator Date: Sat, 18 Apr 2026 23:44:17 +0800 Subject: [PATCH] =?UTF-8?q?2026-04-18-23-39-35=20-=20=E5=9B=9B=E9=A1=B9?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E4=B8=8B=E5=88=92=E7=BA=BF=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E3=80=81PDF=E6=96=87=E4=BB=B6=E5=90=8D=E3=80=81?= =?UTF-8?q?=E9=97=B4=E8=B7=9D=E7=BC=A9=E7=B4=A7=E3=80=81=E8=A1=A8=E5=8D=95?= =?UTF-8?q?=E9=80=86=E5=90=91=E8=81=94=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ReportEditor.tsx | 28 ++++-- src/types.ts | 4 +- src/utils/defaultContent.ts | 2 +- src/utils/print.ts | 7 +- 工程分析/实现方案-2026-04-18-23-39-35.md | 108 +++++++++++++++++++++++ 工程分析/测试方案-2026-04-18-23-39-35.md | 64 ++++++++++++++ 工程分析/需求分析-2026-04-18-23-39-35.md | 34 +++++++ 7 files changed, 236 insertions(+), 11 deletions(-) create mode 100644 工程分析/实现方案-2026-04-18-23-39-35.md create mode 100644 工程分析/测试方案-2026-04-18-23-39-35.md create mode 100644 工程分析/需求分析-2026-04-18-23-39-35.md diff --git a/src/pages/ReportEditor.tsx b/src/pages/ReportEditor.tsx index 2b79c2b..5bdeca1 100644 --- a/src/pages/ReportEditor.tsx +++ b/src/pages/ReportEditor.tsx @@ -55,6 +55,24 @@ export default function ReportEditor() { const [activeTab, setActiveTab] = useState<'info' | 'video'>('info'); const [activeFieldKey, setActiveFieldKey] = useState(null); + + useEffect(() => { + if (!editorRef.current) return; + const allFields = editorRef.current.querySelectorAll('.field-value'); + allFields.forEach(el => { + (el as HTMLElement).style.backgroundColor = '#f8fafc'; + (el as HTMLElement).style.boxShadow = 'none'; + }); + if (activeFieldKey) { + const targetEl = editorRef.current.querySelector(`.field-value[data-bind="${activeFieldKey}"]`) as HTMLElement; + if (targetEl) { + targetEl.style.backgroundColor = '#eff6ff'; + targetEl.style.boxShadow = '0 0 0 2px #3b82f6'; + targetEl.scrollIntoView({ behavior: 'smooth', block: 'center' }); + } + } + }, [activeFieldKey]); + const [multiSelectOptions, setMultiSelectOptions] = useState>({ surgeon: ['张医生', '李医生', '王医生'], assistant: ['赵医生', '钱医生', '孙医生'], @@ -1525,7 +1543,7 @@ export default function ReportEditor() { if (field.type === 'text' || field.type === 'date') { const inputType = field.type === 'date' ? 'date' : 'text'; return ( -
f2.visibleInForm && f2.type === 'text' && f2.isSystemLocked).length > 1 && (field.key === 'patientName' || field.key === 'hospitalId') ? 'flex-1 space-y-1' : 'space-y-1'} p-2 -mx-2 rounded-xl transition-all duration-300 ${activeFieldKey === field.key ? 'bg-blue-50 ring-1 ring-accent shadow-sm' : ''}`}> +
setActiveFieldKey(field.key)} className={`${field.category === '填空' && formFields.filter(f2 => f2.visibleInForm && f2.type === 'text' && f2.isSystemLocked).length > 1 && (field.key === 'patientName' || field.key === 'hospitalId') ? 'flex-1 space-y-1' : 'space-y-1'} p-2 -mx-2 rounded-xl transition-all duration-300 ${activeFieldKey === field.key ? 'bg-blue-50 ring-1 ring-accent shadow-sm' : ''}`}> @@ -1545,7 +1563,7 @@ export default function ReportEditor() { const isOpen = openDropdown === field.key; const opts = field.options || (field.key === 'anesthesiaType' ? anesthesiaOptions : []); return ( -
+
setActiveFieldKey(field.key)} className={`space-y-1 select-dropdown-root relative p-2 -mx-2 rounded-xl transition-all duration-300 ${activeFieldKey === field.key ? 'bg-blue-50 ring-1 ring-accent shadow-sm' : ''}`}>
+
setActiveFieldKey(field.key)} className={`space-y-1 select-dropdown-root relative p-2 -mx-2 rounded-xl transition-all duration-300 ${activeFieldKey === field.key ? 'bg-blue-50 ring-1 ring-accent shadow-sm' : ''}`}>
+
setActiveFieldKey(field.key)} className={`space-y-1 p-2 -mx-2 rounded-xl transition-all duration-300 ${activeFieldKey === field.key ? 'bg-blue-50 ring-1 ring-accent shadow-sm' : ''}`}>
{ - return ` ×​`; + return ` ×​`; }; export const defaultReportContent = ` diff --git a/src/utils/print.ts b/src/utils/print.ts index 408f4fc..5d7ff2e 100644 --- a/src/utils/print.ts +++ b/src/utils/print.ts @@ -19,6 +19,7 @@ export const printDocument = (htmlContent: string, docTitle: string = '图文报 + ${docTitle} diff --git a/工程分析/实现方案-2026-04-18-23-39-35.md b/工程分析/实现方案-2026-04-18-23-39-35.md new file mode 100644 index 0000000..a376010 --- /dev/null +++ b/工程分析/实现方案-2026-04-18-23-39-35.md @@ -0,0 +1,108 @@ +# 实现方案 —— 2026-04-18-23-39-35 + +## 方案目标 +修复下划线功能、统一导出文件名、缩紧输入框间距、实现表单逆向联动。 + +## 需求 1:修复下划线勾选状态异常及打印失效 + +### 修改文件 1:`src/types.ts` +在 `DEFAULT_FORM_FIELDS` 数组中,为所有字段显式设置 `hasUnderline: false`(如果当前为 `true` 或未指定)。 + +### 修改文件 2:`src/pages/TemplateManage.tsx` +在编辑字段的回显逻辑中: +```ts +setEditFieldHasUnderline(field.hasUnderline === true); +``` +确保 `undefined` 时默认不勾选。 + +### 修改文件 3:`src/utils/print.ts` +恢复默认显示下划线的白名单机制: +```css +@media print { + .smart-field-wrapper .field-value { + border: none !important; + border-bottom: 1px solid #000 !important; + border-radius: 0 !important; + background: transparent !important; + padding: 0 2px 0px 2px !important; + } + .smart-field-wrapper .field-value.no-underline { + border-bottom: none !important; + } +} +``` + +## 需求 2:统一 PDF 和 JSON 导出文件名 + +### 修改文件:`src/utils/print.ts` +确保 `printDocument` 中: +1. 保存原始 `document.title` +2. 设置 `document.title = docTitle` +3. iframe HTML 中也写入 `${docTitle}` +4. 打印完成后恢复 `document.title` + +同时检查 `ReportEditor.tsx` 和 `ReportManage.tsx` 中调用 `printDocument` 时传入的 `docTitle` 是否与 JSON 文件名一致。 + +## 需求 3:缩紧 field-value 内文字间距 + +### 修改文件 1:`src/utils/defaultContent.ts` +```ts +// padding:0 4px → padding:0 2px +// margin:0 2px → margin:0 +// min-width:32px → min-width:24px +// 增加 text-align:center 让文字居中 +``` + +### 修改文件 2:`src/utils/print.ts` +同步修改打印样式中的 `.field-value`: +```css +.smart-field-wrapper .field-value { + min-width: 24px; + padding: 0; + margin: 0; + ... +} +``` + +## 需求 4:ReportEditor 表单逆向联动 + +### 修改文件:`src/pages/ReportEditor.tsx` + +1. **新增 useEffect 监听 activeFieldKey**: +```ts +useEffect(() => { + if (!editorRef.current) return; + const allFields = editorRef.current.querySelectorAll('.field-value'); + allFields.forEach(el => { + (el as HTMLElement).style.backgroundColor = '#f8fafc'; + (el as HTMLElement).style.boxShadow = 'none'; + }); + if (activeFieldKey) { + const targetEl = editorRef.current.querySelector(`.field-value[data-bind="${activeFieldKey}"]`) as HTMLElement; + if (targetEl) { + targetEl.style.backgroundColor = '#eff6ff'; + targetEl.style.boxShadow = '0 0 0 2px #3b82f6'; + targetEl.scrollIntoView({ behavior: 'smooth', block: 'center' }); + } + } +}, [activeFieldKey]); +``` + +2. **右侧表单添加 onFocus/onClick**: +在右侧表单字段容器的 `onClick` 中增加 `setActiveFieldKey(field.key)`,在 input/select 的 `onFocus` 中也增加 `setActiveFieldKey(field.key)`。 + +## 涉及文件及修改点 +| 文件 | 修改点 | +|------|--------| +| `src/types.ts` | DEFAULT_FORM_FIELDS 中 hasUnderline 设为 false | +| `src/pages/TemplateManage.tsx` | 编辑字段回显逻辑 | +| `src/utils/print.ts` | 打印下划线白名单机制;document.title 设置;field-value 间距 | +| `src/utils/defaultContent.ts` | smartField padding/margin 缩小;text-align:center | +| `src/pages/ReportEditor.tsx` | activeFieldKey useEffect 高亮滚动;表单 onFocus 联动 | +| `src/pages/ReportManage.tsx` | 检查导出文件名一致性 | + +## 风险与注意事项 +1. `DEFAULT_FORM_FIELDS` 修改后,现有用户的 localStorage 中已保存的字段配置不会自动更新,需要手动编辑或清除 `formFieldsConfig` 才能看到效果。 +2. `activeFieldKey` 的 useEffect 直接操作 DOM style,需要确保在组件卸载或切换 tab 时清除高亮。 +3. 缩小 padding/margin 后,需要验证在表格单元格(td)内的显示是否正常。 +4. 打印样式中 `.field-value.no-underline` 的优先级必须高于基础 `.field-value` 规则。 diff --git a/工程分析/测试方案-2026-04-18-23-39-35.md b/工程分析/测试方案-2026-04-18-23-39-35.md new file mode 100644 index 0000000..90b0cdb --- /dev/null +++ b/工程分析/测试方案-2026-04-18-23-39-35.md @@ -0,0 +1,64 @@ +# 测试方案 —— 2026-04-18-23-39-35 + +## 测试目标 +验证下划线修复、文件名统一、间距缩紧和双向联动的正确性。 + +## 测试用例 + +### TC-1:基础字段默认不勾选下划线 +**前置条件**:进入模板管理 → 字段管理。 +**步骤**: +1. 点击「患者姓名」或「住院号」的编辑按钮。 +**预期结果**:「打印时显示下划线」复选框默认未勾选。 + +### TC-2:勾选下划线后打印生效 +**前置条件**:某个字段已勾选「打印时显示下划线」。 +**步骤**: +1. 在编辑器中插入该字段。 +2. 点击打印预览。 +**预期结果**:该字段显示下划线,且下划线紧贴文字底部。 + +### TC-3:未勾选下划线打印不显示 +**前置条件**:某个字段未勾选下划线。 +**步骤**: +1. 在编辑器中插入该字段。 +2. 点击打印预览。 +**预期结果**:该字段不显示下划线。 + +### TC-4:PDF 与 JSON 文件名一致 +**前置条件**:报告已填写完整信息。 +**步骤**: +1. 分别点击「导出 PDF」和「导出 JSON」。 +**预期结果**:两个文件的文件名前缀完全一致(如 `图文报告-腹腔镜胆囊切除术报告-未知-无号-2026-04-18T23-28`)。 + +### TC-5:field-value 间距缩紧 +**前置条件**:模板中有 field-value 字段。 +**步骤**: +1. 观察字段框内文字与边框的距离。 +2. 打印预览中观察间距。 +**预期结果**:文字紧贴边框,左右无明显空白。 + +### TC-6:表单逆向联动 +**前置条件**:ReportEditor 已加载默认模板。 +**步骤**: +1. 点击右侧「基本信息」中「手术名称」输入框。 +2. 观察中间模板区域。 +**预期结果**: +- 中间模板中「手术名称」字段高亮显示(蓝色背景 + 蓝色描边)。 +- 页面平滑滚动到该字段位置(视野中央)。 + +### TC-7:正向联动仍正常 +**前置条件**:ReportEditor 已加载默认模板。 +**步骤**: +1. 点击中间模板中的「患者姓名」字段。 +**预期结果**: +- 右侧表单中高亮「患者姓名」输入框。 +- 右侧滚动到该输入框位置。 + +## 回归测试 +- 确保字段插入、编辑、删除功能正常。 +- 确保打印样式正常,所有字段类型显示正确。 +- 确保视频分析、图片占位符功能正常。 + +## 测试通过标准 +所有用例均通过,无控制台报错,下划线逻辑正确,双向联动流畅。 diff --git a/工程分析/需求分析-2026-04-18-23-39-35.md b/工程分析/需求分析-2026-04-18-23-39-35.md new file mode 100644 index 0000000..71c375f --- /dev/null +++ b/工程分析/需求分析-2026-04-18-23-39-35.md @@ -0,0 +1,34 @@ +# 需求分析 —— 2026-04-18-23-39-35 + +## 需求来源 +用户在实际使用中发现下划线功能异常、导出文件名不一致、输入框间距过大、以及表单缺乏逆向联动等问题。 + +## 需求概述 + +### 需求 1:修复下划线勾选状态异常及打印失效 +1. **默认勾选未取消**:`DEFAULT_FORM_FIELDS` 中的基础字段(如患者姓名、住院号)默认 `hasUnderline` 仍为 `true` 或未指定,导致编辑弹窗中仍显示为勾选状态。 +2. **打印失效**:`print.ts` 中 `@media print` 的样式逻辑有问题,导致无论是否勾选「打印时显示下划线」,打印时都不显示下划线。 +3. **下划线紧贴文字**:用户希望勾选后的下划线紧贴文字底部。 + +### 需求 2:统一 PDF 和 JSON 导出文件名 +当前 PDF 导出文件名与 JSON 不一致(缺少时间后缀或格式不同),希望两者完全一致。 + +### 需求 3:缩紧 field-value 内文字间距 +`.field-value` 当前有 `padding:0 4px; margin:0 2px`,导致框内文字偏右,打印时左右间距过大。希望缩小 padding 和 margin。 + +### 需求 4:ReportEditor 表单逆向联动 +当前实现了「点击中间模板字段 → 右侧表单高亮滚动」,但反向逻辑缺失:点击右侧表单输入框时,中间模板内的对应 `.field-value` 不会高亮,也不会滚动到对应位置。 + +## 涉及文件 +- `src/types.ts`(需求 1) +- `src/pages/TemplateManage.tsx`(需求 1) +- `src/utils/print.ts`(需求 1、2、3) +- `src/utils/defaultContent.ts`(需求 3) +- `src/pages/ReportEditor.tsx`(需求 2、4) +- `src/pages/ReportManage.tsx`(需求 2) + +## 需求影响范围 +- 字段默认配置数据 +- 打印样式逻辑 +- 输入框内边距/外边距 +- 编辑器双向联动交互