mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-04 23:18:44 +08:00
feat: Add filtering and genre selection to subscribe share
Co-authored-by: jxxghp <jxxghp@qq.com>
This commit is contained in:
@@ -28,6 +28,65 @@ const page = ref(1)
|
|||||||
// 搜索关键字
|
// 搜索关键字
|
||||||
const keyword = ref(props.keyword)
|
const keyword = ref(props.keyword)
|
||||||
|
|
||||||
|
// 筛选参数
|
||||||
|
const filterParams = reactive({
|
||||||
|
genre_id: '',
|
||||||
|
min_rating: 0,
|
||||||
|
max_rating: 10,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 当前Key(用于重新加载数据)
|
||||||
|
const currentKey = ref(0)
|
||||||
|
|
||||||
|
// TMDB电影风格字典
|
||||||
|
const tmdbMovieGenreDict: Record<string, string> = {
|
||||||
|
'28': t('tmdb.genreType.action'),
|
||||||
|
'12': t('tmdb.genreType.adventure'),
|
||||||
|
'16': t('tmdb.genreType.animation'),
|
||||||
|
'35': t('tmdb.genreType.comedy'),
|
||||||
|
'80': t('tmdb.genreType.crime'),
|
||||||
|
'99': t('tmdb.genreType.documentary'),
|
||||||
|
'18': t('tmdb.genreType.drama'),
|
||||||
|
'10751': t('tmdb.genreType.family'),
|
||||||
|
'14': t('tmdb.genreType.fantasy'),
|
||||||
|
'36': t('tmdb.genreType.history'),
|
||||||
|
'27': t('tmdb.genreType.horror'),
|
||||||
|
'10402': t('tmdb.genreType.music'),
|
||||||
|
'9648': t('tmdb.genreType.mystery'),
|
||||||
|
'10749': t('tmdb.genreType.romance'),
|
||||||
|
'878': t('tmdb.genreType.scienceFiction'),
|
||||||
|
'10770': t('tmdb.genreType.tvMovie'),
|
||||||
|
'53': t('tmdb.genreType.thriller'),
|
||||||
|
'10752': t('tmdb.genreType.war'),
|
||||||
|
'37': t('tmdb.genreType.western'),
|
||||||
|
}
|
||||||
|
|
||||||
|
// TMDB电视剧风格字典
|
||||||
|
const tmdbTvGenreDict: Record<string, string> = {
|
||||||
|
'10759': t('tmdb.genreType.actionAdventure'),
|
||||||
|
'16': t('tmdb.genreType.animation'),
|
||||||
|
'35': t('tmdb.genreType.comedy'),
|
||||||
|
'80': t('tmdb.genreType.crime'),
|
||||||
|
'99': t('tmdb.genreType.documentary'),
|
||||||
|
'18': t('tmdb.genreType.drama'),
|
||||||
|
'10751': t('tmdb.genreType.family'),
|
||||||
|
'10762': t('tmdb.genreType.kids'),
|
||||||
|
'9648': t('tmdb.genreType.mystery'),
|
||||||
|
'10763': t('tmdb.genreType.news'),
|
||||||
|
'10764': t('tmdb.genreType.reality'),
|
||||||
|
'10765': t('tmdb.genreType.sciFiFantasy'),
|
||||||
|
'10766': t('tmdb.genreType.soap'),
|
||||||
|
'10767': t('tmdb.genreType.talk'),
|
||||||
|
'10768': t('tmdb.genreType.warPolitics'),
|
||||||
|
'37': t('tmdb.genreType.western'),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前类型对应的风格字典(订阅分享包含电影和电视剧,所以显示所有风格)
|
||||||
|
const currentGenreDict = computed(() => {
|
||||||
|
// 合并电影和电视剧风格字典
|
||||||
|
return { ...tmdbMovieGenreDict, ...tmdbTvGenreDict }
|
||||||
|
})
|
||||||
|
|
||||||
// 监听 props.keyword 变化
|
// 监听 props.keyword 变化
|
||||||
watch(
|
watch(
|
||||||
() => props.keyword,
|
() => props.keyword,
|
||||||
@@ -37,9 +96,19 @@ watch(
|
|||||||
page.value = 1
|
page.value = 1
|
||||||
dataList.value = []
|
dataList.value = []
|
||||||
isRefreshed.value = false
|
isRefreshed.value = false
|
||||||
|
currentKey.value++
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 监听筛选参数变化
|
||||||
|
watch(filterParams, () => {
|
||||||
|
// 重置数据
|
||||||
|
dataList.value = []
|
||||||
|
page.value = 1
|
||||||
|
isRefreshed.value = false
|
||||||
|
currentKey.value++
|
||||||
|
}, { deep: true })
|
||||||
|
|
||||||
// 是否加载中
|
// 是否加载中
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
||||||
@@ -52,11 +121,23 @@ const currData = ref<SubscribeShare[]>([])
|
|||||||
|
|
||||||
// 拼装参数
|
// 拼装参数
|
||||||
function getParams() {
|
function getParams() {
|
||||||
let params = {
|
let params: { [key: string]: any } = {
|
||||||
page: page.value,
|
page: page.value,
|
||||||
count: 30,
|
count: 30,
|
||||||
name: keyword.value,
|
name: keyword.value,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加筛选参数
|
||||||
|
if (filterParams.genre_id) {
|
||||||
|
params.genre_id = parseInt(filterParams.genre_id)
|
||||||
|
}
|
||||||
|
if (filterParams.min_rating > 0) {
|
||||||
|
params.min_rating = filterParams.min_rating
|
||||||
|
}
|
||||||
|
if (filterParams.max_rating < 10) {
|
||||||
|
params.max_rating = filterParams.max_rating
|
||||||
|
}
|
||||||
|
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,9 +212,63 @@ function removeData(id: number) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<!-- 筛选器 -->
|
||||||
|
<div class="px-3 mb-4">
|
||||||
|
<div class="flex justify-start align-center mb-3">
|
||||||
|
<div class="mr-5">
|
||||||
|
<VLabel>{{ t('tmdb.genre') }}</VLabel>
|
||||||
|
</div>
|
||||||
|
<VChipGroup v-model="filterParams.genre_id">
|
||||||
|
<VChip
|
||||||
|
:color="filterParams.genre_id == key ? 'primary' : ''"
|
||||||
|
filter
|
||||||
|
tile
|
||||||
|
:value="key"
|
||||||
|
v-for="(value, key) in currentGenreDict"
|
||||||
|
:key="key"
|
||||||
|
>
|
||||||
|
{{ value }}
|
||||||
|
</VChip>
|
||||||
|
</VChipGroup>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-start align-center">
|
||||||
|
<div class="mr-5">
|
||||||
|
<VLabel>{{ t('tmdb.rating') }}</VLabel>
|
||||||
|
</div>
|
||||||
|
<div class="flex align-center" style="width: 300px;">
|
||||||
|
<VTextField
|
||||||
|
v-model="filterParams.min_rating"
|
||||||
|
variant="outlined"
|
||||||
|
density="compact"
|
||||||
|
type="number"
|
||||||
|
hide-details
|
||||||
|
single-line
|
||||||
|
min="0"
|
||||||
|
max="10"
|
||||||
|
step="0.1"
|
||||||
|
style="width: 80px;"
|
||||||
|
/>
|
||||||
|
<span class="mx-2">-</span>
|
||||||
|
<VTextField
|
||||||
|
v-model="filterParams.max_rating"
|
||||||
|
variant="outlined"
|
||||||
|
density="compact"
|
||||||
|
type="number"
|
||||||
|
hide-details
|
||||||
|
single-line
|
||||||
|
min="0"
|
||||||
|
max="10"
|
||||||
|
step="0.1"
|
||||||
|
style="width: 80px;"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<VPageContentTitle v-if="keyword" :title="`${t('common.search')}:${keyword}`" />
|
<VPageContentTitle v-if="keyword" :title="`${t('common.search')}:${keyword}`" />
|
||||||
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||||
<VInfiniteScroll mode="intersect" side="end" :items="dataList" class="overflow-visible px-2" @load="fetchData">
|
<VInfiniteScroll mode="intersect" side="end" :items="dataList" class="overflow-visible px-2" @load="fetchData" :key="currentKey">
|
||||||
<template #loading />
|
<template #loading />
|
||||||
<template #empty />
|
<template #empty />
|
||||||
<div v-if="dataList.length > 0" class="grid gap-4 grid-subscribe-card" tabindex="0">
|
<div v-if="dataList.length > 0" class="grid gap-4 grid-subscribe-card" tabindex="0">
|
||||||
|
|||||||
Reference in New Issue
Block a user