南方电网

This commit is contained in:
cwchen 2025-11-11 10:51:20 +08:00
parent 8ba255e11a
commit 064cefa5e6
1 changed files with 60 additions and 28 deletions

View File

@ -3,9 +3,10 @@
<div class="search-toolbar">
<el-input v-model="keyword" class="search-input" placeholder="输入关键字搜索" clearable
@keyup.enter.native="handleSearch" @clear="resetSearch">
<el-button slot="append" icon="el-icon-search" @click="handleSearch" :loading="searching"
:disabled="searching">
<el-button slot="append" class="search-btn" icon="el-icon-search" @click="handleSearch"
:loading="searching" :disabled="searching">
<span v-if="!searching">搜索</span>
<span v-else>搜索中...</span>
</el-button>
</el-input>
<div class="search-status" v-if="searchResults.length">
@ -532,8 +533,9 @@ export default {
}
if (!this.pdfDoc) return
if (this.searching) return
// if (this.searching) return
this.searching = true
await this.$nextTick()
try {
const allPrepared = this.pageTextDivs.length === this.totalPages && this.pageTextDivs.every(items => items && items.length)
if (!allPrepared) {
@ -734,7 +736,7 @@ export default {
}
if (!skipNavigate) {
await this.navigateToResult(this.currentResultIndex, true)
await this.navigateToResult(this.currentResultIndex, true, false)
} else {
this.scheduleActiveHighlightRefresh()
}
@ -744,7 +746,7 @@ export default {
this.navigateToResult(this.currentResultIndex)
},
async navigateToResult(index, ensureRendered = false) {
async navigateToResult(index, ensureRendered = false, useSmoothScroll = true) {
if (!this.searchResults.length || index < 0 || index >= this.searchResults.length) return
const currentResult = this.searchResults[index]
const pageNumber = currentResult.pageIndex + 1
@ -760,19 +762,29 @@ export default {
this.currentResultIndex = index
this.scheduleActiveHighlightRefresh()
const target = this.searchResults[this.currentResultIndex]?.element
if (!target) return
const wrapper = this.$refs.pdfWrapper
if (!wrapper) return
this.$nextTick(() => {
const performScroll = () => {
const target = this.searchResults[this.currentResultIndex]?.element
if (!target) return
const wrapper = this.$refs.pdfWrapper
if (!wrapper) return
const container = target.closest('.pdf-page') || target
if (!container) return
const wrapperOffsetTop = container.offsetTop
const containerHeight = container.offsetHeight || target.offsetHeight || 0
const desired = wrapperOffsetTop - Math.max((wrapper.clientHeight - containerHeight) / 2, 0)
this.smoothScrollTo(wrapper, desired)
})
if (useSmoothScroll) {
this.smoothScrollTo(wrapper, desired)
} else {
this.cancelScrollAnimation()
wrapper.scrollTop = desired
}
}
if (useSmoothScroll) {
this.$nextTick(() => performScroll())
} else {
performScroll()
}
},
applyHighlightsToPage(pageIndex) {
@ -939,7 +951,7 @@ export default {
this.scrollAnimationFrame = requestAnimationFrame(step)
},
goToPrevious() {
async goToPrevious() {
if (!this.searchResults.length) return
let targetIndex = this.currentResultIndex
if (targetIndex === -1) {
@ -950,10 +962,10 @@ export default {
targetIndex = this.searchResults.length - 1
}
}
this.navigateToResult(targetIndex)
await this.navigateToResult(targetIndex, false, false)
},
goToNext() {
async goToNext() {
if (!this.searchResults.length) return
let targetIndex = this.currentResultIndex
if (targetIndex === -1) {
@ -964,7 +976,7 @@ export default {
targetIndex = 0
}
}
this.navigateToResult(targetIndex)
await this.navigateToResult(targetIndex, false, false)
},
resetSearch() {
@ -1093,7 +1105,6 @@ export default {
background: #f4f7ff;
padding: 16px;
box-sizing: border-box;
font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Arial, sans-serif;
font-size: 14px;
line-height: 1.6;
color: #1f2430;
@ -1136,15 +1147,6 @@ export default {
padding: 0 8px;
}
.search-preparing {
display: flex;
align-items: center;
gap: 8px;
color: #506dff;
font-size: 14px;
margin-top: 10px;
}
.viewer-container {
flex: 1;
background: #ffffff;
@ -1274,6 +1276,36 @@ export default {
transform: rotate(360deg);
}
}
@keyframes search-glow {
0%,
100% {
box-shadow: 0 0 0 0 rgba(32, 109, 255, 0.45);
}
50% {
box-shadow: 0 0 0 10px rgba(32, 109, 255, 0);
}
}
@keyframes search-rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes search-outline {
0%,
100% {
opacity: 0;
transform: scale(0.9);
}
50% {
opacity: 1;
transform: scale(1.05);
}
}
.pdf-page>canvas.pdf-canvas {
position: relative;