word 预览优化
This commit is contained in:
parent
f05818d31a
commit
ee0581326a
|
|
@ -49,8 +49,6 @@
|
||||||
<script>
|
<script>
|
||||||
import * as docxPreview from 'docx-preview/dist/docx-preview.js'
|
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'
|
const DEFAULT_DOC_URL = 'http://192.168.0.14:9090/smart-bid/technicalSolutionDatabase/2025/11/11/887b35d28b2149b6a7555fb639be9411.docx'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -365,21 +363,117 @@ export default {
|
||||||
|
|
||||||
wrapContentWithArticle(container) {
|
wrapContentWithArticle(container) {
|
||||||
if (!container) return
|
if (!container) return
|
||||||
const existingArticle = container.querySelector(':scope > article.docx-article-wrapper')
|
const sections = Array.from(container.querySelectorAll('.docx-wrapper section'))
|
||||||
if (existingArticle) {
|
if (sections.length === 0) {
|
||||||
|
this.wrapElementsInSections(container)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const article = document.createElement('article')
|
sections.forEach((section) => {
|
||||||
article.className = 'docx-article-wrapper'
|
this.wrapElementsInSections(section)
|
||||||
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) {
|
wrapElementsInSections(node) {
|
||||||
article.appendChild(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>
|
</script>
|
||||||
|
|
@ -395,12 +489,16 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.document-search-word article.docx-article-wrapper {
|
.document-search-word article.docx-article-wrapper {
|
||||||
max-width: 960px;
|
display: block;
|
||||||
margin: 0 auto;
|
margin: 0 auto 32px;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
border-radius: 16px;
|
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;
|
padding: 48px 56px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #1f2a62;
|
||||||
|
line-height: 1.75;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-toolbar {
|
.search-toolbar {
|
||||||
|
|
@ -702,6 +800,4 @@ export default {
|
||||||
background: #206dff !important;
|
background: #206dff !important;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
Loading…
Reference in New Issue