diff --git a/clinical-web/src/utils/signing-pdf.ts b/clinical-web/src/utils/signing-pdf.ts index 65e1753..b84d103 100644 --- a/clinical-web/src/utils/signing-pdf.ts +++ b/clinical-web/src/utils/signing-pdf.ts @@ -7,7 +7,9 @@ * 直接截图既截不全、版面也会跟着变; * ② 固定页眉在每页重复:页眉是系统按 HIS 数据渲染的,服务端生成 PDF 时同样要按页重复; * ③ 页码只写 "1 / 2" 这类 ASCII:jsPDF 内置字体不含中文, - * 画中文页码需要内嵌字体(体积会明显变大),这一步留给服务端用真字体实现。 + * 画中文页码需要内嵌字体(体积会明显变大),这一步留给服务端用真字体实现; + * ④ 导出前对 flex 容器做一次兼容降级:html2canvas 不实现 flex 布局, + * 填写项胶囊里的文字、输入框取值、签名图会被整块丢掉,见 applyExportFlexFallback。 * * 输出为位图 PDF:文本不可选中,仅供原型演示;正式文书以服务端生成的 PDF 为准。 */ @@ -36,6 +38,44 @@ export interface SigningPdfInput { fileName: string } +/** + * html2canvas 兼容处理:flex 容器里的文字与控件取值会被整块丢掉。 + * + * 实测(签署工作台导出的 PDF,html2canvas 1.4):页面上明明印着「与患者关系:文本框 配偶」、 + * 签名图也画出来了,导出的位图里这些却全是空白,只剩胶囊的边框和底色—— + * 填写项胶囊 `.sign-field` 与控件容器 `.sign-field__control` 都是 `display: inline-flex`, + * 而 html2canvas 1.4 不实现 flex 布局,容器内文本的落点算不出来, + * 于是连同 `` 的取值、签名 `` 一起被丢掉(连 `

` 里的「待签名」提示也不见了)。 + * + * 换成 `inline-block` 后内容全部回来,于是这里把这两层降级。**只在导出克隆体上改**: + * 屏幕上的版式一行不动,PDF 也不会丢内容;`.sign-doc-header` 那层 flex 实测不受影响,不动它。 + * + * gap 在 inline-block 下失效,所以把原来的 4px 项间距、align-items: center、 + * 签名位的 justify-content: center 用等效的 inline 写法补回来,导出结果与屏幕观感一致。 + */ +function applyExportFlexFallback(root: HTMLElement) { + root.querySelectorAll('.sign-field, .sign-field__control').forEach((element) => { + element.style.display = 'inline-block' + }) + + // 胶囊原来是 inline-flex + gap: 4px,项名与控件之间的间距要自己补 + root.querySelectorAll('.sign-field__label').forEach((element) => { + element.style.marginRight = '4px' + }) + + root.querySelectorAll('.sign-field__control').forEach((element) => { + // 原来是 align-items: center + element.style.verticalAlign = 'middle' + }) + + // 签名位原来是 justify-content: center,inline-block 下改用 text-align 居中 + root + .querySelectorAll('.sign-field--signature .sign-field__control') + .forEach((element) => { + element.style.textAlign = 'center' + }) +} + /** 量固定页眉的高度(含下外边距)——它是每页要重复的那一条 */ function measureHeaderHeight(element: HTMLElement) { const header = element.querySelector('.sign-doc-header') @@ -68,6 +108,8 @@ export async function createSigningPdf(input: SigningPdfInput): Promise { useCORS: true, logging: false, onclone: (clonedDocument, clonedElement) => { + applyExportFlexFallback(clonedElement) + clonedElement.style.width = `${CAPTURE_WIDTH_PX}px` clonedElement.style.height = 'auto' clonedElement.style.maxHeight = 'none'