|
|
@@ -1,59 +1,5 @@
|
|
|
<template>
|
|
|
<section class="space-y-6">
|
|
|
- <!-- 搜索框 - 固定在Header下方 -->
|
|
|
- <div
|
|
|
- class="sticky top-16 z-30 bg-surface/90 backdrop-blur supports-[backdrop-filter]:bg-surface/70 border-b border-white/5 pb-3"
|
|
|
- >
|
|
|
- <div class="flex gap-3">
|
|
|
- <div class="relative flex-1">
|
|
|
- <input
|
|
|
- v-model="searchKeyword"
|
|
|
- type="text"
|
|
|
- placeholder="搜索视频..."
|
|
|
- class="w-full px-4 py-3 pr-12 rounded-xl bg-white/5 border border-white/10 text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-emerald-500/50 focus:border-emerald-500/50 transition"
|
|
|
- @keyup.enter="() => handleSearch()"
|
|
|
- />
|
|
|
- <button
|
|
|
- v-if="searchKeyword"
|
|
|
- @click="clearSearch"
|
|
|
- class="absolute right-3 top-1/2 transform -translate-y-1/2 text-white/50 hover:text-white/80 transition"
|
|
|
- >
|
|
|
- <svg
|
|
|
- class="w-5 h-5"
|
|
|
- fill="none"
|
|
|
- stroke="currentColor"
|
|
|
- viewBox="0 0 24 24"
|
|
|
- >
|
|
|
- <path
|
|
|
- stroke-linecap="round"
|
|
|
- stroke-linejoin="round"
|
|
|
- stroke-width="2"
|
|
|
- d="M6 18L18 6M6 6l12 12"
|
|
|
- />
|
|
|
- </svg>
|
|
|
- </button>
|
|
|
- </div>
|
|
|
- <button
|
|
|
- @click="() => handleSearch()"
|
|
|
- class="px-4 py-3 rounded-xl bg-white/5 border border-white/10 text-white/70 hover:bg-white/10 hover:text-white hover:border-white/20 transition"
|
|
|
- >
|
|
|
- <svg
|
|
|
- class="w-5 h-5"
|
|
|
- fill="none"
|
|
|
- stroke="currentColor"
|
|
|
- viewBox="0 0 24 24"
|
|
|
- >
|
|
|
- <path
|
|
|
- stroke-linecap="round"
|
|
|
- stroke-linejoin="round"
|
|
|
- stroke-width="2"
|
|
|
- d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
|
|
- />
|
|
|
- </svg>
|
|
|
- </button>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
<!-- 为你推荐卡片 -->
|
|
|
<div
|
|
|
v-if="!isSearchMode"
|
|
|
@@ -199,7 +145,7 @@
|
|
|
<button
|
|
|
@click="
|
|
|
isSearchMode
|
|
|
- ? handleSearch(currentPage - 1)
|
|
|
+ ? handleSearch(currentSearchKeyword, currentPage - 1)
|
|
|
: loadVideosByTag(selectedMenu, currentPage - 1)
|
|
|
"
|
|
|
:disabled="currentPage <= 1"
|
|
|
@@ -215,7 +161,7 @@
|
|
|
v-if="currentPage > 3"
|
|
|
@click="
|
|
|
isSearchMode
|
|
|
- ? handleSearch(1)
|
|
|
+ ? handleSearch(currentSearchKeyword, 1)
|
|
|
: loadVideosByTag(selectedMenu, 1)
|
|
|
"
|
|
|
class="px-3 py-2 rounded-lg bg-white/5 border border-white/10 text-white/70 hover:bg-white/10 hover:text-white transition text-sm"
|
|
|
@@ -233,7 +179,7 @@
|
|
|
v-if="currentPage > 1"
|
|
|
@click="
|
|
|
isSearchMode
|
|
|
- ? handleSearch(currentPage - 1)
|
|
|
+ ? handleSearch(currentSearchKeyword, currentPage - 1)
|
|
|
: loadVideosByTag(selectedMenu, currentPage - 1)
|
|
|
"
|
|
|
class="px-3 py-2 rounded-lg bg-white/5 border border-white/10 text-white/70 hover:bg-white/10 hover:text-white transition text-sm"
|
|
|
@@ -253,7 +199,7 @@
|
|
|
v-if="currentPage < totalPages"
|
|
|
@click="
|
|
|
isSearchMode
|
|
|
- ? handleSearch(currentPage + 1)
|
|
|
+ ? handleSearch(currentSearchKeyword, currentPage + 1)
|
|
|
: loadVideosByTag(selectedMenu, currentPage + 1)
|
|
|
"
|
|
|
class="px-3 py-2 rounded-lg bg-white/5 border border-white/10 text-white/70 hover:bg-white/10 hover:text-white transition text-sm"
|
|
|
@@ -289,7 +235,7 @@
|
|
|
v-if="currentPage < totalPages - 2"
|
|
|
@click="
|
|
|
isSearchMode
|
|
|
- ? handleSearch(totalPages)
|
|
|
+ ? handleSearch(currentSearchKeyword, totalPages)
|
|
|
: loadVideosByTag(selectedMenu, totalPages)
|
|
|
"
|
|
|
class="px-3 py-2 rounded-lg bg-white/5 border border-white/10 text-white/70 hover:bg-white/10 hover:text-white transition text-sm"
|
|
|
@@ -302,7 +248,7 @@
|
|
|
<button
|
|
|
@click="
|
|
|
isSearchMode
|
|
|
- ? handleSearch(currentPage + 1)
|
|
|
+ ? handleSearch(currentSearchKeyword, currentPage + 1)
|
|
|
: loadVideosByTag(selectedMenu, currentPage + 1)
|
|
|
"
|
|
|
:disabled="currentPage >= totalPages"
|
|
|
@@ -327,7 +273,7 @@
|
|
|
<button
|
|
|
@click="
|
|
|
isSearchMode
|
|
|
- ? handleSearch(currentPage - 1)
|
|
|
+ ? handleSearch(currentSearchKeyword, currentPage - 1)
|
|
|
: loadVideosByTag(selectedMenu, currentPage - 1)
|
|
|
"
|
|
|
:disabled="currentPage <= 1"
|
|
|
@@ -343,7 +289,7 @@
|
|
|
v-if="currentPage > 2"
|
|
|
@click="
|
|
|
isSearchMode
|
|
|
- ? handleSearch(1)
|
|
|
+ ? handleSearch(currentSearchKeyword, 1)
|
|
|
: loadVideosByTag(selectedMenu, 1)
|
|
|
"
|
|
|
class="px-2 py-2 rounded-lg bg-white/5 border border-white/10 text-white/70 hover:bg-white/10 hover:text-white transition text-sm"
|
|
|
@@ -361,7 +307,7 @@
|
|
|
v-if="currentPage > 1"
|
|
|
@click="
|
|
|
isSearchMode
|
|
|
- ? handleSearch(currentPage - 1)
|
|
|
+ ? handleSearch(currentSearchKeyword, currentPage - 1)
|
|
|
: loadVideosByTag(selectedMenu, currentPage - 1)
|
|
|
"
|
|
|
class="px-2 py-2 rounded-lg bg-white/5 border border-white/10 text-white/70 hover:bg-white/10 hover:text-white transition text-sm"
|
|
|
@@ -381,7 +327,7 @@
|
|
|
v-if="currentPage < totalPages"
|
|
|
@click="
|
|
|
isSearchMode
|
|
|
- ? handleSearch(currentPage + 1)
|
|
|
+ ? handleSearch(currentSearchKeyword, currentPage + 1)
|
|
|
: loadVideosByTag(selectedMenu, currentPage + 1)
|
|
|
"
|
|
|
class="px-2 py-2 rounded-lg bg-white/5 border border-white/10 text-white/70 hover:bg-white/10 hover:text-white transition text-sm"
|
|
|
@@ -401,7 +347,7 @@
|
|
|
v-if="currentPage < totalPages - 1"
|
|
|
@click="
|
|
|
isSearchMode
|
|
|
- ? handleSearch(totalPages)
|
|
|
+ ? handleSearch(currentSearchKeyword, totalPages)
|
|
|
: loadVideosByTag(selectedMenu, totalPages)
|
|
|
"
|
|
|
class="px-2 py-2 rounded-lg bg-white/5 border border-white/10 text-white/70 hover:bg-white/10 hover:text-white transition text-sm"
|
|
|
@@ -425,7 +371,7 @@
|
|
|
<button
|
|
|
@click="
|
|
|
isSearchMode
|
|
|
- ? handleSearch(currentPage + 1)
|
|
|
+ ? handleSearch(currentSearchKeyword, currentPage + 1)
|
|
|
: loadVideosByTag(selectedMenu, currentPage + 1)
|
|
|
"
|
|
|
:disabled="currentPage >= totalPages"
|
|
|
@@ -447,7 +393,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, onMounted } from "vue";
|
|
|
+import { ref, onMounted, onBeforeUnmount } from "vue";
|
|
|
import { useRouter } from "vue-router";
|
|
|
import { searchVideoByTags, searchVideoByKeyword } from "@/services/api";
|
|
|
import { videoMenus as fixedVideoMenus } from "@/data/videoMenus";
|
|
|
@@ -502,8 +448,8 @@ const selectedSort = ref<string>("time");
|
|
|
const showAllTags = ref(false);
|
|
|
|
|
|
// 搜索相关
|
|
|
-const searchKeyword = ref("");
|
|
|
const isSearchMode = ref(false);
|
|
|
+const currentSearchKeyword = ref("");
|
|
|
|
|
|
// 格式化时长
|
|
|
const formatDuration = (duration: string | number): string => {
|
|
|
@@ -564,7 +510,7 @@ const jumpToPageHandler = () => {
|
|
|
try {
|
|
|
if (isSearchMode.value) {
|
|
|
console.log("搜索模式,执行搜索跳转");
|
|
|
- handleSearch(page);
|
|
|
+ handleSearch(currentSearchKeyword.value, page);
|
|
|
} else {
|
|
|
console.log("标签模式,执行标签跳转");
|
|
|
loadVideosByTag(selectedMenu.value || "", page);
|
|
|
@@ -589,7 +535,7 @@ const selectSort = async (sort: string) => {
|
|
|
// 重新查询当前显示的内容
|
|
|
if (isSearchMode.value) {
|
|
|
// 如果是搜索模式,重新执行搜索
|
|
|
- await handleSearch(1);
|
|
|
+ await handleSearch(currentSearchKeyword.value, 1);
|
|
|
} else if (selectedMenu.value) {
|
|
|
// 如果选择了特定菜单,按菜单查询
|
|
|
await loadVideosByTag(selectedMenu.value, 1);
|
|
|
@@ -619,17 +565,24 @@ const toggleTags = () => {
|
|
|
};
|
|
|
|
|
|
// 搜索功能
|
|
|
-const handleSearch = async (page = 1) => {
|
|
|
- if (!searchKeyword.value.trim()) return;
|
|
|
+const handleSearch = async (keyword: string, page = 1) => {
|
|
|
+ if (!keyword.trim()) {
|
|
|
+ // 如果关键词为空,清除搜索模式
|
|
|
+ isSearchMode.value = false;
|
|
|
+ currentSearchKeyword.value = "";
|
|
|
+ loadVideosByTag("");
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
isSearchMode.value = true;
|
|
|
+ currentSearchKeyword.value = keyword.trim();
|
|
|
loading.value = true;
|
|
|
currentPage.value = page;
|
|
|
|
|
|
try {
|
|
|
const response = await searchVideoByKeyword(
|
|
|
device,
|
|
|
- searchKeyword.value.trim(),
|
|
|
+ keyword.trim(),
|
|
|
page,
|
|
|
pageSize.value,
|
|
|
"long",
|
|
|
@@ -658,14 +611,6 @@ const handleSearch = async (page = 1) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-// 清除搜索
|
|
|
-const clearSearch = () => {
|
|
|
- searchKeyword.value = "";
|
|
|
- isSearchMode.value = false;
|
|
|
- // 恢复默认显示(加载所有视频)
|
|
|
- loadVideosByTag("");
|
|
|
-};
|
|
|
-
|
|
|
// 播放视频
|
|
|
const playVideo = (video: any) => {
|
|
|
const vipLevel = userStore.getVipLevel();
|
|
|
@@ -738,8 +683,24 @@ const initializeVideoMenus = async () => {
|
|
|
await loadVideosByTag("");
|
|
|
};
|
|
|
|
|
|
+// 监听Header搜索事件
|
|
|
+const handleHeaderSearch = (event: CustomEvent) => {
|
|
|
+ const { keyword } = event.detail;
|
|
|
+ handleSearch(keyword);
|
|
|
+};
|
|
|
+
|
|
|
onMounted(() => {
|
|
|
initializeVideoMenus();
|
|
|
+ // 监听Header搜索事件
|
|
|
+ window.addEventListener("header-search", handleHeaderSearch as EventListener);
|
|
|
+});
|
|
|
+
|
|
|
+onBeforeUnmount(() => {
|
|
|
+ // 清理事件监听器
|
|
|
+ window.removeEventListener(
|
|
|
+ "header-search",
|
|
|
+ handleHeaderSearch as EventListener
|
|
|
+ );
|
|
|
});
|
|
|
</script>
|
|
|
|