mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 23:56:42 +08:00
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "moviepilot",
|
"name": "moviepilot",
|
||||||
"version": "2.5.5",
|
"version": "2.5.5-1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"bin": "dist/service.js",
|
"bin": "dist/service.js",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { useUserStore } from '@/stores'
|
|||||||
import SearchSiteDialog from '@/components/dialog/SearchSiteDialog.vue'
|
import SearchSiteDialog from '@/components/dialog/SearchSiteDialog.vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useDisplay } from 'vuetify'
|
import { useDisplay } from 'vuetify'
|
||||||
|
import { hasPermission, filterMenusByPermission } from '@/utils/permission'
|
||||||
|
|
||||||
// 显示器宽度
|
// 显示器宽度
|
||||||
const display = useDisplay()
|
const display = useDisplay()
|
||||||
@@ -31,6 +32,37 @@ const superUser = userStore.superUser
|
|||||||
// 当前用户名
|
// 当前用户名
|
||||||
const userName = userStore.userName
|
const userName = userStore.userName
|
||||||
|
|
||||||
|
// 权限检查
|
||||||
|
const hasSearchPermission = computed(() => {
|
||||||
|
return hasPermission(
|
||||||
|
{
|
||||||
|
is_superuser: userStore.superUser,
|
||||||
|
...userStore.permissions,
|
||||||
|
},
|
||||||
|
'search',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const hasSubscribePermission = computed(() => {
|
||||||
|
return hasPermission(
|
||||||
|
{
|
||||||
|
is_superuser: userStore.superUser,
|
||||||
|
...userStore.permissions,
|
||||||
|
},
|
||||||
|
'subscribe',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const hasManagePermission = computed(() => {
|
||||||
|
return hasPermission(
|
||||||
|
{
|
||||||
|
is_superuser: userStore.superUser,
|
||||||
|
...userStore.permissions,
|
||||||
|
},
|
||||||
|
'manage',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
// 所有订阅数据
|
// 所有订阅数据
|
||||||
const SubscribeItems = ref<Subscribe[]>([])
|
const SubscribeItems = ref<Subscribe[]>([])
|
||||||
|
|
||||||
@@ -109,18 +141,27 @@ function getMenus(): NavMenu[] {
|
|||||||
return menus
|
return menus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取用户权限信息
|
||||||
|
const userPermissions = computed(() => ({
|
||||||
|
is_superuser: userStore.superUser,
|
||||||
|
...userStore.permissions,
|
||||||
|
}))
|
||||||
|
|
||||||
// 匹配的菜单列表
|
// 匹配的菜单列表
|
||||||
const matchedMenuItems = computed(() => {
|
const matchedMenuItems = computed(() => {
|
||||||
if (!searchWord.value) return []
|
if (!searchWord.value) return []
|
||||||
if (!superUser) return []
|
|
||||||
const lowerWord = (searchWord.value as string).toLowerCase()
|
const lowerWord = (searchWord.value as string).toLowerCase()
|
||||||
const menuItems = getMenus()
|
const menuItems = getMenus()
|
||||||
if (menuItems)
|
if (menuItems) {
|
||||||
return menuItems.filter(
|
// 先根据用户权限过滤菜单
|
||||||
|
const filteredMenus = filterMenusByPermission(menuItems, userPermissions.value)
|
||||||
|
// 再根据搜索词过滤
|
||||||
|
return filteredMenus.filter(
|
||||||
item =>
|
item =>
|
||||||
item.title.toLowerCase().includes(lowerWord) ||
|
item.title.toLowerCase().includes(lowerWord) ||
|
||||||
(item.description && item.description.toLowerCase().includes(lowerWord)),
|
(item.description && item.description.toLowerCase().includes(lowerWord)),
|
||||||
)
|
)
|
||||||
|
}
|
||||||
return []
|
return []
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -140,10 +181,10 @@ async function fetchInstalledPlugins() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 区配的插件列表
|
// 匹配的插件列表
|
||||||
const matchedPluginItems = computed(() => {
|
const matchedPluginItems = computed(() => {
|
||||||
if (!searchWord.value) return []
|
if (!searchWord.value) return []
|
||||||
if (!superUser) return []
|
if (!hasManagePermission.value) return []
|
||||||
const lowerWord = (searchWord.value as string).toLowerCase()
|
const lowerWord = (searchWord.value as string).toLowerCase()
|
||||||
return pluginItems.value.filter((item: Plugin) => {
|
return pluginItems.value.filter((item: Plugin) => {
|
||||||
if (!item.plugin_name && !item.plugin_desc) return false
|
if (!item.plugin_name && !item.plugin_desc) return false
|
||||||
@@ -196,6 +237,7 @@ const openSiteDialog = () => {
|
|||||||
// 匹配的订阅列表
|
// 匹配的订阅列表
|
||||||
const matchedSubscribeItems = computed(() => {
|
const matchedSubscribeItems = computed(() => {
|
||||||
if (!searchWord.value) return []
|
if (!searchWord.value) return []
|
||||||
|
if (!hasSubscribePermission.value) return []
|
||||||
const lowerWord = (searchWord.value as string).toLowerCase()
|
const lowerWord = (searchWord.value as string).toLowerCase()
|
||||||
return SubscribeItems.value.filter((item: Subscribe) => {
|
return SubscribeItems.value.filter((item: Subscribe) => {
|
||||||
return (item.name.toLowerCase().includes(lowerWord) && (superUser || userName === item.username)) || false
|
return (item.name.toLowerCase().includes(lowerWord) && (superUser || userName === item.username)) || false
|
||||||
@@ -298,11 +340,20 @@ onMounted(() => {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
searchWordInput.value?.focus()
|
searchWordInput.value?.focus()
|
||||||
}, 500)
|
}, 500)
|
||||||
fetchInstalledPlugins()
|
// 根据权限加载不同的数据
|
||||||
fetchSubscribes()
|
if (hasManagePermission.value) {
|
||||||
|
fetchInstalledPlugins()
|
||||||
|
}
|
||||||
|
if (hasSubscribePermission.value) {
|
||||||
|
fetchSubscribes()
|
||||||
|
}
|
||||||
loadRecentSearches()
|
loadRecentSearches()
|
||||||
loadUserSitePreferences()
|
if (hasSearchPermission.value) {
|
||||||
if (superUser) queryAllSites()
|
loadUserSitePreferences()
|
||||||
|
if (hasManagePermission.value) {
|
||||||
|
queryAllSites()
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
@@ -433,7 +484,7 @@ onMounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
</VHover>
|
</VHover>
|
||||||
|
|
||||||
<VHover v-if="superUser">
|
<VHover v-if="hasManagePermission">
|
||||||
<template #default="hover">
|
<template #default="hover">
|
||||||
<VListItem
|
<VListItem
|
||||||
density="comfortable"
|
density="comfortable"
|
||||||
@@ -578,7 +629,7 @@ onMounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 将站点资源搜索移到最底部 -->
|
<!-- 将站点资源搜索移到最底部 -->
|
||||||
<template v-if="searchWord">
|
<template v-if="searchWord && hasSearchPermission">
|
||||||
<VDivider class="mx-4 mx-sm-6 my-2 search-divider" />
|
<VDivider class="mx-4 mx-sm-6 my-2 search-divider" />
|
||||||
<VListSubheader class="font-weight-medium text-uppercase py-2 px-4 px-sm-6">{{
|
<VListSubheader class="font-weight-medium text-uppercase py-2 px-4 px-sm-6">{{
|
||||||
t('dialog.searchBar.siteResources')
|
t('dialog.searchBar.siteResources')
|
||||||
@@ -611,7 +662,7 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="superUser"
|
v-if="hasManagePermission"
|
||||||
class="d-flex align-center flex-wrap site-chips-container mt-4 py-2 px-2 px-sm-3"
|
class="d-flex align-center flex-wrap site-chips-container mt-4 py-2 px-2 px-sm-3"
|
||||||
>
|
>
|
||||||
<div class="d-flex align-center flex-wrap flex-grow-1">
|
<div class="d-flex align-center flex-wrap flex-grow-1">
|
||||||
|
|||||||
@@ -3,28 +3,12 @@ import * as Mousetrap from 'mousetrap'
|
|||||||
import SearchBarDialog from '@/components/dialog/SearchBarDialog.vue'
|
import SearchBarDialog from '@/components/dialog/SearchBarDialog.vue'
|
||||||
import { useDisplay } from 'vuetify'
|
import { useDisplay } from 'vuetify'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useUserStore } from '@/stores'
|
|
||||||
import { hasPermission } from '@/utils/permission'
|
|
||||||
|
|
||||||
const display = useDisplay()
|
const display = useDisplay()
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
// 用户Store
|
|
||||||
const userStore = useUserStore()
|
|
||||||
|
|
||||||
const searchDialog = ref(false)
|
const searchDialog = ref(false)
|
||||||
|
|
||||||
// 检查是否有搜索权限
|
|
||||||
const hasSearchPermission = computed(() => {
|
|
||||||
return hasPermission(
|
|
||||||
{
|
|
||||||
is_superuser: userStore.superUser,
|
|
||||||
...userStore.permissions,
|
|
||||||
},
|
|
||||||
'search',
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
// 注册快捷键
|
// 注册快捷键
|
||||||
Mousetrap.bind(['command+k', 'ctrl+k'], openSearchDialog)
|
Mousetrap.bind(['command+k', 'ctrl+k'], openSearchDialog)
|
||||||
|
|
||||||
@@ -44,7 +28,7 @@ const metaKey = computed(() => (isMac() ? '⌘+K' : 'Ctrl+K'))
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- 👉 Search Icon -->
|
<!-- 👉 Search Icon -->
|
||||||
<div v-if="hasSearchPermission" class="d-flex align-center cursor-pointer ms-lg-n2" style="user-select: none">
|
<div class="d-flex align-center cursor-pointer ms-lg-n2" style="user-select: none">
|
||||||
<IconBtn @click="openSearchDialog">
|
<IconBtn @click="openSearchDialog">
|
||||||
<VIcon icon="ri-search-line" />
|
<VIcon icon="ri-search-line" />
|
||||||
</IconBtn>
|
</IconBtn>
|
||||||
@@ -54,7 +38,7 @@ const metaKey = computed(() => (isMac() ? '⌘+K' : 'Ctrl+K'))
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- 搜索弹窗 -->
|
<!-- 搜索弹窗 -->
|
||||||
<SearchBarDialog v-model="searchDialog" v-if="searchDialog && hasSearchPermission" @close="searchDialog = false" />
|
<SearchBarDialog v-model="searchDialog" v-if="searchDialog" @close="searchDialog = false" />
|
||||||
</template>
|
</template>
|
||||||
<style type="scss" scoped>
|
<style type="scss" scoped>
|
||||||
.meta-key {
|
.meta-key {
|
||||||
|
|||||||
@@ -1547,7 +1547,7 @@ export default {
|
|||||||
discovery: 'Discovery',
|
discovery: 'Discovery',
|
||||||
discoveryDesc: 'Access recommendation and exploration features',
|
discoveryDesc: 'Access recommendation and exploration features',
|
||||||
search: 'Search',
|
search: 'Search',
|
||||||
searchDesc: 'Use search functionality and view search results',
|
searchDesc: 'Search site resources and add downloads',
|
||||||
subscribe: 'Subscribe',
|
subscribe: 'Subscribe',
|
||||||
subscribeDesc: 'Manage movie and TV show subscriptions',
|
subscribeDesc: 'Manage movie and TV show subscriptions',
|
||||||
manage: 'Manage',
|
manage: 'Manage',
|
||||||
|
|||||||
@@ -1527,7 +1527,7 @@ export default {
|
|||||||
discovery: '发现',
|
discovery: '发现',
|
||||||
discoveryDesc: '访问推荐和探索功能',
|
discoveryDesc: '访问推荐和探索功能',
|
||||||
search: '搜索',
|
search: '搜索',
|
||||||
searchDesc: '使用搜索功能和查看搜索结果',
|
searchDesc: '搜索站点资源和添加下载',
|
||||||
subscribe: '订阅',
|
subscribe: '订阅',
|
||||||
subscribeDesc: '管理电影和电视剧订阅',
|
subscribeDesc: '管理电影和电视剧订阅',
|
||||||
manage: '管理',
|
manage: '管理',
|
||||||
|
|||||||
@@ -1529,7 +1529,7 @@ export default {
|
|||||||
discovery: '發現',
|
discovery: '發現',
|
||||||
discoveryDesc: '存取推薦和探索功能',
|
discoveryDesc: '存取推薦和探索功能',
|
||||||
search: '搜索',
|
search: '搜索',
|
||||||
searchDesc: '使用搜索功能和查看搜索結果',
|
searchDesc: '搜索站點資源和添加下載',
|
||||||
subscribe: '訂閱',
|
subscribe: '訂閱',
|
||||||
subscribeDesc: '管理電影和電視劇訂閱',
|
subscribeDesc: '管理電影和電視劇訂閱',
|
||||||
manage: '管理',
|
manage: '管理',
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ const { t } = useI18n()
|
|||||||
|
|
||||||
// 从 Store 中获取用户信息
|
// 从 Store 中获取用户信息
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const superUser = userStore.superUser
|
|
||||||
|
|
||||||
// 获取用户权限信息
|
// 获取用户权限信息
|
||||||
const userPermissions = computed(() => ({
|
const userPermissions = computed(() => ({
|
||||||
|
|||||||
Reference in New Issue
Block a user