南方电网

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