mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-06-09 01:31:14 +08:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
356ffddb1c | ||
|
|
de69be7c4e | ||
|
|
e962f555ae | ||
|
|
1987246585 | ||
|
|
393264f66b | ||
|
|
9b50020b3b | ||
|
|
5e5545fe01 | ||
|
|
0e8da35b0a | ||
|
|
4d2cf73330 | ||
|
|
5df89f2ce4 | ||
|
|
045c0b4c0c | ||
|
|
8b4ffa0795 | ||
|
|
14359a37ae | ||
|
|
a8e4a1c2e0 | ||
|
|
9048d181af | ||
|
|
1cb02994bf | ||
|
|
6fad85e957 | ||
|
|
db9b2ee6b3 |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "moviepilot",
|
"name": "moviepilot",
|
||||||
"version": "1.9.8",
|
"version": "1.9.11",
|
||||||
"private": true,
|
"private": true,
|
||||||
"bin": "dist/service.js",
|
"bin": "dist/service.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ api.interceptors.response.use(
|
|||||||
router.push('/login')
|
router.push('/login')
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject(new Error(error))
|
return Promise.reject(error)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ watch(
|
|||||||
'outline-dashed outline-1': props.media?.best_version && imageLoaded,
|
'outline-dashed outline-1': props.media?.best_version && imageLoaded,
|
||||||
'transition transform-cpu duration-300 scale-105 shadow-lg': hover.isHovering,
|
'transition transform-cpu duration-300 scale-105 shadow-lg': hover.isHovering,
|
||||||
}"
|
}"
|
||||||
|
min-height="170"
|
||||||
@click="editSubscribeDialog"
|
@click="editSubscribeDialog"
|
||||||
>
|
>
|
||||||
<div class="me-n3 absolute top-1 right-2">
|
<div class="me-n3 absolute top-1 right-2">
|
||||||
|
|||||||
@@ -350,7 +350,7 @@ onMounted(() => {
|
|||||||
</VCol>
|
</VCol>
|
||||||
</VRow>
|
</VRow>
|
||||||
<VRow>
|
<VRow>
|
||||||
<VCol cols="12" md="6" v-if="props.storage == 'local'">
|
<VCol cols="12" md="6">
|
||||||
<VSwitch
|
<VSwitch
|
||||||
v-model="transferForm.scrape"
|
v-model="transferForm.scrape"
|
||||||
label="刮削元数据"
|
label="刮削元数据"
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ const transferItems = ref<FileItem[]>([])
|
|||||||
|
|
||||||
// 大小控制
|
// 大小控制
|
||||||
const scrollStyle = computed(() => {
|
const scrollStyle = computed(() => {
|
||||||
return appMode
|
return appMode.value
|
||||||
? 'height: calc(100vh - 15.5rem - env(safe-area-inset-bottom) - 3.5rem)'
|
? 'height: calc(100vh - 15.5rem - env(safe-area-inset-bottom) - 3.5rem)'
|
||||||
: 'height: calc(100vh - 14.5rem - env(safe-area-inset-bottom)'
|
: 'height: calc(100vh - 14.5rem - env(safe-area-inset-bottom)'
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -12,12 +12,18 @@ import MediaServerLibrary from '@/views/dashboard/MediaServerLibrary.vue'
|
|||||||
import MediaServerPlaying from '@/views/dashboard/MediaServerPlaying.vue'
|
import MediaServerPlaying from '@/views/dashboard/MediaServerPlaying.vue'
|
||||||
import DashboardRender from '@/components/render/DashboardRender.vue'
|
import DashboardRender from '@/components/render/DashboardRender.vue'
|
||||||
import { isNullOrEmptyObject } from '@/@core/utils'
|
import { isNullOrEmptyObject } from '@/@core/utils'
|
||||||
|
|
||||||
// 输入参数
|
// 输入参数
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
// 仪表板配置
|
// 仪表板配置
|
||||||
config: Object as PropType<DashboardItem>,
|
config: Object as PropType<DashboardItem>,
|
||||||
// 刷新状态
|
// 刷新状态
|
||||||
refreshStatus: Boolean,
|
refreshStatus: Boolean,
|
||||||
|
// 是否允许刷新数据
|
||||||
|
allowRefresh: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['update:refreshStatus'])
|
const emit = defineEmits(['update:refreshStatus'])
|
||||||
@@ -32,10 +38,10 @@ onUnmounted(() => {
|
|||||||
<AnalyticsStorage v-if="config?.id === 'storage'" />
|
<AnalyticsStorage v-if="config?.id === 'storage'" />
|
||||||
<AnalyticsMediaStatistic v-else-if="config?.id === 'mediaStatistic'" />
|
<AnalyticsMediaStatistic v-else-if="config?.id === 'mediaStatistic'" />
|
||||||
<AnalyticsWeeklyOverview v-else-if="config?.id === 'weeklyOverview'" />
|
<AnalyticsWeeklyOverview v-else-if="config?.id === 'weeklyOverview'" />
|
||||||
<AnalyticsSpeed v-else-if="config?.id === 'speed'" />
|
<AnalyticsSpeed v-else-if="config?.id === 'speed'" :allowRefresh="props.allowRefresh" />
|
||||||
<AnalyticsScheduler v-else-if="config?.id === 'scheduler'" />
|
<AnalyticsScheduler v-else-if="config?.id === 'scheduler'" :allowRefresh="props.allowRefresh" />
|
||||||
<AnalyticsCpu v-else-if="config?.id === 'cpu'" />
|
<AnalyticsCpu v-else-if="config?.id === 'cpu'" :allowRefresh="props.allowRefresh" />
|
||||||
<AnalyticsMemory v-else-if="config?.id === 'memory'" />
|
<AnalyticsMemory v-else-if="config?.id === 'memory'" :allowRefresh="props.allowRefresh" />
|
||||||
<MediaServerLibrary v-else-if="config?.id === 'library'" />
|
<MediaServerLibrary v-else-if="config?.id === 'library'" />
|
||||||
<MediaServerPlaying v-else-if="config?.id === 'playing'" />
|
<MediaServerPlaying v-else-if="config?.id === 'playing'" />
|
||||||
<MediaServerLatest v-else-if="config?.id === 'latest'" />
|
<MediaServerLatest v-else-if="config?.id === 'latest'" />
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import * as Mousetrap from 'mousetrap'
|
import * as Mousetrap from 'mousetrap'
|
||||||
import SearchBarView from '@/views/system/SearchBarView.vue'
|
import SearchBarView from '@/views/system/SearchBarView.vue'
|
||||||
import { useDisplay } from 'vuetify'
|
import { useDisplay } from 'vuetify'
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
|
||||||
const display = useDisplay()
|
const display = useDisplay()
|
||||||
|
|
||||||
@@ -15,6 +16,14 @@ function openSearchDialog() {
|
|||||||
searchDialog.value = true
|
searchDialog.value = true
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检测操作系统是否是Mac
|
||||||
|
function isMac() {
|
||||||
|
return navigator.platform.toUpperCase().indexOf('MAC') >= 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算属性:根据操作系统显示不同的按键提示
|
||||||
|
const metaKey = computed(() => (isMac() ? '⌘+K' : 'Ctrl+K'))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -25,12 +34,13 @@ function openSearchDialog() {
|
|||||||
</IconBtn>
|
</IconBtn>
|
||||||
<span v-if="display.lgAndUp.value" class="flex align-center text-disabled ms-2" @click="openSearchDialog">
|
<span v-if="display.lgAndUp.value" class="flex align-center text-disabled ms-2" @click="openSearchDialog">
|
||||||
<span class="me-3">搜索</span>
|
<span class="me-3">搜索</span>
|
||||||
<span class="meta-key">⌘K</span>
|
<span class="meta-key">{{ metaKey }}</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- 搜索弹窗 -->
|
<!-- 搜索弹窗 -->
|
||||||
<SearchBarView v-model="searchDialog" v-if="searchDialog" @close="searchDialog = false" />
|
<SearchBarView v-model="searchDialog" v-if="searchDialog" @close="searchDialog = false" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style type="scss" scoped>
|
<style type="scss" scoped>
|
||||||
.meta-key {
|
.meta-key {
|
||||||
border: thin solid rgba(var(--v-border-color), var(--v-border-opacity));
|
border: thin solid rgba(var(--v-border-color), var(--v-border-opacity));
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ const superUser = store.state.auth.superUser
|
|||||||
// 是否拉升高度
|
// 是否拉升高度
|
||||||
const isElevated = ref(true)
|
const isElevated = ref(true)
|
||||||
|
|
||||||
|
// 是否发送请求的总开关
|
||||||
|
const isRequest = ref(true)
|
||||||
|
|
||||||
// 计算属性,控制是否拉升高度
|
// 计算属性,控制是否拉升高度
|
||||||
const elevatedConf = controlledComputed(
|
const elevatedConf = controlledComputed(
|
||||||
() => isElevated.value,
|
() => isElevated.value,
|
||||||
@@ -269,7 +272,8 @@ async function getPluginDashboard(id: string, key: string) {
|
|||||||
if (
|
if (
|
||||||
res.attrs?.refresh &&
|
res.attrs?.refresh &&
|
||||||
pluginDashboardRefreshStatus.value[pluginDashboardId] &&
|
pluginDashboardRefreshStatus.value[pluginDashboardId] &&
|
||||||
enableConfig.value[pluginDashboardId]
|
enableConfig.value[pluginDashboardId] &&
|
||||||
|
isRequest.value
|
||||||
) {
|
) {
|
||||||
// 清除之前的定时器
|
// 清除之前的定时器
|
||||||
if (refreshTimers.value[pluginDashboardId]) {
|
if (refreshTimers.value[pluginDashboardId]) {
|
||||||
@@ -298,6 +302,14 @@ onBeforeMount(async () => {
|
|||||||
await loadDashboardConfig()
|
await loadDashboardConfig()
|
||||||
getPluginDashboardMeta()
|
getPluginDashboardMeta()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onActivated(async () => {
|
||||||
|
isRequest.value = true
|
||||||
|
})
|
||||||
|
|
||||||
|
onDeactivated(() => {
|
||||||
|
isRequest.value = false
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -314,6 +326,7 @@ onBeforeMount(async () => {
|
|||||||
<VCol v-if="enableConfig[buildPluginDashboardId(element.id, element.key)] && element.cols" v-bind:="element.cols">
|
<VCol v-if="enableConfig[buildPluginDashboardId(element.id, element.key)] && element.cols" v-bind:="element.cols">
|
||||||
<DashboardElement
|
<DashboardElement
|
||||||
:config="element"
|
:config="element"
|
||||||
|
:allow-refresh="isRequest"
|
||||||
v-model:refreshStatus="pluginDashboardRefreshStatus[buildPluginDashboardId(element.id, element.key)]"
|
v-model:refreshStatus="pluginDashboardRefreshStatus[buildPluginDashboardId(element.id, element.key)]"
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
|
|||||||
@@ -4,6 +4,15 @@ import { useTheme } from 'vuetify'
|
|||||||
import { hexToRgb } from '@layouts/utils'
|
import { hexToRgb } from '@layouts/utils'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
|
|
||||||
|
// 输入参数
|
||||||
|
const props = defineProps({
|
||||||
|
// 是否允许刷新数据
|
||||||
|
allowRefresh: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
const vuetifyTheme = useTheme()
|
const vuetifyTheme = useTheme()
|
||||||
|
|
||||||
const currentTheme = controlledComputed(
|
const currentTheme = controlledComputed(
|
||||||
@@ -94,6 +103,7 @@ const chartOptions = controlledComputed(
|
|||||||
|
|
||||||
// 调用API接口获取最新CPU使用率
|
// 调用API接口获取最新CPU使用率
|
||||||
async function getCpuUsage() {
|
async function getCpuUsage() {
|
||||||
|
if (!props.allowRefresh) return
|
||||||
try {
|
try {
|
||||||
// 请求数据
|
// 请求数据
|
||||||
current.value = (await api.get('dashboard/cpu')) ?? 0
|
current.value = (await api.get('dashboard/cpu')) ?? 0
|
||||||
|
|||||||
@@ -5,6 +5,15 @@ import { hexToRgb } from '@layouts/utils'
|
|||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import { formatBytes } from '@/@core/utils/formatters'
|
import { formatBytes } from '@/@core/utils/formatters'
|
||||||
|
|
||||||
|
// 输入参数
|
||||||
|
const props = defineProps({
|
||||||
|
// 是否允许刷新数据
|
||||||
|
allowRefresh: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
const vuetifyTheme = useTheme()
|
const vuetifyTheme = useTheme()
|
||||||
|
|
||||||
const currentTheme = controlledComputed(
|
const currentTheme = controlledComputed(
|
||||||
@@ -100,6 +109,7 @@ const chartOptions = controlledComputed(
|
|||||||
|
|
||||||
// 调用API接口获取最新内存使用量
|
// 调用API接口获取最新内存使用量
|
||||||
async function getMemorgUsage() {
|
async function getMemorgUsage() {
|
||||||
|
if (!props.allowRefresh) return
|
||||||
try {
|
try {
|
||||||
// 请求数据
|
// 请求数据
|
||||||
;[usedMemory.value, memoryUsage.value] = await api.get('dashboard/memory')
|
;[usedMemory.value, memoryUsage.value] = await api.get('dashboard/memory')
|
||||||
|
|||||||
@@ -2,6 +2,15 @@
|
|||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import type { ScheduleInfo } from '@/api/types'
|
import type { ScheduleInfo } from '@/api/types'
|
||||||
|
|
||||||
|
// 输入参数
|
||||||
|
const props = defineProps({
|
||||||
|
// 是否允许刷新数据
|
||||||
|
allowRefresh: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
// 定时服务列表
|
// 定时服务列表
|
||||||
const schedulerList = ref<ScheduleInfo[]>([])
|
const schedulerList = ref<ScheduleInfo[]>([])
|
||||||
|
|
||||||
@@ -10,6 +19,9 @@ let refreshTimer: NodeJS.Timeout | null = null
|
|||||||
|
|
||||||
// 调用API加载定时服务列表
|
// 调用API加载定时服务列表
|
||||||
async function loadSchedulerList() {
|
async function loadSchedulerList() {
|
||||||
|
if (!props.allowRefresh) {
|
||||||
|
return
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const res: ScheduleInfo[] = await api.get('dashboard/schedule')
|
const res: ScheduleInfo[] = await api.get('dashboard/schedule')
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,15 @@ import { formatFileSize } from '@/@core/utils/formatters'
|
|||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import type { DownloaderInfo } from '@/api/types'
|
import type { DownloaderInfo } from '@/api/types'
|
||||||
|
|
||||||
|
// 输入参数
|
||||||
|
const props = defineProps({
|
||||||
|
// 是否允许刷新数据
|
||||||
|
allowRefresh: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
// 定时器
|
// 定时器
|
||||||
let refreshTimer: NodeJS.Timeout | null = null
|
let refreshTimer: NodeJS.Timeout | null = null
|
||||||
|
|
||||||
@@ -35,6 +44,10 @@ const infoItems = ref([
|
|||||||
|
|
||||||
// 调用API查询下载器数据
|
// 调用API查询下载器数据
|
||||||
async function loadDownloaderInfo() {
|
async function loadDownloaderInfo() {
|
||||||
|
if (!props.allowRefresh) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res: DownloaderInfo = await api.get('dashboard/downloader')
|
const res: DownloaderInfo = await api.get('dashboard/downloader')
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,13 @@ const options = controlledComputed(
|
|||||||
fontSize: '12px',
|
fontSize: '12px',
|
||||||
},
|
},
|
||||||
|
|
||||||
formatter: (value: number) => (value > 999 ? (value / 1000).toFixed(0) : value),
|
formatter: (value: number) => {
|
||||||
|
if (value > 999) {
|
||||||
|
return (value / 1000).toFixed(1) + 'k'
|
||||||
|
} else {
|
||||||
|
return value.toString()
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { Context } from '@/api/types'
|
import type { Context } from '@/api/types'
|
||||||
import TorrentItem from '@/components/cards/TorrentItem.vue'
|
import TorrentItem from '@/components/cards/TorrentItem.vue'
|
||||||
|
import { list } from 'postcss'
|
||||||
import { useDisplay } from 'vuetify'
|
import { useDisplay } from 'vuetify'
|
||||||
|
|
||||||
// 显示器宽度
|
// 显示器宽度
|
||||||
@@ -35,6 +36,13 @@ const filterForm = reactive({
|
|||||||
resolution: [] as string[],
|
resolution: [] as string[],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 列表样式
|
||||||
|
const listStyle = computed(() => {
|
||||||
|
return appMode.value
|
||||||
|
? 'height: calc(100vh - 7.5rem - env(safe-area-inset-bottom) - 3.5rem)'
|
||||||
|
: 'height: calc(100vh - 6.5rem - env(safe-area-inset-bottom)'
|
||||||
|
})
|
||||||
|
|
||||||
// 排序字段
|
// 排序字段
|
||||||
const sortField = ref('default')
|
const sortField = ref('default')
|
||||||
|
|
||||||
@@ -167,14 +175,7 @@ onMounted(() => {
|
|||||||
</VListItem>
|
</VListItem>
|
||||||
</VList>
|
</VList>
|
||||||
<VList v-if="dataList.length !== 0" lines="three" class="rounded p-0 torrent-list-vscroll shadow-lg">
|
<VList v-if="dataList.length !== 0" lines="three" class="rounded p-0 torrent-list-vscroll shadow-lg">
|
||||||
<VVirtualScroll
|
<VVirtualScroll :items="dataList" :style="listStyle">
|
||||||
:items="dataList"
|
|
||||||
:style="
|
|
||||||
appMode
|
|
||||||
? 'height: calc(100vh - 7.5rem - env(safe-area-inset-bottom) - 3.5rem)'
|
|
||||||
: 'height: calc(100vh - 6.5rem - env(safe-area-inset-bottom)'
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<template #default="{ item }">
|
<template #default="{ item }">
|
||||||
<TorrentItem :torrent="item" :key="`${item.torrent_info.page_url}`" />
|
<TorrentItem :torrent="item" :key="`${item.torrent_info.page_url}`" />
|
||||||
</template>
|
</template>
|
||||||
@@ -182,11 +183,7 @@ onMounted(() => {
|
|||||||
</VList>
|
</VList>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol xl="2" md="3" v-if="display.mdAndUp.value">
|
<VCol xl="2" md="3" v-if="display.mdAndUp.value">
|
||||||
<VList
|
<VList lines="one" class="rounded shadow-lg" :style="listStyle">
|
||||||
lines="one"
|
|
||||||
class="rounded shadow-lg"
|
|
||||||
style="block-size: calc(100vh - 6.5rem - env(safe-area-inset-bottom))"
|
|
||||||
>
|
|
||||||
<VListSubheader> 排序 </VListSubheader>
|
<VListSubheader> 排序 </VListSubheader>
|
||||||
<VListItem>
|
<VListItem>
|
||||||
<VChipGroup column v-model="sortField">
|
<VChipGroup column v-model="sortField">
|
||||||
|
|||||||
@@ -124,6 +124,12 @@ const TransferDict: { [key: string]: string } = {
|
|||||||
rclone_move: 'Rclone移动',
|
rclone_move: 'Rclone移动',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tableStyle = computed(() => {
|
||||||
|
return appMode.value
|
||||||
|
? 'height: calc(100vh - 15.5rem - env(safe-area-inset-bottom) - 3.5rem)'
|
||||||
|
: 'height: calc(100vh - 14.5rem - env(safe-area-inset-bottom)'
|
||||||
|
})
|
||||||
|
|
||||||
// 分页提示
|
// 分页提示
|
||||||
const pageTip = computed(() => {
|
const pageTip = computed(() => {
|
||||||
const begin = itemsPerPage.value * (currentPage.value - 1) + 1
|
const begin = itemsPerPage.value * (currentPage.value - 1) + 1
|
||||||
@@ -142,12 +148,19 @@ const totalPage = computed(() => {
|
|||||||
|
|
||||||
// 切换页签和搜索词
|
// 切换页签和搜索词
|
||||||
watch(
|
watch(
|
||||||
[() => currentPage.value, () => itemsPerPage.value, () => search.value],
|
[() => currentPage.value, () => itemsPerPage.value],
|
||||||
debounce(async () => {
|
debounce(async () => {
|
||||||
reloadPage()
|
reloadPage()
|
||||||
}, 1000),
|
}, 1000),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
[() => search.value],
|
||||||
|
debounce(async () => {
|
||||||
|
reloadPage(true)
|
||||||
|
}, 1000),
|
||||||
|
)
|
||||||
|
|
||||||
// 获取订阅列表数据
|
// 获取订阅列表数据
|
||||||
async function fetchData(page = currentPage.value, count = itemsPerPage.value) {
|
async function fetchData(page = currentPage.value, count = itemsPerPage.value) {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@@ -329,7 +342,7 @@ function addUrlQuery(url: string, name: string, value: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 重载页面
|
// 重载页面
|
||||||
function reloadPage() {
|
function reloadPage(resetPage = false) {
|
||||||
let url = '/history'
|
let url = '/history'
|
||||||
if (search.value) {
|
if (search.value) {
|
||||||
url = addUrlQuery(url, 'search', search.value)
|
url = addUrlQuery(url, 'search', search.value)
|
||||||
@@ -338,7 +351,7 @@ function reloadPage() {
|
|||||||
url = addUrlQuery(url, 'itemsPerPage', itemsPerPage.value)
|
url = addUrlQuery(url, 'itemsPerPage', itemsPerPage.value)
|
||||||
}
|
}
|
||||||
if (currentPage.value) {
|
if (currentPage.value) {
|
||||||
url = addUrlQuery(url, 'currentPage', currentPage.value)
|
url = addUrlQuery(url, 'currentPage', resetPage ? 1 : currentPage.value)
|
||||||
}
|
}
|
||||||
router.push(url)
|
router.push(url)
|
||||||
}
|
}
|
||||||
@@ -394,11 +407,7 @@ onMounted(fetchData)
|
|||||||
show-select
|
show-select
|
||||||
loading-text="加载中..."
|
loading-text="加载中..."
|
||||||
hover
|
hover
|
||||||
:style="
|
:style="tableStyle"
|
||||||
appMode
|
|
||||||
? 'height: calc(100vh - 15.5rem - env(safe-area-inset-bottom) - 3.5rem)'
|
|
||||||
: 'height: calc(100vh - 14.5rem - env(safe-area-inset-bottom)'
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<template #item.title="{ item }">
|
<template #item.title="{ item }">
|
||||||
<div class="d-flex align-center">
|
<div class="d-flex align-center">
|
||||||
|
|||||||
@@ -1,12 +1,19 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import type { Plugin, Subscribe } from '@/api/types'
|
import type { Plugin, Subscribe } from '@/api/types'
|
||||||
import { SystemNavMenus, UserfulMenus, PluginTabs, SettingTabs } from '@/router/menu'
|
import { SystemNavMenus, UserfulMenus, SettingTabs } from '@/router/menu'
|
||||||
import { NavMenu } from '@/@layouts/types'
|
import { NavMenu } from '@/@layouts/types'
|
||||||
|
import store from '@/store'
|
||||||
|
|
||||||
// 路由
|
// 路由
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
|
// 超级用户
|
||||||
|
const superUser = store.state.auth.superUser
|
||||||
|
|
||||||
|
// 当前用户名
|
||||||
|
const userName = store.state.auth.userName
|
||||||
|
|
||||||
// 定义事件
|
// 定义事件
|
||||||
const emit = defineEmits(['close'])
|
const emit = defineEmits(['close'])
|
||||||
|
|
||||||
@@ -74,6 +81,7 @@ function getMenus(): NavMenu[] {
|
|||||||
// 匹配的菜单列表
|
// 匹配的菜单列表
|
||||||
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)
|
||||||
@@ -104,6 +112,7 @@ async function fetchInstalledPlugins() {
|
|||||||
// 区配的插件列表
|
// 区配的插件列表
|
||||||
const matchedPluginItems = computed(() => {
|
const matchedPluginItems = 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()
|
||||||
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
|
||||||
@@ -114,7 +123,7 @@ const matchedPluginItems = computed(() => {
|
|||||||
// 所有订阅数据
|
// 所有订阅数据
|
||||||
const SubscribeItems = ref<Subscribe[]>([])
|
const SubscribeItems = ref<Subscribe[]>([])
|
||||||
|
|
||||||
// 获取电影订阅列表数据
|
// 获取订阅列表数据
|
||||||
async function fetchSubscribes() {
|
async function fetchSubscribes() {
|
||||||
try {
|
try {
|
||||||
SubscribeItems.value = await api.get('subscribe/')
|
SubscribeItems.value = await api.get('subscribe/')
|
||||||
@@ -128,7 +137,7 @@ const matchedSubscribeItems = computed(() => {
|
|||||||
if (!searchWord.value) return []
|
if (!searchWord.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)
|
return (item.name.toLowerCase().includes(lowerWord) && (superUser || userName === item.username)) || false
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -287,7 +296,7 @@ onMounted(() => {
|
|||||||
</VListItem>
|
</VListItem>
|
||||||
</template>
|
</template>
|
||||||
</VHover>
|
</VHover>
|
||||||
<VHover>
|
<VHover v-if="superUser">
|
||||||
<template #default="hover">
|
<template #default="hover">
|
||||||
<VListItem prepend-icon="mdi-history" link v-bind="hover.props" @click="searchHistory">
|
<VListItem prepend-icon="mdi-history" link v-bind="hover.props" @click="searchHistory">
|
||||||
<VListItemTitle class="break-words whitespace-break-spaces">
|
<VListItemTitle class="break-words whitespace-break-spaces">
|
||||||
@@ -382,7 +391,7 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</VCol>
|
</VCol>
|
||||||
</VRow>
|
</VRow>
|
||||||
<VRow>
|
<VRow v-if="superUser">
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<p class="custom-letter-spacing text-sm text-disabled text-uppercase py-2 px-4 mb-0">常用功能</p>
|
<p class="custom-letter-spacing text-sm text-disabled text-uppercase py-2 px-4 mb-0">常用功能</p>
|
||||||
<VList lines="one">
|
<VList lines="one">
|
||||||
|
|||||||
Reference in New Issue
Block a user