mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-06 16:16:42 +08:00
Merge pull request #456 from wikrin/refactor/scraping-switch-to-policy
This commit is contained in:
@@ -1528,6 +1528,11 @@ export default {
|
|||||||
episodeThumb: 'Thumb',
|
episodeThumb: 'Thumb',
|
||||||
scrapingSwitchSaveFailed: 'Scraping switch settings save failed: {message}',
|
scrapingSwitchSaveFailed: 'Scraping switch settings save failed: {message}',
|
||||||
scrapingSwitchSaveError: 'Scraping switch settings save failed',
|
scrapingSwitchSaveError: 'Scraping switch settings save failed',
|
||||||
|
policy: {
|
||||||
|
skipDesc: 'Skip scraping, this file will not be generated',
|
||||||
|
missingOnlyDesc: 'Scrape only if missing, existing file remains unchanged',
|
||||||
|
overwriteDesc: 'Always scrape, existing file will be overwritten',
|
||||||
|
}
|
||||||
},
|
},
|
||||||
site: {
|
site: {
|
||||||
siteSync: 'Site Synchronization',
|
siteSync: 'Site Synchronization',
|
||||||
|
|||||||
@@ -1515,6 +1515,11 @@ export default {
|
|||||||
episodeThumb: '缩略图',
|
episodeThumb: '缩略图',
|
||||||
scrapingSwitchSaveFailed: '刮削开关设置保存失败:{message}',
|
scrapingSwitchSaveFailed: '刮削开关设置保存失败:{message}',
|
||||||
scrapingSwitchSaveError: '刮削开关设置保存失败',
|
scrapingSwitchSaveError: '刮削开关设置保存失败',
|
||||||
|
policy: {
|
||||||
|
skipDesc: '跳过刮削,不生成该文件',
|
||||||
|
missingOnlyDesc: '仅在缺失时刮削,已存在则保持不变',
|
||||||
|
overwriteDesc: '始终刮削,已存在则覆盖',
|
||||||
|
}
|
||||||
},
|
},
|
||||||
site: {
|
site: {
|
||||||
siteSync: '站点同步',
|
siteSync: '站点同步',
|
||||||
|
|||||||
@@ -1516,6 +1516,11 @@ export default {
|
|||||||
episodeThumb: '縮略圖',
|
episodeThumb: '縮略圖',
|
||||||
scrapingSwitchSaveFailed: '刮削開關設定保存失敗:{message}',
|
scrapingSwitchSaveFailed: '刮削開關設定保存失敗:{message}',
|
||||||
scrapingSwitchSaveError: '刮削開關設定保存失敗',
|
scrapingSwitchSaveError: '刮削開關設定保存失敗',
|
||||||
|
policy: {
|
||||||
|
skipDesc: '跳過刮削,不生成該文件',
|
||||||
|
missingOnlyDesc: '僅在缺失時刮削,已存在則保持不變',
|
||||||
|
overwriteDesc: '始終刮削,已存在則覆蓋',
|
||||||
|
}
|
||||||
},
|
},
|
||||||
site: {
|
site: {
|
||||||
siteSync: '站點同步',
|
siteSync: '站點同步',
|
||||||
|
|||||||
@@ -85,28 +85,57 @@ const SystemSettings = ref<any>({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// 刮削开关设置
|
// 刮削配置
|
||||||
const ScrapingSwitchs = ref<any>({
|
const scrapingConfig = [
|
||||||
movie_nfo: true, // 电影NFO
|
{
|
||||||
movie_poster: true, // 电影海报
|
section: 'movie',
|
||||||
movie_backdrop: true, // 电影背景图
|
items: [
|
||||||
movie_logo: true, // 电影Logo
|
{ key: 'movie_nfo', label: 'setting.system.movieNfo' },
|
||||||
movie_disc: true, // 电影光盘图
|
{ key: 'movie_poster', label: 'setting.system.moviePoster' },
|
||||||
movie_banner: true, // 电影横幅图
|
{ key: 'movie_backdrop', label: 'setting.system.movieBackdrop' },
|
||||||
movie_thumb: true, // 电影缩略图
|
{ key: 'movie_logo', label: 'setting.system.movieLogo' },
|
||||||
tv_nfo: true, // 电视剧NFO
|
{ key: 'movie_disc', label: 'setting.system.movieDisc' },
|
||||||
tv_poster: true, // 电视剧海报
|
{ key: 'movie_banner', label: 'setting.system.movieBanner' },
|
||||||
tv_backdrop: true, // 电视剧背景图
|
{ key: 'movie_thumb', label: 'setting.system.movieThumb' },
|
||||||
tv_banner: true, // 电视剧横幅图
|
],
|
||||||
tv_logo: true, // 电视剧Logo
|
},
|
||||||
tv_thumb: true, // 电视剧缩略图
|
{
|
||||||
season_nfo: true, // 季NFO
|
section: 'tv',
|
||||||
season_poster: true, // 季海报
|
items: [
|
||||||
season_banner: true, // 季横幅图
|
{ key: 'tv_nfo', label: 'setting.system.tvNfo' },
|
||||||
season_thumb: true, // 季缩略图
|
{ key: 'tv_poster', label: 'setting.system.tvPoster' },
|
||||||
episode_nfo: true, // 集NFO
|
{ key: 'tv_backdrop', label: 'setting.system.tvBackdrop' },
|
||||||
episode_thumb: true, // 集缩略图
|
{ key: 'tv_banner', label: 'setting.system.tvBanner' },
|
||||||
})
|
{ key: 'tv_logo', label: 'setting.system.tvLogo' },
|
||||||
|
{ key: 'tv_thumb', label: 'setting.system.tvThumb' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
section: 'season',
|
||||||
|
items: [
|
||||||
|
{ key: 'season_nfo', label: 'setting.system.seasonNfo' },
|
||||||
|
{ key: 'season_poster', label: 'setting.system.seasonPoster' },
|
||||||
|
{ key: 'season_banner', label: 'setting.system.seasonBanner' },
|
||||||
|
{ key: 'season_thumb', label: 'setting.system.seasonThumb' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
section: 'episode',
|
||||||
|
items: [
|
||||||
|
{ key: 'episode_nfo', label: 'setting.system.episodeNfo' },
|
||||||
|
{ key: 'episode_thumb', label: 'setting.system.episodeThumb' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
// 刮削策略设置
|
||||||
|
const ScrapingPolicies = ref<Record<string, 'skip' | 'missingOnly' | 'overwrite'>>(
|
||||||
|
Object.fromEntries(
|
||||||
|
scrapingConfig.flatMap(section =>
|
||||||
|
section.items.map(item => [item.key, 'missingOnly'])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
// 是否发送请求的总开关
|
// 是否发送请求的总开关
|
||||||
const isRequest = ref(true)
|
const isRequest = ref(true)
|
||||||
@@ -481,7 +510,13 @@ async function loadScrapingSwitchs() {
|
|||||||
try {
|
try {
|
||||||
const result: { [key: string]: any } = await api.get('system/setting/ScrapingSwitchs')
|
const result: { [key: string]: any } = await api.get('system/setting/ScrapingSwitchs')
|
||||||
if (result.success && result.data?.value) {
|
if (result.success && result.data?.value) {
|
||||||
ScrapingSwitchs.value = { ...ScrapingSwitchs.value, ...result.data.value }
|
const loadedSwitches = result.data.value
|
||||||
|
for (const key in loadedSwitches) {
|
||||||
|
if (typeof loadedSwitches[key] === 'boolean') { // 兼容旧数据
|
||||||
|
loadedSwitches[key] = loadedSwitches[key] ? 'missingOnly' : 'skip'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ScrapingPolicies.value = { ...ScrapingPolicies.value, ...loadedSwitches }
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
@@ -491,7 +526,7 @@ async function loadScrapingSwitchs() {
|
|||||||
// 保存刮削开关设置
|
// 保存刮削开关设置
|
||||||
async function saveScrapingSwitchs() {
|
async function saveScrapingSwitchs() {
|
||||||
try {
|
try {
|
||||||
const result: { [key: string]: any } = await api.post('system/setting/ScrapingSwitchs', ScrapingSwitchs.value)
|
const result: { [key: string]: any } = await api.post('system/setting/ScrapingSwitchs', ScrapingPolicies.value)
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
@@ -1120,173 +1155,64 @@ onDeactivated(() => {
|
|||||||
<VExpansionPanels>
|
<VExpansionPanels>
|
||||||
<VExpansionPanel>
|
<VExpansionPanel>
|
||||||
<VExpansionPanelTitle class="text-lg">
|
<VExpansionPanelTitle class="text-lg">
|
||||||
<template #default>
|
<VIcon icon="mdi-checkbox-multiple-outline" class="me-2" />
|
||||||
<VIcon icon="mdi-checkbox-multiple-outline" class="me-2" />
|
{{ t('setting.system.scrapingSwitchSettings') }}
|
||||||
{{ t('setting.system.scrapingSwitchSettings') }}
|
<!-- 帮助图标 -->
|
||||||
</template>
|
<VTooltip location="bottom" open-delay="200">
|
||||||
|
<template #activator="{ props: tooltipProps }">
|
||||||
|
<VBtn
|
||||||
|
v-bind="tooltipProps"
|
||||||
|
icon="mdi-help-circle"
|
||||||
|
size="small"
|
||||||
|
variant="text"
|
||||||
|
color="medium-emphasis"
|
||||||
|
class="ml-2"
|
||||||
|
@click.stop
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<div class="d-flex flex-column gap-2 py-2">
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<VIcon icon="mdi-file-remove" color="error" class="mr-2" />
|
||||||
|
<span>{{ t('setting.system.policy.skipDesc') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<VIcon icon="mdi-file-plus" color="success" class="mr-2" />
|
||||||
|
<span>{{ t('setting.system.policy.missingOnlyDesc') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-center">
|
||||||
|
<VIcon icon="mdi-file-replace" color="primary" class="mr-2" />
|
||||||
|
<span>{{ t('setting.system.policy.overwriteDesc') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</VTooltip>
|
||||||
</VExpansionPanelTitle>
|
</VExpansionPanelTitle>
|
||||||
<VExpansionPanelText>
|
<VExpansionPanelText>
|
||||||
<VRow>
|
<VRow v-for="section in scrapingConfig" :key="section.section">
|
||||||
<VCol cols="12" class="pb-2">
|
<VCol cols="12" class="pb-2">
|
||||||
<VListSubheader class="text-lg">{{ t('setting.system.movie') }}</VListSubheader>
|
<VListSubheader class="text-lg">{{ t(`setting.system.${section.section}`) }}</VListSubheader>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="6" md="3">
|
<VCol
|
||||||
<VCheckbox
|
v-for="item in section.items"
|
||||||
v-model="ScrapingSwitchs.movie_nfo"
|
:key="item.key"
|
||||||
:label="t('setting.system.movieNfo')"
|
cols="12"
|
||||||
density="compact"
|
md="4"
|
||||||
/>
|
>
|
||||||
</VCol>
|
<div class="d-flex align-center">
|
||||||
<VCol cols="6" md="3">
|
<VBtnToggle
|
||||||
<VCheckbox
|
:model-value="ScrapingPolicies[item.key]"
|
||||||
v-model="ScrapingSwitchs.movie_poster"
|
@update:model-value="ScrapingPolicies[item.key] = $event"
|
||||||
:label="t('setting.system.moviePoster')"
|
color="primary"
|
||||||
density="compact"
|
variant="tonal"
|
||||||
/>
|
rounded="lg"
|
||||||
</VCol>
|
>
|
||||||
<VCol cols="6" md="3">
|
<VBtn value="skip" color="error" icon="mdi-file-remove" />
|
||||||
<VCheckbox
|
<VBtn value="missingOnly" color="success" icon="mdi-file-plus" />
|
||||||
v-model="ScrapingSwitchs.movie_backdrop"
|
<VBtn value="overwrite" color="primary" icon="mdi-file-replace" />
|
||||||
:label="t('setting.system.movieBackdrop')"
|
</VBtnToggle>
|
||||||
density="compact"
|
<span class="ml-2">{{ t(item.label) }}</span>
|
||||||
/>
|
</div>
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.movie_logo"
|
|
||||||
:label="t('setting.system.movieLogo')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.movie_disc"
|
|
||||||
:label="t('setting.system.movieDisc')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.movie_banner"
|
|
||||||
:label="t('setting.system.movieBanner')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.movie_thumb"
|
|
||||||
:label="t('setting.system.movieThumb')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
</VRow>
|
|
||||||
|
|
||||||
<VDivider class="my-4" />
|
|
||||||
|
|
||||||
<VRow>
|
|
||||||
<VCol cols="12" class="pb-2">
|
|
||||||
<VListSubheader class="text-lg">{{ t('setting.system.tv') }}</VListSubheader>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.tv_nfo"
|
|
||||||
:label="t('setting.system.tvNfo')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.tv_poster"
|
|
||||||
:label="t('setting.system.tvPoster')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.tv_backdrop"
|
|
||||||
:label="t('setting.system.tvBackdrop')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.tv_banner"
|
|
||||||
:label="t('setting.system.tvBanner')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.tv_logo"
|
|
||||||
:label="t('setting.system.tvLogo')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.tv_thumb"
|
|
||||||
:label="t('setting.system.tvThumb')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
</VRow>
|
|
||||||
|
|
||||||
<VDivider class="my-4" />
|
|
||||||
|
|
||||||
<VRow>
|
|
||||||
<VCol cols="12" class="pb-2">
|
|
||||||
<VListSubheader class="text-lg">{{ t('setting.system.season') }}</VListSubheader>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.season_nfo"
|
|
||||||
:label="t('setting.system.seasonNfo')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.season_poster"
|
|
||||||
:label="t('setting.system.seasonPoster')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.season_banner"
|
|
||||||
:label="t('setting.system.seasonBanner')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.season_thumb"
|
|
||||||
:label="t('setting.system.seasonThumb')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
</VRow>
|
|
||||||
|
|
||||||
<VDivider class="my-4" />
|
|
||||||
|
|
||||||
<VRow>
|
|
||||||
<VCol cols="12" class="pb-2">
|
|
||||||
<VListSubheader class="text-lg">{{ t('setting.system.episode') }}</VListSubheader>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.episode_nfo"
|
|
||||||
:label="t('setting.system.episodeNfo')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="6" md="3">
|
|
||||||
<VCheckbox
|
|
||||||
v-model="ScrapingSwitchs.episode_thumb"
|
|
||||||
:label="t('setting.system.episodeThumb')"
|
|
||||||
density="compact"
|
|
||||||
/>
|
|
||||||
</VCol>
|
</VCol>
|
||||||
|
<VDivider v-if="section.section !== 'episode'" class="my-4" />
|
||||||
</VRow>
|
</VRow>
|
||||||
</VExpansionPanelText>
|
</VExpansionPanelText>
|
||||||
</VExpansionPanel>
|
</VExpansionPanel>
|
||||||
|
|||||||
Reference in New Issue
Block a user