word 预览优化
This commit is contained in:
parent
f05818d31a
commit
ee0581326a
|
|
@ -49,8 +49,6 @@
|
|||
<script>
|
||||
import * as docxPreview from 'docx-preview/dist/docx-preview.js'
|
||||
|
||||
const DOCX_CUSTOM_STYLE_ID = 'docx-preview-custom-style'
|
||||
|
||||
const DEFAULT_DOC_URL = 'http://192.168.0.14:9090/smart-bid/technicalSolutionDatabase/2025/11/11/887b35d28b2149b6a7555fb639be9411.docx'
|
||||
|
||||
export default {
|
||||
|
|
@ -365,21 +363,117 @@ export default {
|
|||
|
||||
wrapContentWithArticle(container) {
|
||||
if (!container) return
|
||||
const existingArticle = container.querySelector(':scope > article.docx-article-wrapper')
|
||||
if (existingArticle) {
|
||||
const sections = Array.from(container.querySelectorAll('.docx-wrapper section'))
|
||||
if (sections.length === 0) {
|
||||
this.wrapElementsInSections(container)
|
||||
return
|
||||
}
|
||||
const article = document.createElement('article')
|
||||
article.className = 'docx-article-wrapper'
|
||||
const nodes = Array.from(container.childNodes)
|
||||
.filter((node) => node.nodeType === Node.ELEMENT_NODE || (node.nodeType === Node.TEXT_NODE && node.textContent.trim()))
|
||||
nodes.forEach((node) => {
|
||||
if (node !== article) {
|
||||
article.appendChild(node)
|
||||
sections.forEach((section) => {
|
||||
this.wrapElementsInSections(section)
|
||||
})
|
||||
},
|
||||
|
||||
wrapElementsInSections(node) {
|
||||
if (!node) return
|
||||
|
||||
// 获取所有需要包装的元素类型,但排除 header 和 footer 内的
|
||||
const selectors = [
|
||||
'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
||||
'ul', 'ol', 'blockquote', 'table'
|
||||
]
|
||||
console.log(node);
|
||||
|
||||
// 获取所有匹配的元素
|
||||
const allElements = Array.from(node.querySelectorAll(selectors.join(',')))
|
||||
|
||||
// 过滤:只保留最外层的元素(没有父元素也是目标选择器)
|
||||
const elements = allElements.filter(el => {
|
||||
// 检查元素是否在 header 或 footer 内
|
||||
let parent = el.parentElement
|
||||
while (parent && parent !== node) {
|
||||
const tag = parent.tagName ? parent.tagName.toLowerCase() : ''
|
||||
if (tag === 'header' || tag === 'footer') {
|
||||
return false // 在 header/footer 内,跳过
|
||||
}
|
||||
|
||||
// 如果父元素也是目标选择器之一,说明当前元素是嵌套的,应该跳过
|
||||
if (selectors.includes(tag)) {
|
||||
return false
|
||||
}
|
||||
|
||||
parent = parent.parentElement
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
if (elements.length === 0) return
|
||||
|
||||
// 按连续元素分组
|
||||
const elementGroups = this.groupConsecutiveElements(elements)
|
||||
|
||||
// 为每个元素组创建 article 包装
|
||||
elementGroups.forEach(group => {
|
||||
if (group.length > 0) {
|
||||
this.wrapElementGroupWithArticle(group)
|
||||
}
|
||||
})
|
||||
container.appendChild(article)
|
||||
},
|
||||
|
||||
groupConsecutiveElements(elements) {
|
||||
const groups = []
|
||||
let currentGroup = []
|
||||
|
||||
elements.forEach((el, index) => {
|
||||
// 如果当前组为空,直接添加
|
||||
if (currentGroup.length === 0) {
|
||||
currentGroup.push(el)
|
||||
return
|
||||
}
|
||||
// 检查是否连续(在 DOM 中相邻)
|
||||
const lastEl = currentGroup[currentGroup.length - 1]
|
||||
let nextElement = lastEl.nextElementSibling
|
||||
|
||||
// 跳过空白文本节点等,找到下一个元素
|
||||
while (nextElement && nextElement.nodeType !== 1) {
|
||||
nextElement = nextElement.nextElementSibling
|
||||
}
|
||||
|
||||
if (nextElement === el) {
|
||||
// 连续的元素
|
||||
currentGroup.push(el)
|
||||
} else {
|
||||
// 不连续,开始新组
|
||||
groups.push([...currentGroup])
|
||||
currentGroup = [el]
|
||||
}
|
||||
|
||||
// 如果是最后一个元素,结束当前组
|
||||
if (index === elements.length - 1) {
|
||||
groups.push([...currentGroup])
|
||||
}
|
||||
})
|
||||
|
||||
return groups
|
||||
},
|
||||
|
||||
wrapElementGroupWithArticle(elements) {
|
||||
if (!elements || elements.length === 0) return
|
||||
|
||||
const firstElement = elements[0]
|
||||
const parent = firstElement.parentElement
|
||||
|
||||
// 创建 article 元素
|
||||
const article = document.createElement('article')
|
||||
article.className = 'docx-article-wrapper'
|
||||
|
||||
// 在第一个元素前插入 article
|
||||
parent.insertBefore(article, firstElement)
|
||||
|
||||
// 将所有元素移动到 article 中
|
||||
elements.forEach(el => {
|
||||
article.appendChild(el)
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
@ -395,12 +489,16 @@ export default {
|
|||
}
|
||||
|
||||
.document-search-word article.docx-article-wrapper {
|
||||
max-width: 960px;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
margin: 0 auto 32px;
|
||||
background: #ffffff;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 18px 40px rgba(25, 64, 158, 0.12);
|
||||
box-shadow: 0 20px 48px rgba(25, 64, 158, 0.12);
|
||||
padding: 48px 56px;
|
||||
box-sizing: border-box;
|
||||
color: #1f2a62;
|
||||
line-height: 1.75;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.search-toolbar {
|
||||
|
|
@ -702,6 +800,4 @@ export default {
|
|||
background: #206dff !important;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
Loading…
Reference in New Issue