mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-08 01:06:41 +08:00
fix keepalive
This commit is contained in:
@@ -13,8 +13,8 @@ const activeState = computed(() => {
|
|||||||
return {
|
return {
|
||||||
home: route.path === '/dashboard',
|
home: route.path === '/dashboard',
|
||||||
ranking: route.path === '/ranking',
|
ranking: route.path === '/ranking',
|
||||||
movie: route.path === '/subscribe-movie',
|
movie: route.path === '/subscribe/movie',
|
||||||
tv: route.path === '/subscribe-tv',
|
tv: route.path === '/subscribe/tv',
|
||||||
apps: route.path === '/apps',
|
apps: route.path === '/apps',
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -30,24 +30,24 @@ const activeState = computed(() => {
|
|||||||
style="block-size: calc(3.5rem + env(safe-area-inset-bottom))"
|
style="block-size: calc(3.5rem + env(safe-area-inset-bottom))"
|
||||||
>
|
>
|
||||||
<VBtn to="/dashboard" :ripple="false">
|
<VBtn to="/dashboard" :ripple="false">
|
||||||
<VIcon v-if="activeState.home" size="32">mdi-home</VIcon>
|
<VIcon v-if="activeState.home" size="28">mdi-home</VIcon>
|
||||||
<VIcon v-else size="32">mdi-home-outline</VIcon>
|
<VIcon v-else size="28">mdi-home-outline</VIcon>
|
||||||
</VBtn>
|
</VBtn>
|
||||||
<VBtn to="/ranking" :ripple="false">
|
<VBtn to="/ranking" :ripple="false">
|
||||||
<VIcon v-if="activeState.ranking" size="32">mdi-star</VIcon>
|
<VIcon v-if="activeState.ranking" size="28">mdi-star</VIcon>
|
||||||
<VIcon v-else size="32">mdi-star-outline</VIcon>
|
<VIcon v-else size="28">mdi-star-outline</VIcon>
|
||||||
</VBtn>
|
</VBtn>
|
||||||
<VBtn to="/subscribe-movie?tab=mysub" :ripple="false">
|
<VBtn to="/subscribe/movie" :ripple="false">
|
||||||
<VIcon v-if="activeState.movie" size="32">mdi-movie-open</VIcon>
|
<VIcon v-if="activeState.movie" size="28">mdi-movie-open</VIcon>
|
||||||
<VIcon v-else size="32">mdi-movie-open-outline</VIcon>
|
<VIcon v-else size="28">mdi-movie-open-outline</VIcon>
|
||||||
</VBtn>
|
</VBtn>
|
||||||
<VBtn to="/subscribe-tv?tab=mysub" :ripple="false">
|
<VBtn to="/subscribe/tv" :ripple="false">
|
||||||
<VIcon v-if="activeState.tv" size="32">mdi-television-play</VIcon>
|
<VIcon v-if="activeState.tv" size="28">mdi-television-play</VIcon>
|
||||||
<VIcon v-else size="32">mdi-television</VIcon>
|
<VIcon v-else size="28">mdi-television</VIcon>
|
||||||
</VBtn>
|
</VBtn>
|
||||||
<VBtn to="/apps" :ripple="false">
|
<VBtn to="/apps" :ripple="false">
|
||||||
<VIcon v-if="activeState.apps" size="32">mdi-dots-horizontal-circle</VIcon>
|
<VIcon v-if="activeState.apps" size="28">mdi-dots-horizontal-circle</VIcon>
|
||||||
<VIcon v-else size="32">mdi-dots-horizontal</VIcon>
|
<VIcon v-else size="28">mdi-dots-horizontal</VIcon>
|
||||||
</VBtn>
|
</VBtn>
|
||||||
</VBottomNavigation>
|
</VBottomNavigation>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import SubscribeListView from '@/views/subscribe/SubscribeListView.vue'
|
|
||||||
import SubscribePopularView from '@/views/subscribe/SubscribePopularView.vue'
|
|
||||||
import router from '@/router'
|
|
||||||
import { SubscribeTvTabs } from '@/router/menu'
|
|
||||||
|
|
||||||
const route = useRoute()
|
|
||||||
|
|
||||||
const activeTab = ref(route.query.tab)
|
|
||||||
|
|
||||||
// 订阅ID参数
|
|
||||||
const subId = ref(route.query.id as string)
|
|
||||||
|
|
||||||
// 跳转tab
|
|
||||||
function jumpTab(tab: string) {
|
|
||||||
router.push('/subscribe-tv?tab=' + tab)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<VTabs v-model="activeTab">
|
|
||||||
<VTab v-for="item in SubscribeTvTabs" :value="item.tab" @click="jumpTab(item.tab)">
|
|
||||||
<span class="mx-5">{{ item.title }}</span>
|
|
||||||
</VTab>
|
|
||||||
</VTabs>
|
|
||||||
|
|
||||||
<VWindow v-model="activeTab" class="mt-5 disable-tab-transition" :touch="false">
|
|
||||||
<VWindowItem value="mysub">
|
|
||||||
<transition name="fade-slide" appear>
|
|
||||||
<SubscribeListView type="电视剧" :subid="subId" />
|
|
||||||
</transition>
|
|
||||||
</VWindowItem>
|
|
||||||
<VWindowItem value="popular">
|
|
||||||
<transition name="fade-slide" appear>
|
|
||||||
<SubscribePopularView type="电视剧" :subid="subId" />
|
|
||||||
</transition>
|
|
||||||
</VWindowItem>
|
|
||||||
</VWindow>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@@ -1,27 +1,24 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import SubscribeListView from '@/views/subscribe/SubscribeListView.vue'
|
import SubscribeListView from '@/views/subscribe/SubscribeListView.vue'
|
||||||
import SubscribePopularView from '@/views/subscribe/SubscribePopularView.vue'
|
import SubscribePopularView from '@/views/subscribe/SubscribePopularView.vue'
|
||||||
import router from '@/router'
|
|
||||||
import { SubscribeMovieTabs } from '@/router/menu'
|
import { SubscribeMovieTabs } from '@/router/menu'
|
||||||
|
import router from '@/router'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
// 订阅ID参数
|
const subType = route.meta.subType?.toString()
|
||||||
const subId = ref(route.query.id as string)
|
const subId = ref(route.query.id as string)
|
||||||
|
|
||||||
// 当前标签
|
|
||||||
const activeTab = ref(route.query.tab)
|
const activeTab = ref(route.query.tab)
|
||||||
|
|
||||||
// 跳转tab
|
|
||||||
function jumpTab(tab: string) {
|
function jumpTab(tab: string) {
|
||||||
router.push('/subscribe-movie?tab=' + tab)
|
router.push('/subscribe/movie?tab=' + tab)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<VTabs v-model="activeTab">
|
<VTabs v-model="activeTab">
|
||||||
<VTab v-for="item in SubscribeMovieTabs" :value="item.tab" @click="jumpTab(item.tab)">
|
<VTab v-for="item in SubscribeMovieTabs" :value="item.tab" @to="jumpTab(item.tab)">
|
||||||
<span class="mx-5">{{ item.title }}</span>
|
<span class="mx-5">{{ item.title }}</span>
|
||||||
</VTab>
|
</VTab>
|
||||||
</VTabs>
|
</VTabs>
|
||||||
@@ -29,12 +26,12 @@ function jumpTab(tab: string) {
|
|||||||
<VWindow v-model="activeTab" class="mt-5 disable-tab-transition" :touch="false">
|
<VWindow v-model="activeTab" class="mt-5 disable-tab-transition" :touch="false">
|
||||||
<VWindowItem value="mysub">
|
<VWindowItem value="mysub">
|
||||||
<transition name="fade-slide" appear>
|
<transition name="fade-slide" appear>
|
||||||
<SubscribeListView type="电影" :subid="subId" />
|
<SubscribeListView :type="subType" :subid="subId" />
|
||||||
</transition>
|
</transition>
|
||||||
</VWindowItem>
|
</VWindowItem>
|
||||||
<VWindowItem value="popular">
|
<VWindowItem value="popular">
|
||||||
<transition name="fade-slide" appear>
|
<transition name="fade-slide" appear>
|
||||||
<SubscribePopularView type="电影" :subid="subId" />
|
<SubscribePopularView :type="subType" />
|
||||||
</transition>
|
</transition>
|
||||||
</VWindowItem>
|
</VWindowItem>
|
||||||
</VWindow>
|
</VWindow>
|
||||||
+14
-4
@@ -23,6 +23,7 @@ const router = createRouter({
|
|||||||
path: '/dashboard',
|
path: '/dashboard',
|
||||||
component: () => import('../pages/dashboard.vue'),
|
component: () => import('../pages/dashboard.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
|
keepAlive: true,
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -42,23 +43,28 @@ const router = createRouter({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/subscribe-movie',
|
path: '/subscribe/movie',
|
||||||
component: () => import('../pages/subscribe-movie.vue'),
|
component: () => import('../pages/subscribe.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
|
keepAlive: true,
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
|
subType: '电影',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/subscribe-tv',
|
path: '/subscribe/tv',
|
||||||
component: () => import('../pages/subscribe-tv.vue'),
|
component: () => import('../pages/subscribe.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
|
keepAlive: true,
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
|
subType: '电视剧',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/calendar',
|
path: '/calendar',
|
||||||
component: () => import('../pages/calendar.vue'),
|
component: () => import('../pages/calendar.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
|
keepAlive: true,
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -80,6 +86,7 @@ const router = createRouter({
|
|||||||
path: '/site',
|
path: '/site',
|
||||||
component: () => import('../pages/site.vue'),
|
component: () => import('../pages/site.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
|
keepAlive: true,
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -87,6 +94,7 @@ const router = createRouter({
|
|||||||
path: '/plugins',
|
path: '/plugins',
|
||||||
component: () => import('../pages/plugin.vue'),
|
component: () => import('../pages/plugin.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
|
keepAlive: true,
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -120,6 +128,7 @@ const router = createRouter({
|
|||||||
component: () => import('../pages/person.vue'),
|
component: () => import('../pages/person.vue'),
|
||||||
props: true,
|
props: true,
|
||||||
meta: {
|
meta: {
|
||||||
|
keepAlive: true,
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -127,6 +136,7 @@ const router = createRouter({
|
|||||||
path: '/media',
|
path: '/media',
|
||||||
component: () => import('../pages/media.vue'),
|
component: () => import('../pages/media.vue'),
|
||||||
meta: {
|
meta: {
|
||||||
|
keepAlive: true,
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
+7
-7
@@ -25,7 +25,7 @@ export const SystemNavMenus = [
|
|||||||
title: '电影',
|
title: '电影',
|
||||||
full_title: '电影订阅',
|
full_title: '电影订阅',
|
||||||
icon: 'mdi-movie-open-outline',
|
icon: 'mdi-movie-open-outline',
|
||||||
to: '/subscribe-movie?tab=mysub',
|
to: '/subscribe/movie',
|
||||||
header: '订阅',
|
header: '订阅',
|
||||||
admin: false,
|
admin: false,
|
||||||
},
|
},
|
||||||
@@ -33,7 +33,7 @@ export const SystemNavMenus = [
|
|||||||
title: '电视剧',
|
title: '电视剧',
|
||||||
full_title: '电视剧订阅',
|
full_title: '电视剧订阅',
|
||||||
icon: 'mdi-television',
|
icon: 'mdi-television',
|
||||||
to: '/subscribe-tv?tab=mysub',
|
to: '/subscribe/tv',
|
||||||
header: '订阅',
|
header: '订阅',
|
||||||
admin: false,
|
admin: false,
|
||||||
},
|
},
|
||||||
@@ -69,7 +69,7 @@ export const SystemNavMenus = [
|
|||||||
{
|
{
|
||||||
title: '插件',
|
title: '插件',
|
||||||
icon: 'mdi-apps',
|
icon: 'mdi-apps',
|
||||||
to: '/plugins?tab=installed',
|
to: '/plugins',
|
||||||
header: '系统',
|
header: '系统',
|
||||||
admin: true,
|
admin: true,
|
||||||
},
|
},
|
||||||
@@ -186,12 +186,12 @@ export const SubscribeMovieTabs = [
|
|||||||
{
|
{
|
||||||
title: '我的订阅',
|
title: '我的订阅',
|
||||||
tab: 'mysub',
|
tab: 'mysub',
|
||||||
icon: 'mdi-movie-roll',
|
icon: 'mdi-movie-open-outline',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '热门订阅',
|
title: '热门订阅',
|
||||||
tab: 'popular',
|
tab: 'popular',
|
||||||
icon: 'mdi-movie-roll',
|
icon: 'mdi-movie-open-outline',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -200,12 +200,12 @@ export const SubscribeTvTabs = [
|
|||||||
{
|
{
|
||||||
title: '我的订阅',
|
title: '我的订阅',
|
||||||
tab: 'mysub',
|
tab: 'mysub',
|
||||||
icon: 'mdi-television-classic',
|
icon: 'mdi-television',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '热门订阅',
|
title: '热门订阅',
|
||||||
tab: 'popular',
|
tab: 'popular',
|
||||||
icon: 'mdi-television-classic',
|
icon: 'mdi-television',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import PluginCard from '@/components/cards/PluginCard.vue'
|
|||||||
import noImage from '@images/logos/plugin.png'
|
import noImage from '@images/logos/plugin.png'
|
||||||
import { useDisplay } from 'vuetify'
|
import { useDisplay } from 'vuetify'
|
||||||
import { isNullOrEmptyObject } from '@/@core/utils'
|
import { isNullOrEmptyObject } from '@/@core/utils'
|
||||||
import router from '@/router'
|
|
||||||
import { PluginTabs } from '@/router/menu'
|
import { PluginTabs } from '@/router/menu'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@@ -39,6 +38,9 @@ const sortOptions = [
|
|||||||
{ title: '最新发布', value: 'add_time' },
|
{ title: '最新发布', value: 'add_time' },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// 加载中
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
// 已安装插件列表
|
// 已安装插件列表
|
||||||
const dataList = ref<Plugin[]>([])
|
const dataList = ref<Plugin[]>([])
|
||||||
|
|
||||||
@@ -198,11 +200,13 @@ const filterPlugins = computed(() => {
|
|||||||
// 获取插件列表数据
|
// 获取插件列表数据
|
||||||
async function fetchInstalledPlugins() {
|
async function fetchInstalledPlugins() {
|
||||||
try {
|
try {
|
||||||
|
loading.value = true
|
||||||
dataList.value = await api.get('plugin/', {
|
dataList.value = await api.get('plugin/', {
|
||||||
params: {
|
params: {
|
||||||
state: 'installed',
|
state: 'installed',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
loading.value = false
|
||||||
isRefreshed.value = true
|
isRefreshed.value = true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
@@ -212,6 +216,7 @@ async function fetchInstalledPlugins() {
|
|||||||
// 获取未安装插件列表数据
|
// 获取未安装插件列表数据
|
||||||
async function fetchUninstalledPlugins() {
|
async function fetchUninstalledPlugins() {
|
||||||
try {
|
try {
|
||||||
|
loading.value = true
|
||||||
uninstalledList.value = await api.get('plugin/', {
|
uninstalledList.value = await api.get('plugin/', {
|
||||||
params: {
|
params: {
|
||||||
state: 'market',
|
state: 'market',
|
||||||
@@ -227,6 +232,8 @@ async function fetchUninstalledPlugins() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
loading.value = false
|
||||||
|
isRefreshed.value = true
|
||||||
// 更新插件市场列表
|
// 更新插件市场列表
|
||||||
// 排除已安装且有更新的,上面的问题在于“本地存在未安装的旧版本插件且云端有更新时”不会在插件市场展示
|
// 排除已安装且有更新的,上面的问题在于“本地存在未安装的旧版本插件且云端有更新时”不会在插件市场展示
|
||||||
marketList.value = uninstalledList.value.filter(item => !(item.has_update && item.installed))
|
marketList.value = uninstalledList.value.filter(item => !(item.has_update && item.installed))
|
||||||
@@ -312,11 +319,6 @@ function handleRepoUrl(url: string | undefined) {
|
|||||||
return url.replace('https://github.com/', '').replace('https://raw.githubusercontent.com/', '')
|
return url.replace('https://github.com/', '').replace('https://raw.githubusercontent.com/', '')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跳转tab
|
|
||||||
function jumpTab(tab: string) {
|
|
||||||
router.push('/plugins?tab=' + tab)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载时获取数据
|
// 加载时获取数据
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
await refreshData()
|
await refreshData()
|
||||||
@@ -334,7 +336,7 @@ onBeforeMount(async () => {
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<VTabs v-model="activeTab">
|
<VTabs v-model="activeTab">
|
||||||
<VTab v-for="item in PluginTabs" :value="item.tab" @click="jumpTab(item.tab)">
|
<VTab v-for="item in PluginTabs" :value="item.tab">
|
||||||
<span class="mx-5">{{ item.title }}</span>
|
<span class="mx-5">{{ item.title }}</span>
|
||||||
</VTab>
|
</VTab>
|
||||||
</VTabs>
|
</VTabs>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import SiteCard from '@/components/cards/SiteCard.vue'
|
|||||||
import NoDataFound from '@/components/NoDataFound.vue'
|
import NoDataFound from '@/components/NoDataFound.vue'
|
||||||
import SiteAddEditDialog from '@/components/dialog/SiteAddEditDialog.vue'
|
import SiteAddEditDialog from '@/components/dialog/SiteAddEditDialog.vue'
|
||||||
import { useDisplay } from 'vuetify'
|
import { useDisplay } from 'vuetify'
|
||||||
|
import { isLength } from 'lodash'
|
||||||
|
|
||||||
// 显示器宽度
|
// 显示器宽度
|
||||||
const display = useDisplay()
|
const display = useDisplay()
|
||||||
@@ -21,13 +22,18 @@ const dataList = ref<Site[]>([])
|
|||||||
// 是否刷新过
|
// 是否刷新过
|
||||||
const isRefreshed = ref(false)
|
const isRefreshed = ref(false)
|
||||||
|
|
||||||
|
// 是否加载中
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
// 新增站点对话框
|
// 新增站点对话框
|
||||||
const siteAddDialog = ref(false)
|
const siteAddDialog = ref(false)
|
||||||
|
|
||||||
// 获取站点列表数据
|
// 获取站点列表数据
|
||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
try {
|
try {
|
||||||
|
loading.value = true
|
||||||
dataList.value = await api.get('site/')
|
dataList.value = await api.get('site/')
|
||||||
|
loading.value = false
|
||||||
isRefreshed.value = true
|
isRefreshed.value = true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
@@ -50,6 +56,12 @@ async function savaSitesPriority() {
|
|||||||
|
|
||||||
// 加载时获取数据
|
// 加载时获取数据
|
||||||
onBeforeMount(fetchData)
|
onBeforeMount(fetchData)
|
||||||
|
|
||||||
|
onActivated(() => {
|
||||||
|
if (!loading.value) {
|
||||||
|
fetchData()
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<script lang='ts' setup>
|
<script lang="ts" setup>
|
||||||
import type { CalendarOptions, EventSourceInput } from '@fullcalendar/core'
|
import type { CalendarOptions, EventSourceInput } from '@fullcalendar/core'
|
||||||
import dayGridPlugin from '@fullcalendar/daygrid'
|
import dayGridPlugin from '@fullcalendar/daygrid'
|
||||||
import interactionPlugin from '@fullcalendar/interaction'
|
import interactionPlugin from '@fullcalendar/interaction'
|
||||||
@@ -8,6 +8,13 @@ import type { Ref } from 'vue'
|
|||||||
import type { MediaInfo, Subscribe, TmdbEpisode } from '@/api/types'
|
import type { MediaInfo, Subscribe, TmdbEpisode } from '@/api/types'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import { formatEp, parseDate } from '@/@core/utils/formatters'
|
import { formatEp, parseDate } from '@/@core/utils/formatters'
|
||||||
|
import ProgressDialog from '@/components/dialog/ProgressDialog.vue'
|
||||||
|
|
||||||
|
// 进度框
|
||||||
|
const progressDialog = ref(false)
|
||||||
|
|
||||||
|
// 加载中
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
// 日历属性
|
// 日历属性
|
||||||
const calendarOptions: Ref<CalendarOptions> = ref({
|
const calendarOptions: Ref<CalendarOptions> = ref({
|
||||||
@@ -51,12 +58,9 @@ async function eventsHander(subscribe: Subscribe) {
|
|||||||
mediaType: subscribe.type,
|
mediaType: subscribe.type,
|
||||||
len: 1,
|
len: 1,
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// 调用API查询集信息
|
// 调用API查询集信息
|
||||||
const episodes: TmdbEpisode[] = await api.get(
|
const episodes: TmdbEpisode[] = await api.get(`tmdb/${subscribe.tmdbid}/${subscribe.season}`)
|
||||||
`tmdb/${subscribe.tmdbid}/${subscribe.season}`,
|
|
||||||
)
|
|
||||||
|
|
||||||
interface EpisodeInfo {
|
interface EpisodeInfo {
|
||||||
title: string
|
title: string
|
||||||
@@ -78,8 +82,7 @@ async function eventsHander(subscribe: Subscribe) {
|
|||||||
if (dictEpisode[air_date]) {
|
if (dictEpisode[air_date]) {
|
||||||
dictEpisode[air_date].subtitle += `,${episode.episode_number}`
|
dictEpisode[air_date].subtitle += `,${episode.episode_number}`
|
||||||
dictEpisode[air_date].len++
|
dictEpisode[air_date].len++
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
dictEpisode[air_date] = {
|
dictEpisode[air_date] = {
|
||||||
title: subscribe.name,
|
title: subscribe.name,
|
||||||
subtitle: `${episode.episode_number}`,
|
subtitle: `${episode.episode_number}`,
|
||||||
@@ -100,25 +103,30 @@ async function eventsHander(subscribe: Subscribe) {
|
|||||||
|
|
||||||
// 调用API查询所有订阅
|
// 调用API查询所有订阅
|
||||||
async function getSubscribes() {
|
async function getSubscribes() {
|
||||||
|
progressDialog.value = true
|
||||||
try {
|
try {
|
||||||
// 订阅
|
// 订阅
|
||||||
|
loading.value = true
|
||||||
const subscribes: Subscribe[] = await api.get('subscribe/')
|
const subscribes: Subscribe[] = await api.get('subscribe/')
|
||||||
|
loading.value = false
|
||||||
const subEvents = await Promise.all(
|
const subEvents = await Promise.all(subscribes.map(async sub => eventsHander(sub)))
|
||||||
subscribes.map(async sub => eventsHander(sub)),
|
|
||||||
)
|
|
||||||
|
|
||||||
calendarOptions.value.events = subEvents.flat().filter(event => event.start) as EventSourceInput
|
calendarOptions.value.events = subEvents.flat().filter(event => event.start) as EventSourceInput
|
||||||
}
|
} catch (error) {
|
||||||
catch (error) {
|
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
|
progressDialog.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 页面加载时调用API查询所有订阅
|
// 页面加载时调用API查询所有订阅
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getSubscribes()
|
getSubscribes()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onActivated(() => {
|
||||||
|
if (!loading.value) {
|
||||||
|
getSubscribes()
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -186,9 +194,10 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</FullCalendar>
|
</FullCalendar>
|
||||||
|
<ProgressDialog v-if="progressDialog" v-model="progressDialog" text="正在加载 ..." />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang='scss'>
|
<style lang="scss">
|
||||||
.v-application .fc {
|
.v-application .fc {
|
||||||
--fc-today-bg-color: rgba(var(--v-theme-on-surface), 0.04);
|
--fc-today-bg-color: rgba(var(--v-theme-on-surface), 0.04);
|
||||||
--fc-border-color: rgba(var(--v-border-color), var(--v-border-opacity));
|
--fc-border-color: rgba(var(--v-border-color), var(--v-border-opacity));
|
||||||
@@ -200,7 +209,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
// 当天背景渐变
|
// 当天背景渐变
|
||||||
.fc-day-today {
|
.fc-day-today {
|
||||||
background-image: linear-gradient(to bottom, #AF85FD ,rgba(var(--v-theme-on-surface), 0.04));
|
background-image: linear-gradient(to bottom, #af85fd, rgba(var(--v-theme-on-surface), 0.04));
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-application .fc a {
|
.v-application .fc a {
|
||||||
@@ -295,11 +304,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
.v-application .fc .fc-toolbar-chunk .fc-button-group .fc-button-primary,
|
.v-application .fc .fc-toolbar-chunk .fc-button-group .fc-button-primary,
|
||||||
.v-application .fc .fc-toolbar-chunk .fc-button-group .fc-button-primary:hover,
|
.v-application .fc .fc-toolbar-chunk .fc-button-group .fc-button-primary:hover,
|
||||||
.v-application
|
.v-application .fc .fc-toolbar-chunk .fc-button-group .fc-button-primary:not(.disabled):active {
|
||||||
.fc
|
|
||||||
.fc-toolbar-chunk
|
|
||||||
.fc-button-group
|
|
||||||
.fc-button-primary:not(.disabled):active {
|
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
|
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
|
||||||
@@ -323,19 +328,11 @@ onMounted(() => {
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-application
|
.v-application .fc .fc-toolbar-chunk:last-child .fc-button-group .fc-button:not(:last-child) {
|
||||||
.fc
|
|
||||||
.fc-toolbar-chunk:last-child
|
|
||||||
.fc-button-group
|
|
||||||
.fc-button:not(:last-child) {
|
|
||||||
border-inline-end: 0.0625rem solid rgba(var(--v-theme-primary), var(--v-overlay-scrim-opacity));
|
border-inline-end: 0.0625rem solid rgba(var(--v-theme-primary), var(--v-overlay-scrim-opacity));
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-application
|
.v-application .fc .fc-toolbar-chunk:last-child .fc-button-group .fc-button.fc-button-active {
|
||||||
.fc
|
|
||||||
.fc-toolbar-chunk:last-child
|
|
||||||
.fc-button-group
|
|
||||||
.fc-button.fc-button-active {
|
|
||||||
background-color: rgba(var(--v-theme-primary), var(--v-activated-opacity));
|
background-color: rgba(var(--v-theme-primary), var(--v-activated-opacity));
|
||||||
color: rgb(var(--v-theme-primary));
|
color: rgb(var(--v-theme-primary));
|
||||||
}
|
}
|
||||||
@@ -371,7 +368,7 @@ onMounted(() => {
|
|||||||
padding-inline: 0.25rem;
|
padding-inline: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-application .fc tbody[role="rowgroup"] > tr > td[role="presentation"] {
|
.v-application .fc tbody[role='rowgroup'] > tr > td[role='presentation'] {
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,8 +397,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
.v-application .fc .fc-popover {
|
.v-application .fc .fc-popover {
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
box-shadow: 0 4px 14px -4px var(--v-shadow-key-umbra-opacity),
|
box-shadow: 0 4px 14px -4px var(--v-shadow-key-umbra-opacity), 0 4px 8px -4px var(--v-shadow-key-penumbra-opacity),
|
||||||
0 4px 8px -4px var(--v-shadow-key-penumbra-opacity),
|
|
||||||
0 4px 8px -4px var(--v-shadow-key-ambient-opacity);
|
0 4px 8px -4px var(--v-shadow-key-ambient-opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,12 +437,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-theme--dark
|
.v-theme--dark .v-application .fc .fc-toolbar-chunk .fc-button-group .fc-drawerToggler-button {
|
||||||
.v-application
|
|
||||||
.fc
|
|
||||||
.fc-toolbar-chunk
|
|
||||||
.fc-button-group
|
|
||||||
.fc-drawerToggler-button {
|
|
||||||
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' stroke='rgba(232,232,241,0.68)' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round' class='css-i6dzq1'%3E%3Cpath d='M3 12h18M3 6h18M3 18h18'/%3E%3C/svg%3E");
|
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' stroke='rgba(232,232,241,0.68)' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round' class='css-i6dzq1'%3E%3Cpath d='M3 12h18M3 6h18M3 18h18'/%3E%3C/svg%3E");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 是否刷新过
|
// 是否刷新过
|
||||||
const isRefreshed = ref(false)
|
let isRefreshed = ref(false)
|
||||||
|
|
||||||
// 数据列表
|
// 数据列表
|
||||||
const dataList = ref<Subscribe[]>([])
|
const dataList = ref<Subscribe[]>([])
|
||||||
@@ -38,7 +38,9 @@ const historyDialog = ref(false)
|
|||||||
// 获取订阅列表数据
|
// 获取订阅列表数据
|
||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
try {
|
try {
|
||||||
|
loading.value = true
|
||||||
dataList.value = await api.get('subscribe/')
|
dataList.value = await api.get('subscribe/')
|
||||||
|
loading.value = false
|
||||||
isRefreshed.value = true
|
isRefreshed.value = true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
@@ -49,10 +51,9 @@ async function fetchData() {
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
||||||
// 下拉刷新
|
// 下拉刷新
|
||||||
function onRefresh() {
|
async function onRefresh({ done }: { done: any }) {
|
||||||
loading.value = true
|
await fetchData()
|
||||||
fetchData()
|
done('ok')
|
||||||
loading.value = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 过滤数据,管理员用户显示全部,非管理员只显示自己的订阅
|
// 过滤数据,管理员用户显示全部,非管理员只显示自己的订阅
|
||||||
@@ -75,6 +76,12 @@ onMounted(async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
onActivated(async () => {
|
||||||
|
if (!loading.value) {
|
||||||
|
fetchData()
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -76,13 +76,13 @@ async function fetchData({ done }: { done: any }) {
|
|||||||
done('ok')
|
done('ok')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 加载一次
|
|
||||||
// 设置加载中
|
// 设置加载中
|
||||||
loading.value = true
|
loading.value = true
|
||||||
// 请求API
|
// 请求API
|
||||||
currData.value = await api.get(apipath, {
|
currData.value = await api.get(apipath, {
|
||||||
params: getParams(),
|
params: getParams(),
|
||||||
})
|
})
|
||||||
|
loading.value = false
|
||||||
// 标计为已请求完成
|
// 标计为已请求完成
|
||||||
isRefreshed.value = true
|
isRefreshed.value = true
|
||||||
if (currData.value.length === 0) {
|
if (currData.value.length === 0) {
|
||||||
@@ -97,8 +97,6 @@ async function fetchData({ done }: { done: any }) {
|
|||||||
done('ok')
|
done('ok')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 取消加载中
|
|
||||||
loading.value = false
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
// 返回加载失败
|
// 返回加载失败
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
<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 {
|
import { SystemNavMenus, UserfulMenus, PluginTabs, SettingTabs } from '@/router/menu'
|
||||||
SystemNavMenus,
|
|
||||||
UserfulMenus,
|
|
||||||
SubscribeMovieTabs,
|
|
||||||
SubscribeTvTabs,
|
|
||||||
PluginTabs,
|
|
||||||
SettingTabs,
|
|
||||||
} from '@/router/menu'
|
|
||||||
import { NavMenu } from '@/@layouts/types'
|
import { NavMenu } from '@/@layouts/types'
|
||||||
|
|
||||||
// 路由
|
// 路由
|
||||||
@@ -54,14 +47,14 @@ function getMenus(): NavMenu[] {
|
|||||||
item =>
|
item =>
|
||||||
item &&
|
item &&
|
||||||
menus.push({
|
menus.push({
|
||||||
title: item.title,
|
title: item.full_title ?? item.title,
|
||||||
icon: item.icon,
|
icon: item.icon,
|
||||||
to: item.to,
|
to: item.to,
|
||||||
header: item.header,
|
header: item.header,
|
||||||
admin: item.admin,
|
admin: item.admin,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
// 各类标签页
|
// 设置标签页
|
||||||
SettingTabs.forEach(
|
SettingTabs.forEach(
|
||||||
item =>
|
item =>
|
||||||
item &&
|
item &&
|
||||||
@@ -74,39 +67,6 @@ function getMenus(): NavMenu[] {
|
|||||||
description: item.description,
|
description: item.description,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
SubscribeMovieTabs.forEach(
|
|
||||||
item =>
|
|
||||||
item &&
|
|
||||||
menus.push({
|
|
||||||
title: '电影 -> ' + item.title,
|
|
||||||
icon: item.icon,
|
|
||||||
to: `/subscribe-movie?tab=${item.tab}`,
|
|
||||||
header: '',
|
|
||||||
admin: false,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
SubscribeTvTabs.forEach(
|
|
||||||
item =>
|
|
||||||
item &&
|
|
||||||
menus.push({
|
|
||||||
title: '电视剧 -> ' + item.title,
|
|
||||||
icon: item.icon,
|
|
||||||
to: `/subscribe-tv?tab=${item.tab}`,
|
|
||||||
header: '',
|
|
||||||
admin: false,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
PluginTabs.forEach(
|
|
||||||
item =>
|
|
||||||
item &&
|
|
||||||
menus.push({
|
|
||||||
title: '插件 -> ' + item.title,
|
|
||||||
icon: item.icon,
|
|
||||||
to: `/plugins?tab=${item.tab}`,
|
|
||||||
header: '',
|
|
||||||
admin: true,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
return menus
|
return menus
|
||||||
}
|
}
|
||||||
@@ -236,14 +196,14 @@ function goPage(to: string) {
|
|||||||
function goSubscribe(subscribe: Subscribe) {
|
function goSubscribe(subscribe: Subscribe) {
|
||||||
if (subscribe.type === '电影') {
|
if (subscribe.type === '电影') {
|
||||||
router.push({
|
router.push({
|
||||||
path: '/subscribe-movie',
|
path: '/subscribe/movie',
|
||||||
query: {
|
query: {
|
||||||
id: subscribe.id,
|
id: subscribe.id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
router.push({
|
router.push({
|
||||||
path: '/subscribe-tv',
|
path: '/subscribe/tv',
|
||||||
query: {
|
query: {
|
||||||
id: subscribe.id,
|
id: subscribe.id,
|
||||||
},
|
},
|
||||||
|
|||||||
+2
-2
@@ -90,7 +90,7 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': '电影订阅',
|
'name': '电影订阅',
|
||||||
'url': './subscribe-movie?tab=mysub',
|
'url': './subscribe/movie',
|
||||||
'icons': [
|
'icons': [
|
||||||
{
|
{
|
||||||
'src': './clock-icon-192x192.png',
|
'src': './clock-icon-192x192.png',
|
||||||
@@ -101,7 +101,7 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': '电视剧订阅',
|
'name': '电视剧订阅',
|
||||||
'url': './subscribe-tv?tab=mysub',
|
'url': './subscribe/tv',
|
||||||
'icons': [
|
'icons': [
|
||||||
{
|
{
|
||||||
'src': './clock-icon-192x192.png',
|
'src': './clock-icon-192x192.png',
|
||||||
|
|||||||
Reference in New Issue
Block a user