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