feat: Add filtering and genre selection to subscribe share

Co-authored-by: jxxghp <jxxghp@qq.com>
This commit is contained in:
Cursor Agent
2025-09-16 00:46:08 +00:00
parent dd1447e93c
commit b260427312

View File

@@ -28,6 +28,65 @@ const page = ref(1)
// 搜索关键字
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 变化
watch(
() => props.keyword,
@@ -37,9 +96,19 @@ watch(
page.value = 1
dataList.value = []
isRefreshed.value = false
currentKey.value++
},
)
// 监听筛选参数变化
watch(filterParams, () => {
// 重置数据
dataList.value = []
page.value = 1
isRefreshed.value = false
currentKey.value++
}, { deep: true })
// 是否加载中
const loading = ref(false)
@@ -52,11 +121,23 @@ const currData = ref<SubscribeShare[]>([])
// 拼装参数
function getParams() {
let params = {
let params: { [key: string]: any } = {
page: page.value,
count: 30,
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
}
@@ -131,9 +212,63 @@ function removeData(id: number) {
</script>
<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}`" />
<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 #empty />
<div v-if="dataList.length > 0" class="grid gap-4 grid-subscribe-card" tabindex="0">