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 @@
+
+
+
+
+
+
+
+
+

+
{{ item.keyword }}
+
{{ item.count }}+课程
+
+
+
+
+
+
+
+
+
+

+
{{ item }}
+
+
+
+
+
+
+
+
+
+
+
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')
+}