mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 23:56:42 +08:00
feat:媒体搜索聚合开关设置
This commit is contained in:
@@ -30,9 +30,28 @@ const selectedSites = ref<number[]>([])
|
|||||||
const defaultFilterRules = ref({
|
const defaultFilterRules = ref({
|
||||||
include: '',
|
include: '',
|
||||||
exclude: '',
|
exclude: '',
|
||||||
min_seeders: 0
|
min_seeders: 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 媒体信息数据源字典
|
||||||
|
const mediaSourcesDict = [
|
||||||
|
{
|
||||||
|
title: 'TheMovieDb',
|
||||||
|
value: 'themoviedb',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '豆瓣',
|
||||||
|
value: 'douban',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Bangumi',
|
||||||
|
value: 'bangumi',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
// 当前选中的媒体信息数据源
|
||||||
|
const selectedMediaSource = ref([])
|
||||||
|
|
||||||
// 导入代码弹窗
|
// 导入代码弹窗
|
||||||
const importCodeDialog = ref(false)
|
const importCodeDialog = ref(false)
|
||||||
|
|
||||||
@@ -55,8 +74,7 @@ async function queryCustomFilters() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
} catch (error) {
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,17 +92,11 @@ async function saveCustomFilters() {
|
|||||||
.join('>')
|
.join('>')
|
||||||
}
|
}
|
||||||
// 保存
|
// 保存
|
||||||
const result: { [key: string]: any } = await api.post(
|
const result: { [key: string]: any } = await api.post('system/setting/SearchFilterRules', value)
|
||||||
'system/setting/SearchFilterRules',
|
|
||||||
value,
|
|
||||||
)
|
|
||||||
|
|
||||||
if (result.success)
|
if (result.success) $toast.success('搜索优先级保存成功')
|
||||||
$toast.success('搜索优先级保存成功')
|
else $toast.error('搜索优先级保存失败!')
|
||||||
else
|
} catch (error) {
|
||||||
$toast.error('搜索优先级保存失败!')
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,8 +104,7 @@ async function saveCustomFilters() {
|
|||||||
// 更新规则卡片的值
|
// 更新规则卡片的值
|
||||||
function updateFilterCardValue(pri: string, rules: string[]) {
|
function updateFilterCardValue(pri: string, rules: string[]) {
|
||||||
const card = filterCards.value.find(card => card.pri === pri)
|
const card = filterCards.value.find(card => card.pri === pri)
|
||||||
if (card)
|
if (card) card.rules = rules
|
||||||
card.rules = rules
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 移除卡片
|
// 移除卡片
|
||||||
@@ -129,8 +140,7 @@ async function querySites() {
|
|||||||
// 过滤站点,只有启用的站点才显示
|
// 过滤站点,只有启用的站点才显示
|
||||||
allSites.value = data.filter(item => item.is_active)
|
allSites.value = data.filter(item => item.is_active)
|
||||||
querySelectedSites()
|
querySelectedSites()
|
||||||
}
|
} catch (error) {
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,8 +151,7 @@ async function querySelectedSites() {
|
|||||||
const result: { [key: string]: any } = await api.get('system/setting/IndexerSites')
|
const result: { [key: string]: any } = await api.get('system/setting/IndexerSites')
|
||||||
|
|
||||||
selectedSites.value = result.data?.value ?? []
|
selectedSites.value = result.data?.value ?? []
|
||||||
}
|
} catch (error) {
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,12 +162,9 @@ async function saveSelectedSites() {
|
|||||||
// 用户名密码
|
// 用户名密码
|
||||||
const result: { [key: string]: any } = await api.post('system/setting/IndexerSites', selectedSites.value)
|
const result: { [key: string]: any } = await api.post('system/setting/IndexerSites', selectedSites.value)
|
||||||
|
|
||||||
if (result.success)
|
if (result.success) $toast.success('搜索站点保存成功')
|
||||||
$toast.success('搜索站点保存成功')
|
else $toast.error('搜索站点保存失败!')
|
||||||
else
|
} catch (error) {
|
||||||
$toast.error('搜索站点保存失败!')
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -167,13 +173,11 @@ async function saveSelectedSites() {
|
|||||||
function onLevelUp(pri: string) {
|
function onLevelUp(pri: string) {
|
||||||
// 找到当前卡片
|
// 找到当前卡片
|
||||||
const card = filterCards.value.find(card => card.pri === pri)
|
const card = filterCards.value.find(card => card.pri === pri)
|
||||||
if (!card)
|
if (!card) return
|
||||||
return
|
|
||||||
|
|
||||||
// 找到当前卡片的上一张卡片
|
// 找到当前卡片的上一张卡片
|
||||||
const prevCard = filterCards.value.find(card => card.pri === (parseInt(pri) - 1).toString())
|
const prevCard = filterCards.value.find(card => card.pri === (parseInt(pri) - 1).toString())
|
||||||
if (!prevCard)
|
if (!prevCard) return
|
||||||
return
|
|
||||||
|
|
||||||
// 交换两张卡片的优先级
|
// 交换两张卡片的优先级
|
||||||
const temp = card.pri
|
const temp = card.pri
|
||||||
@@ -188,13 +192,11 @@ function onLevelUp(pri: string) {
|
|||||||
function onLevelDown(pri: string) {
|
function onLevelDown(pri: string) {
|
||||||
// 找到当前卡片
|
// 找到当前卡片
|
||||||
const card = filterCards.value.find(card => card.pri === pri)
|
const card = filterCards.value.find(card => card.pri === pri)
|
||||||
if (!card)
|
if (!card) return
|
||||||
return
|
|
||||||
|
|
||||||
// 找到当前卡片的下一张卡片
|
// 找到当前卡片的下一张卡片
|
||||||
const nextCard = filterCards.value.find(card => card.pri === (parseInt(pri) + 1).toString())
|
const nextCard = filterCards.value.find(card => card.pri === (parseInt(pri) + 1).toString())
|
||||||
if (!nextCard)
|
if (!nextCard) return
|
||||||
return
|
|
||||||
|
|
||||||
// 交换两张卡片的优先级
|
// 交换两张卡片的优先级
|
||||||
const temp = card.pri
|
const temp = card.pri
|
||||||
@@ -208,13 +210,9 @@ function onLevelDown(pri: string) {
|
|||||||
// 查询包含与排除规则
|
// 查询包含与排除规则
|
||||||
async function queryDefaultFilter() {
|
async function queryDefaultFilter() {
|
||||||
try {
|
try {
|
||||||
const result: { [key: string]: any } = await api.get(
|
const result: { [key: string]: any } = await api.get('system/setting/DefaultSearchFilterRules')
|
||||||
'system/setting/DefaultSearchFilterRules',
|
if (result.data?.value) defaultFilterRules.value = result.data?.value
|
||||||
)
|
} catch (error) {
|
||||||
if (result.data?.value)
|
|
||||||
defaultFilterRules.value = result.data?.value
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,12 +224,9 @@ async function saveDefaultFilter() {
|
|||||||
'system/setting/DefaultSearchFilterRules',
|
'system/setting/DefaultSearchFilterRules',
|
||||||
defaultFilterRules.value,
|
defaultFilterRules.value,
|
||||||
)
|
)
|
||||||
if (result.success)
|
if (result.success) $toast.success('默认包含/排除规则保存成功')
|
||||||
$toast.success('默认包含/排除规则保存成功')
|
else $toast.error('默认包含/排除规则保存失败!')
|
||||||
else
|
} catch (error) {
|
||||||
$toast.error('默认包含/排除规则保存失败!')
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -239,8 +234,7 @@ async function saveDefaultFilter() {
|
|||||||
// 分享规则
|
// 分享规则
|
||||||
function shareRules() {
|
function shareRules() {
|
||||||
// 有值才处理
|
// 有值才处理
|
||||||
if (filterCards.value.length === 0)
|
if (filterCards.value.length === 0) return
|
||||||
return
|
|
||||||
|
|
||||||
// 将卡片规则接装为字符串
|
// 将卡片规则接装为字符串
|
||||||
const value = filterCards.value
|
const value = filterCards.value
|
||||||
@@ -252,22 +246,18 @@ function shareRules() {
|
|||||||
try {
|
try {
|
||||||
copyToClipboard(value)
|
copyToClipboard(value)
|
||||||
$toast.success('优先级规则已复制到剪贴板')
|
$toast.success('优先级规则已复制到剪贴板')
|
||||||
}
|
} catch (error) {
|
||||||
catch (error) {
|
|
||||||
$toast.error('优先级规则复制失败!')
|
$toast.error('优先级规则复制失败!')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听导入代码变化
|
// 监听导入代码变化
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
if (!importCodeString.value)
|
if (!importCodeString.value) return
|
||||||
return
|
|
||||||
|
|
||||||
// 导入代码需要以空格开头和结束,没有则拼接
|
// 导入代码需要以空格开头和结束,没有则拼接
|
||||||
if (!importCodeString.value.startsWith(' '))
|
if (!importCodeString.value.startsWith(' ')) importCodeString.value = ` ${importCodeString.value}`
|
||||||
importCodeString.value = ` ${importCodeString.value}`
|
if (!importCodeString.value.endsWith(' ')) importCodeString.value = `${importCodeString.value} `
|
||||||
if (!importCodeString.value.endsWith(' '))
|
|
||||||
importCodeString.value = `${importCodeString.value} `
|
|
||||||
|
|
||||||
// 将导入的代码转换为规则卡片
|
// 将导入的代码转换为规则卡片
|
||||||
const groups = importCodeString.value.split('>')
|
const groups = importCodeString.value.split('>')
|
||||||
@@ -279,15 +269,67 @@ watchEffect(() => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 调用API查询下载器设置
|
||||||
|
async function loadMediaSourceSetting() {
|
||||||
|
try {
|
||||||
|
const result1: { [key: string]: any } = await api.get('system/setting/SEARCH_SOURCE')
|
||||||
|
if (result1.success) selectedMediaSource.value = result1.data?.value?.split(',')
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用API保存下载器设置
|
||||||
|
async function saveMediaSourceSetting() {
|
||||||
|
try {
|
||||||
|
const result: { [key: string]: any } = await api.post(
|
||||||
|
'system/setting/SEARCH_SOURCE',
|
||||||
|
selectedMediaSource.value.join(','),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
$toast.success('保存媒体数据源设置成功')
|
||||||
|
} else {
|
||||||
|
$toast.error('保存媒体数据源设置失败!')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
queryCustomFilters()
|
queryCustomFilters()
|
||||||
querySites()
|
querySites()
|
||||||
queryDefaultFilter()
|
queryDefaultFilter()
|
||||||
|
loadMediaSourceSetting()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VRow>
|
<VRow>
|
||||||
|
<VCol cols="12">
|
||||||
|
<VCard title="媒体数据源">
|
||||||
|
<VCardSubtitle> 设定搜索时展示哪些源的媒体信息。</VCardSubtitle>
|
||||||
|
<VCardText>
|
||||||
|
<VRow>
|
||||||
|
<VCol cols="12" md="6">
|
||||||
|
<VSelect
|
||||||
|
v-model="selectedMediaSource"
|
||||||
|
multiple
|
||||||
|
chips
|
||||||
|
:items="mediaSourcesDict"
|
||||||
|
label="当前使用数据源"
|
||||||
|
hint="选中多项时会同时展示来自不同数据源的搜索结果"
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</VCardText>
|
||||||
|
|
||||||
|
<VCardItem>
|
||||||
|
<VBtn type="submit" @click="saveMediaSourceSetting"> 保存 </VBtn>
|
||||||
|
</VCardItem>
|
||||||
|
</VCard>
|
||||||
|
</VCol>
|
||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VCard title="搜索站点">
|
<VCard title="搜索站点">
|
||||||
<VCardSubtitle> 只有选中的站点才会在搜索中使用。</VCardSubtitle>
|
<VCardSubtitle> 只有选中的站点才会在搜索中使用。</VCardSubtitle>
|
||||||
@@ -308,9 +350,7 @@ onMounted(() => {
|
|||||||
</VCardItem>
|
</VCardItem>
|
||||||
|
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VBtn type="submit" @click="saveSelectedSites">
|
<VBtn type="submit" @click="saveSelectedSites"> 保存 </VBtn>
|
||||||
保存
|
|
||||||
</VBtn>
|
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
</VCard>
|
</VCard>
|
||||||
</VCol>
|
</VCol>
|
||||||
@@ -319,24 +359,15 @@ onMounted(() => {
|
|||||||
<template #append>
|
<template #append>
|
||||||
<IconBtn>
|
<IconBtn>
|
||||||
<VIcon icon="mdi-dots-vertical" />
|
<VIcon icon="mdi-dots-vertical" />
|
||||||
<VMenu
|
<VMenu activator="parent" close-on-content-click>
|
||||||
activator="parent"
|
|
||||||
close-on-content-click
|
|
||||||
>
|
|
||||||
<VList>
|
<VList>
|
||||||
<VListItem
|
<VListItem variant="plain" @click="shareRules">
|
||||||
variant="plain"
|
|
||||||
@click="shareRules"
|
|
||||||
>
|
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<VIcon icon="mdi-share" />
|
<VIcon icon="mdi-share" />
|
||||||
</template>
|
</template>
|
||||||
<VListItemTitle>分享</VListItemTitle>
|
<VListItemTitle>分享</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
<VListItem
|
<VListItem variant="plain" @click="importCodeDialog = true">
|
||||||
variant="plain"
|
|
||||||
@click="importCodeDialog = true"
|
|
||||||
>
|
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<VIcon icon="mdi-import" />
|
<VIcon icon="mdi-import" />
|
||||||
</template>
|
</template>
|
||||||
@@ -363,18 +394,8 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VBtn
|
<VBtn type="submit" class="me-2" @click="saveCustomFilters()"> 保存 </VBtn>
|
||||||
type="submit"
|
<VBtn color="success" variant="tonal" @click="addFilterCard()">
|
||||||
class="me-2"
|
|
||||||
@click="saveCustomFilters()"
|
|
||||||
>
|
|
||||||
保存
|
|
||||||
</VBtn>
|
|
||||||
<VBtn
|
|
||||||
color="success"
|
|
||||||
variant="tonal"
|
|
||||||
@click="addFilterCard()"
|
|
||||||
>
|
|
||||||
<VIcon icon="mdi-plus" />
|
<VIcon icon="mdi-plus" />
|
||||||
</VBtn>
|
</VBtn>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
@@ -415,26 +436,13 @@ onMounted(() => {
|
|||||||
</VForm>
|
</VForm>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VBtn
|
<VBtn type="submit" @click="saveDefaultFilter"> 保存 </VBtn>
|
||||||
type="submit"
|
|
||||||
@click="saveDefaultFilter"
|
|
||||||
>
|
|
||||||
保存
|
|
||||||
</VBtn>
|
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
</VCard>
|
</VCard>
|
||||||
</VCol>
|
</VCol>
|
||||||
</VRow>
|
</VRow>
|
||||||
<VDialog
|
<VDialog v-model="importCodeDialog" width="60rem" scrollable>
|
||||||
v-model="importCodeDialog"
|
<ImportCodeDialog v-model="importCodeString" title="导入优先级规则" @close="importCodeDialog = false" />
|
||||||
width="60rem"
|
|
||||||
scrollable
|
|
||||||
>
|
|
||||||
<ImportCodeDialog
|
|
||||||
v-model="importCodeString"
|
|
||||||
title="导入优先级规则"
|
|
||||||
@close="importCodeDialog = false"
|
|
||||||
/>
|
|
||||||
</VDialog>
|
</VDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user