feat:聚合搜索(working...)

This commit is contained in:
jxxghp
2024-06-02 11:13:03 +08:00
parent c6702fbc18
commit a2d28ad360
5 changed files with 131 additions and 110 deletions

View File

@@ -19,7 +19,6 @@
] ]
}, },
"dependencies": { "dependencies": {
"@bytebase/vue-kbar": "^0.1.8",
"@fullcalendar/core": "^6.1.8", "@fullcalendar/core": "^6.1.8",
"@fullcalendar/daygrid": "^6.1.8", "@fullcalendar/daygrid": "^6.1.8",
"@fullcalendar/interaction": "^6.1.7", "@fullcalendar/interaction": "^6.1.7",

View File

@@ -14,7 +14,10 @@ function onClick() {
</script> </script>
<template> <template>
<IconBtn :class="props.innerClass ? props.innerClass : 'absolute right-3 top-3'" @click.stop="onClick"> <IconBtn
:class="props.innerClass ? props.innerClass : 'absolute right-3 top-3'"
@click.stop="onClick"
>
<VIcon icon="mdi-close" /> <VIcon icon="mdi-close" />
</IconBtn> </IconBtn>
</template> </template>

View File

@@ -2,8 +2,6 @@
import VerticalNavSectionTitle from '@/@layouts/components/VerticalNavSectionTitle.vue' import VerticalNavSectionTitle from '@/@layouts/components/VerticalNavSectionTitle.vue'
import VerticalNavLayout from '@layouts/components/VerticalNavLayout.vue' import VerticalNavLayout from '@layouts/components/VerticalNavLayout.vue'
import VerticalNavLink from '@layouts/components/VerticalNavLink.vue' import VerticalNavLink from '@layouts/components/VerticalNavLink.vue'
// Components
import Footer from '@/layouts/components/Footer.vue' import Footer from '@/layouts/components/Footer.vue'
import NavbarThemeSwitcher from '@/layouts/components/NavbarThemeSwitcher.vue' import NavbarThemeSwitcher from '@/layouts/components/NavbarThemeSwitcher.vue'
import UserNofification from '@/layouts/components/UserNotification.vue' import UserNofification from '@/layouts/components/UserNotification.vue'
@@ -25,21 +23,16 @@ const superUser = store.state.auth.superUser
<IconBtn class="ms-n2 d-lg-none" @click="toggleVerticalOverlayNavActive(true)"> <IconBtn class="ms-n2 d-lg-none" @click="toggleVerticalOverlayNavActive(true)">
<VIcon icon="mdi-menu" /> <VIcon icon="mdi-menu" />
</IconBtn> </IconBtn>
<!-- 👉 Search Bar --> <!-- 👉 Search Bar -->
<SearchBar /> <SearchBar />
<!-- 👉 Spacer -->
<VSpacer /> <VSpacer />
<!-- 👉 Shortcuts --> <!-- 👉 Shortcuts -->
<ShortcutBar v-if="superUser" /> <ShortcutBar v-if="superUser" />
<!-- 👉 Theme --> <!-- 👉 Theme -->
<NavbarThemeSwitcher /> <NavbarThemeSwitcher />
<!-- 👉 Notification --> <!-- 👉 Notification -->
<UserNofification /> <UserNofification />
<!-- 👉 UserProfile --> <!-- 👉 UserProfile -->
<UserProfile /> <UserProfile />
</div> </div>
@@ -53,7 +46,6 @@ const superUser = store.state.auth.superUser
to: '/dashboard', to: '/dashboard',
}" }"
/> />
<!-- 👉 发现 --> <!-- 👉 发现 -->
<VerticalNavSectionTitle <VerticalNavSectionTitle
:item="{ :item="{
@@ -74,7 +66,6 @@ const superUser = store.state.auth.superUser
to: '/resource', to: '/resource',
}" }"
/> />
<!-- 👉 订阅 --> <!-- 👉 订阅 -->
<VerticalNavSectionTitle <VerticalNavSectionTitle
:item="{ :item="{
@@ -131,7 +122,6 @@ const superUser = store.state.auth.superUser
to: '/filemanager', to: '/filemanager',
}" }"
/> />
<!-- 👉 系统 --> <!-- 👉 系统 -->
<VerticalNavSectionTitle <VerticalNavSectionTitle
v-if="superUser" v-if="superUser"
@@ -166,10 +156,8 @@ const superUser = store.state.auth.superUser
</template> </template>
<template #after-vertical-nav-items /> <template #after-vertical-nav-items />
<!-- 👉 Pages --> <!-- 👉 Pages -->
<slot /> <slot />
<!-- 👉 Footer --> <!-- 👉 Footer -->
<template #footer> <template #footer>
<Footer /> <Footer />

View File

@@ -1,109 +1,33 @@
<script lang="ts" setup> <script lang="ts" setup>
// 路由 import SearchBarView from '@/views/system/SearchBarView.vue'
const router = useRouter()
// 搜索词
const searchWord = ref(null)
// 搜索弹窗
const searchDialog = ref(false) const searchDialog = ref(false)
// ref
const searchWordInput = ref<HTMLElement | null>(null)
// 当前的搜索类型 media/person
const searchType = ref('media')
// 搜索提示词列表
const searchHintList = ref<string[]>([])
// Search
function search() {
if (!searchWord.value) return
if (!searchHintList.value.includes(searchWord.value)) searchHintList.value.push(searchWord.value)
searchDialog.value = false
router.push({
path: '/browse/media/search',
query: {
title: searchWord.value,
type: searchType.value,
},
})
}
// 切换搜索类型
function switchSearchType() {
searchType.value = searchType.value === 'media' ? 'person' : 'media'
}
// 打开搜索弹窗
function openSearchDialog() { function openSearchDialog() {
searchDialog.value = true searchDialog.value = true
nextTick(() => {
searchWordInput.value?.focus()
})
} }
</script> </script>
<template> <template>
<!-- 👉 Search Button -->
<div class="d-flex align-center cursor-pointer" style="user-select: none">
<VDialog v-model="searchDialog" max-width="50rem" transition="dialog-top-transition">
<!-- Dialog Content -->
<VCard title="搜索">
<VCardText>
<VRow>
<VCol cols="12">
<VCombobox
ref="searchWordInput"
v-model="searchWord"
:items="searchHintList"
:prepend-inner-icon="searchType == 'person' ? 'mdi-account' : 'mdi-movie'"
:label="searchType == 'person' ? '搜索演员' : '搜索电影、电视剧'"
@keydown.enter="search"
@click:prepend-inner="switchSearchType"
clearable
/>
</VCol>
</VRow>
</VCardText>
<VCardActions>
<VSpacer />
<VBtn variant="tonal" @click="search"> 搜索 </VBtn>
</VCardActions>
</VCard>
</VDialog>
</div>
<!-- 👉 Search Icon --> <!-- 👉 Search Icon -->
<IconBtn class="d-md-none" @click="openSearchDialog"> <div class="d-flex align-center cursor-pointer ms-lg-n2" style="user-select: none">
<VIcon icon="mdi-magnify" /> <IconBtn @click="openSearchDialog">
</IconBtn> <VIcon icon="ri-search-line" />
<!-- 👉 Search Textfield --> </IconBtn>
<span class="w-full me-3"> <span class="d-none d-md-flex align-center text-disabled ms-2" @click="openSearchDialog">
<VCombobox <span class="me-3">搜索</span>
key="search_navbar" <span class="meta-key">K</span>
v-model="searchWord" </span>
:items="searchHintList" </div>
class="d-none d-md-block text-disabled search-box" <!-- 搜索弹窗 -->
density="compact" <SearchBarView v-model="searchDialog" @close="searchDialog = false" />
variant="solo"
:prepend-inner-icon="searchType == 'person' ? 'mdi-account' : 'mdi-movie'"
:label="searchType == 'person' ? '搜索演员' : '搜索电影、电视剧'"
append-inner-icon="mdi-magnify"
single-line
hide-details
flat
rounded
@click:append-inner="search"
@click:prepend-inner="switchSearchType"
@keydown.enter="search"
/>
</span>
</template> </template>
<style type="scss" scoped>
<style lang="scss"> .meta-key {
.search-box div.v-input__control div[role='textbox'] { border: thin solid rgba(var(--v-border-color), var(--v-border-opacity));
border: 1px solid rgb(var(--v-theme-background)); border-radius: 6px;
block-size: 1.75rem;
padding-block: 0.1rem;
padding-inline: 0.25rem;
} }
</style> </style>

View File

@@ -0,0 +1,107 @@
<script setup lang="ts">
// 路由
const router = useRouter()
// 定义事件
const emit = defineEmits(['close'])
// 搜索词
const searchWord = ref(null)
// ref
const searchWordInput = ref<HTMLElement | null>(null)
// 搜索提示词列表
const searchHintList = ref<string[]>([])
// Search
function search(searchType: string) {
// 搜索类型 media/person
if (!searchWord.value) return
if (!searchHintList.value.includes(searchWord.value)) searchHintList.value.push(searchWord.value)
router.push({
path: '/browse/media/search',
query: {
title: searchWord.value,
type: searchType,
},
})
emit('close')
}
onMounted(() => {
setTimeout(() => {
searchWordInput.value?.focus()
}, 500)
})
</script>
<template>
<VDialog max-width="40rem">
<VCard>
<VCardText class="pe-12">
<VCombobox
ref="searchWordInput"
v-model="searchWord"
density="compact"
variant="plain"
class="text-high-emphasis"
placeholder="搜索 ..."
:items="searchHintList"
>
<template #prepend>
<VIcon icon="ri-search-line" style="opacity: 1" />
</template>
</VCombobox>
</VCardText>
<DialogCloseBtn inner-class="absolute right-3 top-5 text-high-emphasis" @click="emit('close')" />
<VDivider />
<div class="ps h-100">
<VList lines="one" v-if="searchWord">
<!-- 搜索结果 -->
<VListSubheader v-if="searchWord"> 媒体 </VListSubheader>
<VHover>
<template #default="hover">
<VListItem
prepend-icon="mdi-movie-search"
density="compact"
link
v-bind="hover.props"
@click="search('media')"
>
<VListItemTitle>
搜索 <span class="font-bold">{{ searchWord }} </span> 相关的电影电视剧
</VListItemTitle>
<template #append>
<VIcon v-if="hover.isHovering" icon="ri-corner-down-left-line" />
</template>
</VListItem>
</template>
</VHover>
<VHover>
<template #default="hover">
<VListItem
prepend-icon="mdi-people"
density="compact"
link
v-bind="hover.props"
@click="search('person')"
>
<VListItemTitle>
搜索 <span class="font-bold">{{ searchWord }}</span> 相关的人物
</VListItemTitle>
<template #append>
<VIcon v-if="hover.isHovering" icon="ri-corner-down-left-line" />
</template>
</VListItem>
</template>
</VHover>
<VListSubheader v-if="searchWord"> 功能 </VListSubheader>
<VListSubheader v-if="searchWord"> 插件 </VListSubheader>
</VList>
<div v-else>
<!-- 默认 -->
</div>
</div>
</VCard>
</VDialog>
</template>