From 89fd9ab312c0aef9fcab89fbbaee4add5baa7c57 Mon Sep 17 00:00:00 2001
From: 吴羡 <16976746+Xian-TT3@user.noreply.gitee.com>
Date: 星期二, 27 十月 2026 09:43:22 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 src/utils/reportDocxLayout.js |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/src/utils/reportDocxLayout.js b/src/utils/reportDocxLayout.js
index 98ad551..8b081a6 100644
--- a/src/utils/reportDocxLayout.js
+++ b/src/utils/reportDocxLayout.js
@@ -4,6 +4,41 @@
 const floatingPositionPattern = /<w:tblpPr\b[^>]*\/>/
 const tableIndentPattern = /<w:tblInd\b[^>]*\/>/
 const runFontsPattern = /<w:rFonts\b[^>]*\/>/g
+const tableRowPattern = /<w:tr(?:\s[^>]*)?>[\s\S]*?<\/w:tr>/g
+const tableCellPattern = /<w:tc(?:\s[^>]*)?>[\s\S]*?<\/w:tc>/g
+
+function fitCoverCustomer(xml) {
+  let changed = false
+  const normalized = xml.replace(tableRowPattern, row => {
+    if (changed) return row
+    const cells = [...row.matchAll(tableCellPattern)]
+    if (cells.length !== 2) return row
+    const cellText = cell => [...cell.matchAll(/<w:t(?:\s[^>]*)?>([\s\S]*?)<\/w:t>/g)]
+      .map(match => match[1]).join('')
+    if (cellText(cells[0][0]).replace(/[\s:锛歖/g, '') !== '濮旀墭鍗曚綅') return row
+
+    const valueCell = cells[1][0]
+    const customer = cellText(valueCell)
+    const widthTag = valueCell.match(/<w:tcW\b[^>]*>/)?.[0]
+    const widthTwips = Number(widthTag?.match(/\bw:w="(\d+)"/)?.[1])
+    const fontHalfPoints = Number(valueCell.match(/<w:sz\b[^>]*\bw:val="(\d+)"/)?.[1])
+    if (!customer || customer.includes('{{') || !widthTwips || fontHalfPoints !== 32) return row
+
+    // 灏侀潰涓嬪垝绾挎槸鍗曞厓鏍煎簳杈规銆�16 纾呯殑闀垮崟浣嶅悕绉板垰濂藉崰婊″垪瀹芥椂锛�
+    // PDF 鎺掔増鍣ㄥ彲鑳藉皢娈佃惤缁撴潫绗︽尋鍒扮浜岃锛屽鑷磋〃鏍艰鍜屼笅鍒掔嚎涓嬬Щ銆�
+    const units = [...customer].reduce((sum, char) => sum +
+      (/\s/.test(char) ? 0.35 : char.codePointAt(0) > 0x2e80 ? 1 : 0.6), 0)
+    const availablePoints = widthTwips / 20 - 10
+    if (units * fontHalfPoints / 2 <= availablePoints) return row
+    const fittedHalfPoints = Math.max(24, Math.floor(availablePoints / units * 2))
+    const fittedCell = valueCell.replace(/<w:sz(?:Cs)?\b[^>]*\/>/g, tag =>
+      tag.replace(/\bw:val="32"/, `w:val="${fittedHalfPoints}"`))
+    if (fittedCell === valueCell) return row
+    changed = true
+    return row.replace(valueCell, fittedCell)
+  })
+  return changed ? normalized : null
+}
 
 function alignReportHeader(xml, reportCode) {
   // 鏃ф楠屾姤鍛婃妸椤电爜鏀惧湪娴姩鏂囨湰妗嗕腑锛汼uperDoc 閲嶆柊鍒嗛〉鏃朵細涓㈠け Word 鐨勬í鍚戦敋鐐广��
@@ -129,6 +164,21 @@
   return changed ? documentXml : null
 }
 
+function clearDefaultSequenceUnderlines(xml) {
+  return xml.replace(resultTablePattern, table => {
+    if (!table.includes('搴忓彿') || !/(妫�娴嬬粨鏋渱妫�楠岀粨鏋�)/.test(table)) return table
+    return table.replace(tableRowPattern, row => row.replace(tableCellPattern, (cell, offset) => {
+      if (offset !== row.indexOf('<w:tc')) return cell
+      const text = [...cell.matchAll(/<w:t\b(?![^>]*\/>)[^>]*>([\s\S]*?)<\/w:t>/g)]
+        .map(match => match[1]).join('').trim()
+      if (!/^\d+$/.test(text)) return cell
+      // 鏃ф姤鍛婁腑鐨� <w:u w:color="auto"/> 榛樿浼氳瑙i噴鎴愬崟涓嬪垝绾裤��
+      // 鏄惧紡璁剧疆浜嗙被鍨嬬殑涓嬪垝绾夸繚鐣欙紝鍏佽鐢ㄦ埛鑷淇敼搴忓彿鏍煎紡銆�
+      return cell.replace(/<w:u\b[^>]*\/>/g, tag => /\bw:val=/.test(tag) ? tag : '')
+    }))
+  })
+}
+
 export async function normalizeReportDocxForEditor(blob, reportCode) {
   const zip = await JSZip.loadAsync(blob)
   const documentPart = zip.file('word/document.xml')
@@ -138,6 +188,8 @@
   const themeXml = themePart ? await themePart.async('string') : ''
   const themeFonts = { major: chineseThemeFont(themeXml, 'major'), minor: chineseThemeFont(themeXml, 'minor') }
   let normalizedXml = alignResultTable(documentXml) || documentXml
+  normalizedXml = clearDefaultSequenceUnderlines(normalizedXml)
+  normalizedXml = fitCoverCustomer(normalizedXml) || normalizedXml
   normalizedXml = materializeChineseThemeFonts(normalizedXml, themeFonts) || normalizedXml
   let changed = normalizedXml !== documentXml
   if (changed) zip.file('word/document.xml', normalizedXml)

--
Gitblit v1.9.3