From b283f4e3c731f48fcf5da53beedb0e581503f904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E5=BC=A0?= <2091066548@qq.com> Date: Tue, 9 Sep 2025 15:00:37 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E6=90=9C=E7=B4=A2=E6=B5=AE?= =?UTF-8?q?=E7=AA=97=EF=BC=8C=E5=92=8C=E6=8E=A5=E5=8F=A3=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/layout/AppHeader.vue | 64 +++- src/components/search/SearchDropdown.vue | 384 +++++++++++++++++++++++ src/views/Login.vue | 7 +- 3 files changed, 451 insertions(+), 4 deletions(-) create mode 100644 src/components/search/SearchDropdown.vue diff --git a/src/components/layout/AppHeader.vue b/src/components/layout/AppHeader.vue index 49e5d12..4a7c983 100644 --- a/src/components/layout/AppHeader.vue +++ b/src/components/layout/AppHeader.vue @@ -42,9 +42,24 @@
- @@ -136,6 +151,7 @@ import { NDropdown, NIcon } from 'naive-ui' import LoginModal from '@/components/auth/LoginModal.vue' import RegisterModal from '@/components/auth/RegisterModal.vue' import SafeAvatar from '@/components/common/SafeAvatar.vue' +import SearchDropdown from '@/components/search/SearchDropdown.vue' const router = useRouter() const route = useRoute() @@ -200,6 +216,12 @@ const registerModalVisible = ref(false) const showLanguageDropdown = ref(false) const languageSwitcherRef = ref(null) +// 搜索相关 +const searchKeyword = ref('') +const showSearchDropdown = ref(false) +const searchBoxRef = ref(null) +const searchDropdownRef = ref | null>(null) + // 语言选项配置 const languageOptions = computed(() => [ { @@ -278,6 +300,36 @@ const getLanguageName = (lang: string): string => { return languageMap[lang] || '中文' } +// 搜索相关方法 +const handleSearch = () => { + if (searchKeyword.value.trim()) { + performSearch(searchKeyword.value.trim()) + } +} + +const handleSearchFromDropdown = (keyword: string) => { + searchKeyword.value = keyword + performSearch(keyword) +} + +const performSearch = (keyword: string) => { + console.log('🔍 执行搜索:', keyword) + + // 保存搜索记录到最近搜索 + if (searchDropdownRef.value) { + searchDropdownRef.value.saveRecentSearch(keyword) + } + + // 跳转到搜索结果页面 + router.push({ + path: '/search', + query: { q: keyword } + }) + + // 关闭搜索下拉框 + showSearchDropdown.value = false +} + const handleLearningCenter = () => { @@ -634,10 +686,15 @@ const handleAuthSuccess = () => { // 修复未定义的handleClickOutside const handleClickOutside = (event: MouseEvent) => { - // 这里只处理语言下拉的关闭,其他弹窗由自身控制 + // 处理语言下拉的关闭 if (languageSwitcherRef.value && !languageSwitcherRef.value.contains(event.target as Node)) { showLanguageDropdown.value = false } + + // 处理搜索下拉的关闭 + if (searchBoxRef.value && !searchBoxRef.value.contains(event.target as Node)) { + showSearchDropdown.value = false + } } // 生命周期钩子 @@ -863,6 +920,7 @@ watch(() => route.path, () => { .search-box { /* border-left: 1px solid #ececec; border-right: 1px solid #ececec; */ + position: relative; display: flex; align-items: center; padding: 22px 16px; diff --git a/src/components/search/SearchDropdown.vue b/src/components/search/SearchDropdown.vue new file mode 100644 index 0000000..2abc815 --- /dev/null +++ b/src/components/search/SearchDropdown.vue @@ -0,0 +1,384 @@ + + + + + diff --git a/src/views/Login.vue b/src/views/Login.vue index d93ed5a..4a59465 100644 --- a/src/views/Login.vue +++ b/src/views/Login.vue @@ -114,7 +114,7 @@
@@ -336,6 +336,11 @@ const handleSubmit = async () => { userStore.isLoading = false } } + +// 跳转到服务协议页面 +const goToServiceAgreement = () => { + router.push('/service-agreement') +}