Browse Source

fix(web-admin): prevent blank Word export from broken seal img tags

Self-closing slash before style produced invalid HTML that caused html-to-docx to emit an empty document.

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 1 tháng trước cách đây
mục cha
commit
f09399f5f0

+ 9 - 0
web-admin/src/utils/crm/contract-html-to-docx.test.ts

@@ -100,6 +100,15 @@ describe('normalizeSealImagesForDocx', () => {
     assert.equal(out.includes('position: absolute'), false)
     assert.equal(out.includes('float:left'), true)
     assert.equal(out.includes('alt="印章"'), true)
+    assert.equal(out.includes('/ style='), false)
+    assert.match(out, /<img\s[^>]*style="float:left[^"]*"\s*\/>/)
+  })
+
+  it('does not emit broken self-closing slash before style', () => {
+    const html =
+      '<img src="/yz.png" alt="印章" style="position: absolute; width: 140px; height: 140px;" />'
+    const out = normalizeSealImagesForDocx(html)
+    assert.equal(/<img[^>]*\/\s+style=/.test(out), false)
   })
 })
 

+ 9 - 4
web-admin/src/utils/crm/contract-html-to-docx.ts

@@ -259,14 +259,19 @@ export function normalizeHeaderMetaFlexLayoutForDocx(html: string): string {
 /**
  * 印章在预览为 absolute 居中叠字;Word 不认 absolute,改为 float + 负 margin 浮于后续文字上方。
  * 供方/需方标题下的横向分割线(border-bottom)保持不变。
+ *
+ * 注意:必须去掉原标签里的自闭合 `/`,否则会生成非法的 `<img ... / style="...">`,
+ * html-to-docx 会解析失败并导出空白文档。
  */
 export function normalizeSealImagesForDocx(html: string): string {
-  return html.replace(/<img\b([^>]*alt\s*=\s*["']印章["'][^>]*)>/gi, (_full, attrs: string) => {
-    let rest = String(attrs).replace(/\s*style\s*=\s*(["'])[\s\S]*?\1/i, '')
-    rest = rest.replace(/\s*style\s*=\s*{[^}]*}/i, '')
+  return html.replace(/<img\b([^>]*alt\s*=\s*["']印章["'][^>]*)\/?\s*>/gi, (_full, attrs: string) => {
+    let rest = String(attrs)
+      .replace(/\s*style\s*=\s*(["'])[\s\S]*?\1/i, '')
+      .replace(/\/\s*$/g, '')
+      .trim()
     const style =
       'float:left;width:140px;height:140px;margin:4px 12px -120px 24px;opacity:0.85;'
-    return `<img${rest} style="${style}">`
+    return `<img ${rest} style="${style}" />`
   })
 }