Sfoglia il codice sorgente

修改替换逻辑

yangg 4 mesi fa
parent
commit
e9a1486cf8
1 ha cambiato i file con 118 aggiunte e 90 eliminazioni
  1. 118 90
      src/views/project/components/dataList.vue

+ 118 - 90
src/views/project/components/dataList.vue

@@ -1408,6 +1408,20 @@ export default {
           page-break-inside: auto;
         }
         
+        /* 自适应行高表格样式 */
+        .auto-height-table tr {
+          height: auto !important;
+          min-height: 30px;
+        }
+        
+        .auto-height-table td,
+        .auto-height-table th {
+          white-space: normal;
+          word-wrap: break-word;
+          vertical-align: middle;
+          padding: 8px;
+        }
+        
         /* 有边框表格的通用样式 */
         table[data-has-border="true"] {
           border-collapse: collapse !important;
@@ -2295,103 +2309,97 @@ export default {
           return content
         }
 
-        const tempDiv = document.createElement('div')
-        tempDiv.innerHTML = content
-
-        // 新增:递归处理HTML节点
-        const processNode = (node) => {
-          if (node.nodeType === 3) {
-            // 文本节点
-            return node.textContent
-          }
-
-          let html = ''
-          for (const child of node.childNodes) {
-            html += processNode(child)
+        // 处理替换内容 - 移除外层的span标签并添加自适应行高样式
+        let processedReplacement = replacement
+        if (replacement.includes('<table') && replacement.startsWith('<span')) {
+          // 提取表格内容,移除外层span标签
+          const tempDiv = document.createElement('div')
+          tempDiv.innerHTML = replacement
+          const tableElement = tempDiv.querySelector('table')
+          if (tableElement) {
+            // 添加自适应行高样式
+            tableElement.style.borderCollapse = 'collapse'
+            
+            // 处理表格行和单元格
+            tableElement.querySelectorAll('tr').forEach(row => {
+              // 移除固定高度,使用min-height代替
+              if (row.style.height) {
+                row.style.minHeight = row.style.height
+                row.style.height = 'auto'
+              }
+              
+              // 处理单元格
+              row.querySelectorAll('td, th').forEach(cell => {
+                // 确保单元格内容可以自动换行
+                if (!cell.style.whiteSpace) {
+                  cell.style.whiteSpace = 'normal'
+                }
+                if (!cell.style.wordWrap) {
+                  cell.style.wordWrap = 'break-word'
+                }
+                // 设置垂直对齐方式
+                if (!cell.style.verticalAlign) {
+                  cell.style.verticalAlign = 'middle'
+                }
+                // 确保内边距合适
+                if (!cell.style.padding) {
+                  cell.style.padding = '8px'
+                }
+              })
+            })
+            
+            processedReplacement = tableElement.outerHTML
           }
-          return html
         }
 
-        const handleSplitContent = () => {
-          // 先获取纯文本内容用于匹配
-          const plainText = processNode(tempDiv)
-
-          // 构建用于匹配分割标记的正则表达式
-          const splitRegex = new RegExp(
-            `(\\[|【)(.*?)(${searchCode})(.*?)(\\]|】)`,
-            'g'
-          )
-
-          const currentHtml = tempDiv.innerHTML
-
-          // 查找所有可能的匹配
-          const matches = [
-            ...currentHtml.matchAll(/<[^>]+>|\[|\]|【|】|[^<\[\]【】]+/g)
-          ]
-
-          // 重建HTML,识别并替换目标编码
-          let rebuiltHtml = ''
-          let currentMatch = ''
-          let isCollecting = false
-          let bracketCount = 0
-
-          for (let i = 0; i < matches.length; i++) {
-            const part = matches[i][0]
-
-            if (part === '[' || part === '【') {
-              isCollecting = true
-              bracketCount++
-              currentMatch = part
-              continue
-            }
+        // 创建临时DOM元素来处理HTML内容
+        const tempDiv = document.createElement('div')
+        tempDiv.innerHTML = content
 
-            if (isCollecting) {
-              currentMatch += part
-
-              if (part === ']' || part === '】') {
-                bracketCount--
-                if (bracketCount === 0) {
-                  // 检查收集到的内容是否包含目标编码
-                  const cleanText = currentMatch.replace(/<[^>]+>/g, '')
-                  if (cleanText.includes(searchCode)) {
-                    rebuiltHtml += replacement
-                    isCollecting = false
-                    currentMatch = ''
-                  } else {
-                    rebuiltHtml += currentMatch
-                    isCollecting = false
-                    currentMatch = ''
-                  }
-                }
-              }
-            } else {
-              rebuiltHtml += part
+        // 查找并替换匹配的内容
+        const pattern = new RegExp(`(\\[|【)([^\\]】]*?)(${searchCode})([^\\[【]*?)(\\]|】)`, 'g')
+        
+        // 处理所有文本节点
+        const textNodes = this.getAllTextNodes(tempDiv)
+        textNodes.forEach(textNode => {
+          const text = textNode.textContent
+          if (pattern.test(text)) {
+            // 创建一个包装元素
+            const wrapper = document.createElement('div')
+            wrapper.innerHTML = text.replace(pattern, processedReplacement)
+            
+            // 替换原始文本节点
+            const fragment = document.createDocumentFragment()
+            while (wrapper.firstChild) {
+              fragment.appendChild(wrapper.firstChild)
             }
+            
+            textNode.parentNode.replaceChild(fragment, textNode)
           }
-
-          // 处理未闭合的标记
-          if (currentMatch) {
-            rebuiltHtml += currentMatch
+        })
+        
+        // 特殊处理表格单元格
+        tempDiv.querySelectorAll('td, th').forEach(cell => {
+          const cellText = cell.textContent
+          if (pattern.test(cellText) && !cell.querySelector('table')) {
+            cell.innerHTML = cell.innerHTML.replace(pattern, processedReplacement)
           }
-
-          // 清理可能的残留标签和多余换行
-          rebuiltHtml = rebuiltHtml
-            // 清理空标签
-            .replace(/(<span[^>]*>)\s*(<\/span>)/g, '')
-            .replace(/(<\/span>)(<span[^>]*>)/g, '')
-            .replace(/<a[^>]*><\/a>/g, '')
-            // 清理替换内容前后的多余换行
-            .replace(/(\r?\n|\r)\s*(\[|【)/g, '$2') // 清理标记前的换行
-            .replace(/(\]|】)\s*(\r?\n|\r)/g, '$1') // 清理标记后的换行
-            // 清理连续的换行为单个换行
-            .replace(/(\r?\n|\r){2,}/g, '\n')
-            // 清理多余空格
-            .replace(/\s+/g, ' ')
-
-          tempDiv.innerHTML = rebuiltHtml
-        }
-
-        handleSplitContent()
+        })
+        
+        // 处理最终结果中的所有表格,确保自适应行高
+        tempDiv.querySelectorAll('table').forEach(table => {
+          // 添加自适应样式类
+          table.classList.add('auto-height-table')
+          
+          // 处理所有行
+          table.querySelectorAll('tr').forEach(row => {
+            if (row.style.height && !row.style.minHeight) {
+              row.style.minHeight = row.style.height
+              row.style.height = 'auto'
+            }
+          })
+        })
+        
         return tempDiv.innerHTML
       } catch (error) {
         console.error('替换内容时出错:', error)
@@ -2405,6 +2413,26 @@ export default {
       }
     },
 
+    // 添加一个辅助方法来获取所有文本节点
+    getAllTextNodes(node) {
+      const textNodes = []
+      const walk = document.createTreeWalker(
+        node,
+        NodeFilter.SHOW_TEXT,
+        null,
+        false
+      )
+      
+      let currentNode
+      while ((currentNode = walk.nextNode())) {
+        if (currentNode.textContent.trim()) {
+          textNodes.push(currentNode)
+        }
+      }
+      
+      return textNodes
+    },
+
     // 添加样式到 convertTextToHtml 方法
     convertTextToHtml(text) {
       if (!text) return ''