diff --git a/clinical-web/src/components/document/DocumentPreviewDialog.vue b/clinical-web/src/components/document/DocumentPreviewDialog.vue index 66c94c8..207af7b 100644 --- a/clinical-web/src/components/document/DocumentPreviewDialog.vue +++ b/clinical-web/src/components/document/DocumentPreviewDialog.vue @@ -340,6 +340,8 @@ defineExpose({ getDocumentElement }) gap: 10px; padding: 12px 18px; overflow-y: auto; + /* 纸的 A4 最小高度用 `cqw` 表达,需要这里做容器查询上下文(见 utils/document-paper.ts) */ + container-type: inline-size; } /* 深灰 A4 舞台(原型 #mdPdfView):纸居中、带阴影,像在看 PDF */ @@ -353,9 +355,9 @@ defineExpose({ getDocumentElement }) 640px 配 A4 页边距只剩 446px 版心,而「四、用药信息」那张表的 min-content 就有 508px → 表宽溢出纸面、「药品名称」被挤成 28px 宽的竖排(已踩)。 现在统一走 :root 的 820px:版心 572px,与工作台/编辑器完全一致(所见即所签)。 - 外壳宽度由调用方给(已签署预览传 width=960 → 舞台内宽 912 ≥ 820)。 */ + 外壳宽度由调用方给(已签署预览传 width=960 → 舞台内宽 912 ≥ 820)。 + `flex: none` 已提到 `.doc-paper--a4` 上(纸在哪都不许被 flex 压缩)。 */ .preview-body--stage :deep(.doc-paper) { - flex: none; box-shadow: 0 6px 22px rgb(0 0 0 / 45%); } diff --git a/clinical-web/src/components/signing/SigningDocumentInteractive.vue b/clinical-web/src/components/signing/SigningDocumentInteractive.vue index 97d4259..8f1c2b0 100644 --- a/clinical-web/src/components/signing/SigningDocumentInteractive.vue +++ b/clinical-web/src/components/signing/SigningDocumentInteractive.vue @@ -207,14 +207,16 @@ defineExpose({ getDocumentElement }) } /* 纸桌:灰底 + 内滚,纸(一页 A4)居中摆在上面。 - 纸自己的比例与页边距走统一 A4 规格(.doc-paper--a4,见 utils/document-paper.ts), - 这里只留「桌子」—— 四周留一圈灰边,纸才不会顶到卡片边缘。 */ + 纸自己的 A4 最小高度与页边距走统一 A4 规格(.doc-paper--a4,见 utils/document-paper.ts), + 这里只留「桌子」—— 四周留一圈灰边,纸才不会顶到卡片边缘。 + `container-type` 是纸的 cqw 下限需要的容器查询上下文。 */ .sign-doc-body { flex: 1; min-height: 0; padding: 16px 20px 20px; overflow: auto; background: var(--bg); + container-type: inline-size; } .sign-doc-footer { diff --git a/clinical-web/src/styles/signing-document.css b/clinical-web/src/styles/signing-document.css index 45c689b..0fe749a 100644 --- a/clinical-web/src/styles/signing-document.css +++ b/clinical-web/src/styles/signing-document.css @@ -26,6 +26,8 @@ margin: 0 2px; color: var(--brand-d); font-weight: 600; + /* nowrap 是**编辑态胶囊**要的(原型 `.docfld` 原样):胶囊里是一句标签,不该折行。 + 渲染态在下面 `.filled` 里放开 —— 见那段注释,这是表格被挤坏的那个 bug 的根因。 */ white-space: nowrap; background: var(--brand-l); border: 1px dashed var(--brand); @@ -58,11 +60,19 @@ 所以框的颜色仍由 kind 决定(文本=--brand、签名=橙、勾选=绿)。 这圈框是文书上「这一处是系统管理的填写位」的唯一视觉标识:去掉它, HIS 带出的值(如「患者姓名 陈志强」)与正文文字就完全分不出来(2026-09-27 已踩)。 - 空值同理保留框,框内是一条 `.docfld-blank` 下划线。 */ + 空值同理保留框,框内是一条 `.docfld-blank` 下划线。 + + **`white-space: normal` 是必须的**(2026-09-27 修 bug):编辑态那句 nowrap 会把 + 渲染态的**整块取值**也变成不可折行 —— 勾选/选择类里两个长选项(如「是(带离机构外使用、 + 按单次门诊处方量管理)」)于是把表格的 min-content 撑到 508px。 + 纸宽 820(版心 572)时刚好放得下,**窗口一窄纸被压到 708(版心 494)就溢出**: + 表宽超出版心、「药品名称」那一列被压成 28px 宽的竖排(用户在窄窗口/高缩放下截的图)。 + 渲染态允许折行后 min-content 降到几十像素,纸再窄也放得下。 */ .docfld.filled { padding: 1px 2px; font-weight: 400; cursor: default; + white-space: normal; background: transparent; border-style: solid; } diff --git a/clinical-web/src/utils/document-paper.ts b/clinical-web/src/utils/document-paper.ts index 754d6b7..412fe3a 100644 --- a/clinical-web/src/utils/document-paper.ts +++ b/clinical-web/src/utils/document-paper.ts @@ -41,22 +41,32 @@ export const DOCUMENT_PAPER_CSS = ` --doc-paper-max-w: 820px; --doc-paper-pad-x: clamp(20px, 15.14%, 124px); --doc-paper-pad-y: clamp(16px, 6.83%, 56px); - /* 同一套比例,用**容器查询单位**表达:给「纸壳宽度 == 纸宽」的场景(编辑器)用。 - 那种场景下 cqw 精确等于纸宽的 1%,不需要 clamp 的两段兜底。 - ⚠️ 这三个与上面那三个必须同步改;只在有 container-type:inline-size 祖先的元素上用, - 否则 cqw 会退化成相对视口算。 */ - --doc-paper-pad-x-cqw: 15.14cqw; - --doc-paper-pad-y-cqw: 6.83cqw; - --doc-paper-min-h-cqw: 141.43cqw; /* 297 / 210 */ + /* A4 的**最小高度**:纸宽封顶 820 时就是 1159.71px(= 820 × 297/210); + 容器比 820 窄时纸也会跟着窄,那时按容器宽 × 297/210 算(cqw = 容器宽的 1%)。 + 两个分支在「容器 == 纸宽」处正好接上,所以 min() 挑哪个都对。 + + ⚠️ **不要用 aspect-ratio 表达这个下限**(2026-09-27 踩过): + aspect-ratio 会把纸的**高度定死**,正文比一页高时纸不长高、内容直接溢到纸外 —— + 实测深灰舞台那张纸卡在 1160px 而正文 1355px,用户看到的就是「纸张只显示一页」。 + min-height 只设下限,正文多了纸一定长高(编辑器的纸一直是这么写的,没出过问题)。 + + ⚠️ cqw 相对**最近的容器查询祖先**解析 —— 纸的父级必须带 + container-type: inline-size(probe-a4-paper.cjs 会逐处断言纵向不溢出)。 */ + --doc-paper-min-h: min(calc(var(--doc-paper-max-w) * 297 / 210), 141.43cqw); } -/* 一页 A4:比例 + 一般文书页边距。 - aspect-ratio 只是**下限** —— 内容超过一页时盒子会长高(实测过),不裁切、不内滚。 */ +/* 一页 A4:至少一页的高度 + 一般文书页边距。 + min-height 是**下限** —— 正文超过一页时纸长高,不裁切、不内滚、不溢到纸外。 + + flex: none 也是必须的(2026-09-27 踩过):预览弹窗的纸舞台是 flex 列容器且高度受限, + 纸作为 flex 子项默认 flex-shrink: 1 → 会被**压回 min-height**、正文又溢到纸外。 + flex: none(0 0 auto)让纸既不伸也不缩,高度 = max(正文, 一页 A4)。 */ .doc-paper--a4 { width: 100%; max-width: var(--doc-paper-max-w); margin: 0 auto; - aspect-ratio: 210 / 297; + flex: none; + min-height: var(--doc-paper-min-h); padding: var(--doc-paper-pad-y) var(--doc-paper-pad-x); } diff --git a/clinical-web/src/views/management/documents/components/editors/EditorWangPane.vue b/clinical-web/src/views/management/documents/components/editors/EditorWangPane.vue index 1f9e24d..ea4244a 100644 --- a/clinical-web/src/views/management/documents/components/editors/EditorWangPane.vue +++ b/clinical-web/src/views/management/documents/components/editors/EditorWangPane.vue @@ -302,16 +302,14 @@ onBeforeUnmount(() => { container-type: inline-size; } -/* 白纸:A4 比例(下限)+ 一般文书页边距,走统一 A4 规格(utils/document-paper.ts)。 +/* 白纸:至少一页 A4 + 一般文书页边距,走统一 A4 规格(utils/document-paper.ts)。 原来那套 `--pane-gutter: clamp(20px, 8%, 96px)` 只是"看着像版心", 与签署预览的页边距对不上,编辑时看到的换行位置和签出来不一样。 - **用 min-height 而不是 aspect-ratio**:aspect-ratio 会被 WangEditor 内层的 - 滚动容器吃掉(正文 1574px 而纸定死在 1160px,正文直接露到灰桌上); - min-height 只是下限,正文多了纸自己长高,滚动交给纸桌。 */ + 纸壳(.pane-sheet)宽度 == 纸宽,所以 clamp 那套与 cqw 那套在这里都精确。 */ .pane-content { width: 100%; - min-height: var(--doc-paper-min-h-cqw); - padding: var(--doc-paper-pad-y-cqw) var(--doc-paper-pad-x-cqw); + min-height: var(--doc-paper-min-h); + padding: var(--doc-paper-pad-y) var(--doc-paper-pad-x); background: #fff; box-shadow: var(--sh); }