mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-06-28 02:51:56 +08:00
fix 聚合搜索
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
"express": "^4.18.2",
|
||||
"express-http-proxy": "^2.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"mousetrap": "^1.6.5",
|
||||
"nprogress": "^0.2.0",
|
||||
"qrcode.vue": "^3.4.1",
|
||||
"sass": "^1.59.3",
|
||||
@@ -100,4 +101,4 @@
|
||||
"resolutions": {
|
||||
"postcss": "8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,6 +445,8 @@ export interface Plugin {
|
||||
history?: { [key: string]: string }
|
||||
// 添加时间
|
||||
add_time?: number
|
||||
// 页面打开状态
|
||||
page_open?: boolean
|
||||
}
|
||||
|
||||
// 渲染结构
|
||||
|
||||
@@ -365,11 +365,19 @@ const dropdownItems = ref([
|
||||
// 监听插件状态变化
|
||||
watch(
|
||||
() => props.plugin?.has_update,
|
||||
(newHasUpdate, oldHasUpdate) => {
|
||||
(newHasUpdate, _) => {
|
||||
const updateItemIndex = dropdownItems.value.findIndex(item => item.value === 3)
|
||||
if (updateItemIndex !== -1) dropdownItems.value[updateItemIndex].show = newHasUpdate
|
||||
},
|
||||
)
|
||||
|
||||
// 监听插件窗口状态变化
|
||||
watch(
|
||||
() => props.plugin?.page_open,
|
||||
(newOpenState, _) => {
|
||||
if (newOpenState) openPluginDetail()
|
||||
},
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
<script lang="ts" setup>
|
||||
import * as Mousetrap from 'mousetrap'
|
||||
import SearchBarView from '@/views/system/SearchBarView.vue'
|
||||
|
||||
const searchDialog = ref(false)
|
||||
|
||||
// 注册快捷键
|
||||
Mousetrap.bind(['command+k', 'ctrl+k'], openSearchDialog)
|
||||
|
||||
// 打开搜索弹窗
|
||||
function openSearchDialog() {
|
||||
searchDialog.value = true
|
||||
return false
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -20,7 +26,7 @@ function openSearchDialog() {
|
||||
</span>
|
||||
</div>
|
||||
<!-- 搜索弹窗 -->
|
||||
<SearchBarView v-model="searchDialog" @close="searchDialog = false" />
|
||||
<SearchBarView v-model="searchDialog" v-if="searchDialog" @close="searchDialog = false" />
|
||||
</template>
|
||||
<style type="scss" scoped>
|
||||
.meta-key {
|
||||
|
||||
@@ -22,6 +22,9 @@ let deferApp = (_: number) => true
|
||||
// 当前标签
|
||||
const activeTab = ref(route.query.tab)
|
||||
|
||||
// 插件ID参数
|
||||
const pluginId = ref(route.query.id)
|
||||
|
||||
// 标签页
|
||||
const tabs = [
|
||||
{
|
||||
@@ -330,6 +333,13 @@ function jumpTab(tab: string) {
|
||||
onBeforeMount(async () => {
|
||||
await refreshData()
|
||||
getPluginStatistics()
|
||||
if (activeTab.value != 'market' && pluginId.value) {
|
||||
// 找到这个插件
|
||||
const plugin = dataList.value.find(item => item.id === pluginId.value)
|
||||
if (plugin) {
|
||||
plugin.page_open = true
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import api from '@/api'
|
||||
import type { Plugin } from '@/api/types'
|
||||
|
||||
// 路由
|
||||
const router = useRouter()
|
||||
|
||||
@@ -14,8 +17,69 @@ const searchWordInput = ref<HTMLElement | null>(null)
|
||||
// 搜索提示词列表
|
||||
const searchHintList = ref<string[]>([])
|
||||
|
||||
// Search
|
||||
function search(searchType: string) {
|
||||
// 所有菜单功能
|
||||
const menuItems = ref([])
|
||||
|
||||
// 常用菜单功能
|
||||
const commonMenuItems = ref([
|
||||
{
|
||||
title: '搜索设置',
|
||||
icon: 'mdi-magnify',
|
||||
to: 'setting?tab=search',
|
||||
},
|
||||
{
|
||||
title: '订阅设置',
|
||||
icon: 'mdi-rss',
|
||||
to: 'setting?tab=subscribe',
|
||||
},
|
||||
{
|
||||
title: '服务',
|
||||
icon: 'mdi-list-box',
|
||||
to: 'setting?tab=service',
|
||||
},
|
||||
{
|
||||
title: '词表',
|
||||
icon: 'mdi-file-word-box',
|
||||
to: 'setting?tab=words',
|
||||
},
|
||||
{
|
||||
title: '历史记录',
|
||||
icon: 'mdi-history',
|
||||
to: 'history',
|
||||
},
|
||||
])
|
||||
|
||||
// 所有插件(已安装)
|
||||
const pluginItems = ref<Plugin[]>([])
|
||||
|
||||
// 匹配的菜单列表
|
||||
const matchedMenuItems = ref([])
|
||||
|
||||
// 获取插件列表数据
|
||||
async function fetchInstalledPlugins() {
|
||||
try {
|
||||
pluginItems.value = await api.get('plugin/', {
|
||||
params: {
|
||||
state: 'installed',
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
// 区配的插件列表
|
||||
const matchedPluginItems = computed(() => {
|
||||
if (!searchWord.value) return []
|
||||
const lowerWord = searchWord.value?.toLowerCase()
|
||||
return pluginItems.value.filter((item: Plugin) => {
|
||||
if (!item.plugin_name && !item.plugin_desc) return false
|
||||
return item.plugin_name?.toLowerCase().includes(lowerWord) || item.plugin_desc?.toLowerCase().includes(lowerWord)
|
||||
})
|
||||
})
|
||||
|
||||
// 跳转媒体搜索页面
|
||||
function searchMedia(searchType: string) {
|
||||
// 搜索类型 media/person
|
||||
if (!searchWord.value) return
|
||||
if (!searchHintList.value.includes(searchWord.value)) searchHintList.value.push(searchWord.value)
|
||||
@@ -29,10 +93,29 @@ function search(searchType: string) {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
// 跳转插件页面
|
||||
function showPlugin(pluginId: string) {
|
||||
router.push({
|
||||
path: `/plugins/`,
|
||||
query: {
|
||||
tab: 'installed',
|
||||
id: pluginId,
|
||||
},
|
||||
})
|
||||
emit('close')
|
||||
}
|
||||
|
||||
// 跳转菜单页面
|
||||
function goPage(to: string) {
|
||||
router.push(to)
|
||||
emit('close')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
searchWordInput.value?.focus()
|
||||
}, 500)
|
||||
fetchInstalledPlugins()
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
@@ -47,6 +130,7 @@ onMounted(() => {
|
||||
class="text-high-emphasis"
|
||||
placeholder="搜索 ..."
|
||||
:items="searchHintList"
|
||||
@keydown.enter="searchMedia('media')"
|
||||
>
|
||||
<template #prepend>
|
||||
<VIcon icon="ri-search-line" style="opacity: 1" />
|
||||
@@ -66,7 +150,7 @@ onMounted(() => {
|
||||
density="compact"
|
||||
link
|
||||
v-bind="hover.props"
|
||||
@click="search('media')"
|
||||
@click="searchMedia('media')"
|
||||
>
|
||||
<VListItemTitle>
|
||||
搜索 <span class="font-bold">{{ searchWord }} </span> 相关的电影、电视剧
|
||||
@@ -80,11 +164,11 @@ onMounted(() => {
|
||||
<VHover>
|
||||
<template #default="hover">
|
||||
<VListItem
|
||||
prepend-icon="mdi-people"
|
||||
prepend-icon="mdi-account-search"
|
||||
density="compact"
|
||||
link
|
||||
v-bind="hover.props"
|
||||
@click="search('person')"
|
||||
@click="searchMedia('person')"
|
||||
>
|
||||
<VListItemTitle>
|
||||
搜索 <span class="font-bold">{{ searchWord }}</span> 相关的人物
|
||||
@@ -95,11 +179,78 @@ onMounted(() => {
|
||||
</VListItem>
|
||||
</template>
|
||||
</VHover>
|
||||
<VListSubheader v-if="searchWord"> 功能 </VListSubheader>
|
||||
<VListSubheader v-if="searchWord"> 插件 </VListSubheader>
|
||||
<VListSubheader v-if="matchedMenuItems.length > 0"> 功能 </VListSubheader>
|
||||
<VListSubheader v-if="matchedPluginItems.length > 0"> 插件 </VListSubheader>
|
||||
<VHover v-if="matchedPluginItems.length > 0" v-for="plugin in matchedPluginItems" :key="plugin.id">
|
||||
<template #default="hover">
|
||||
<VListItem
|
||||
prepend-icon="mdi-puzzle"
|
||||
density="compact"
|
||||
link
|
||||
v-bind="hover.props"
|
||||
@click="showPlugin(plugin.id ?? '')"
|
||||
>
|
||||
<VListItemTitle> {{ plugin.plugin_name }} </VListItemTitle>
|
||||
<VListItemSubtitle> {{ plugin.plugin_desc }} </VListItemSubtitle>
|
||||
<template #append>
|
||||
<VIcon v-if="hover.isHovering" icon="ri-corner-down-left-line" />
|
||||
</template>
|
||||
</VListItem>
|
||||
</template>
|
||||
</VHover>
|
||||
</VList>
|
||||
<div v-else>
|
||||
<!-- 默认 -->
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol cols="12" md="6">
|
||||
<p class="custom-letter-spacing text-sm text-disabled text-uppercase py-2 px-4 mb-0">常用功能</p>
|
||||
<VList lines="one">
|
||||
<VHover v-for="(menu, index) in commonMenuItems" :key="index">
|
||||
<template #default="hover">
|
||||
<VListItem
|
||||
:prepend-icon="menu.icon"
|
||||
density="compact"
|
||||
link
|
||||
v-bind="hover.props"
|
||||
@click="goPage(menu.to)"
|
||||
>
|
||||
<VListItemTitle>
|
||||
{{ menu.title }}
|
||||
</VListItemTitle>
|
||||
<template #append>
|
||||
<VIcon v-if="hover.isHovering" icon="ri-corner-down-left-line" />
|
||||
</template>
|
||||
</VListItem>
|
||||
</template>
|
||||
</VHover>
|
||||
</VList>
|
||||
</VCol>
|
||||
<VCol cols="12" md="6">
|
||||
<p class="custom-letter-spacing text-sm text-disabled text-uppercase py-2 px-4 mb-0">常用插件</p>
|
||||
<VList lines="one">
|
||||
<VHover v-for="plugin in pluginItems.slice(0, 5)" :key="plugin.id">
|
||||
<template #default="hover">
|
||||
<VListItem
|
||||
prepend-icon="mdi-package-variant"
|
||||
density="compact"
|
||||
link
|
||||
v-bind="hover.props"
|
||||
@click="showPlugin(plugin.id ?? '')"
|
||||
>
|
||||
<VListItemTitle> {{ plugin.plugin_name }} </VListItemTitle>
|
||||
<template #append>
|
||||
<VIcon v-if="hover.isHovering" icon="ri-corner-down-left-line" />
|
||||
</template>
|
||||
</VListItem>
|
||||
</template>
|
||||
</VHover>
|
||||
</VList>
|
||||
</VCol>
|
||||
<VCol cols="12" md="6"> </VCol>
|
||||
<VCol cols="12" md="6"> </VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
</div>
|
||||
</div>
|
||||
</VCard>
|
||||
|
||||
59
yarn.lock
59
yarn.lock
@@ -1023,13 +1023,6 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@babel/runtime@^7.23.8":
|
||||
version "7.24.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.6.tgz#5b76eb89ad45e2e4a0a8db54c456251469a3358e"
|
||||
integrity sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@babel/template@^7.22.15", "@babel/template@^7.23.9", "@babel/template@^7.24.0":
|
||||
version "7.24.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50"
|
||||
@@ -1064,15 +1057,6 @@
|
||||
"@babel/helper-validator-identifier" "^7.22.20"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@bytebase/vue-kbar@^0.1.8":
|
||||
version "0.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@bytebase/vue-kbar/-/vue-kbar-0.1.8.tgz#79b0cab21e9c013cb8935aa5d94be76fa9e0be3e"
|
||||
integrity sha512-XfF3JadEvWzFngpu1U6C3RvseBEoWXF51Y0D3gL2R7T8Lx+OHEoPCR8jxCMXzROCCJ+eheerKqEiFl5WXrWw4w==
|
||||
dependencies:
|
||||
"@vueuse/core" "^7.1.2"
|
||||
match-sorter "^6.3.1"
|
||||
tiny-invariant "^1.2.0"
|
||||
|
||||
"@csstools/css-parser-algorithms@^2.6.1":
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.6.1.tgz#c45440d1efa2954006748a01697072dae5881bcd"
|
||||
@@ -2201,14 +2185,6 @@
|
||||
"@vueuse/shared" "10.9.0"
|
||||
vue-demi ">=0.14.7"
|
||||
|
||||
"@vueuse/core@^7.1.2":
|
||||
version "7.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-7.7.1.tgz#fc284f4103de73c7fb79bc06579d8066790db511"
|
||||
integrity sha512-PRRgbATMpoeUmkCEBtUeJgOwtew8s+4UsEd+Pm7MhkjL2ihCNrSqxNVtM6NFE4uP2sWnkGcZpCjPuNSxowJ1Ow==
|
||||
dependencies:
|
||||
"@vueuse/shared" "7.7.1"
|
||||
vue-demi "*"
|
||||
|
||||
"@vueuse/math@^10.1.2":
|
||||
version "10.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/math/-/math-10.9.0.tgz#0db3cb27c893fa22c50351397c283d5b6df0f5bc"
|
||||
@@ -2229,13 +2205,6 @@
|
||||
dependencies:
|
||||
vue-demi ">=0.14.7"
|
||||
|
||||
"@vueuse/shared@7.7.1":
|
||||
version "7.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-7.7.1.tgz#77e312de7275380efce86b0079bd7938791a076b"
|
||||
integrity sha512-rN2qd22AUl7VdBxihagWyhUNHCyVk9IpvBTTfHoLH9G7rGE552X1f+zeCfehuno0zXif13jPw+icW/wn2a0rnQ==
|
||||
dependencies:
|
||||
vue-demi "*"
|
||||
|
||||
accepts@~1.3.8:
|
||||
version "1.3.8"
|
||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
|
||||
@@ -5104,14 +5073,6 @@ magic-string@^0.30.2, magic-string@^0.30.3, magic-string@^0.30.5, magic-string@^
|
||||
dependencies:
|
||||
"@jridgewell/sourcemap-codec" "^1.4.15"
|
||||
|
||||
match-sorter@^6.3.1:
|
||||
version "6.3.4"
|
||||
resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-6.3.4.tgz#afa779d8e922c81971fbcb4781c7003ace781be7"
|
||||
integrity sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.23.8"
|
||||
remove-accents "0.5.0"
|
||||
|
||||
mathml-tag-names@^2.1.3:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3"
|
||||
@@ -5294,6 +5255,11 @@ mlly@^1.2.0, mlly@^1.4.2, mlly@^1.5.0:
|
||||
pkg-types "^1.0.3"
|
||||
ufo "^1.3.2"
|
||||
|
||||
mousetrap@^1.6.5:
|
||||
version "1.6.5"
|
||||
resolved "https://registry.yarnpkg.com/mousetrap/-/mousetrap-1.6.5.tgz#8a766d8c272b08393d5f56074e0b5ec183485bf9"
|
||||
integrity sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA==
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
@@ -6008,11 +5974,6 @@ regjsparser@^0.9.1:
|
||||
dependencies:
|
||||
jsesc "~0.5.0"
|
||||
|
||||
remove-accents@0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.5.0.tgz#77991f37ba212afba162e375b627631315bed687"
|
||||
integrity sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==
|
||||
|
||||
request@^2.44.0:
|
||||
version "2.88.2"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
||||
@@ -6857,11 +6818,6 @@ through@^2.3.4:
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
|
||||
|
||||
tiny-invariant@^1.2.0:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127"
|
||||
integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==
|
||||
|
||||
to-fast-properties@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
|
||||
@@ -7288,11 +7244,6 @@ vite@^5.2.8:
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.3"
|
||||
|
||||
vue-demi@*:
|
||||
version "0.14.8"
|
||||
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.8.tgz#00335e9317b45e4a68d3528aaf58e0cec3d5640a"
|
||||
integrity sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==
|
||||
|
||||
vue-demi@>=0.14.7:
|
||||
version "0.14.7"
|
||||
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.7.tgz#8317536b3ef74c5b09f268f7782e70194567d8f2"
|
||||
|
||||
Reference in New Issue
Block a user