mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 23:56:42 +08:00
feat 规则页面拆分
This commit is contained in:
@@ -132,9 +132,9 @@ const ruleTestDialog = ref(false)
|
|||||||
<VIcon icon="mdi-filter-cog-outline" />
|
<VIcon icon="mdi-filter-cog-outline" />
|
||||||
</VAvatar>
|
</VAvatar>
|
||||||
<h6 class="text-base font-weight-medium mt-2 mb-0">
|
<h6 class="text-base font-weight-medium mt-2 mb-0">
|
||||||
规则
|
优先级
|
||||||
</h6>
|
</h6>
|
||||||
<span class="text-sm">过滤规则测试</span>
|
<span class="text-sm">优先级规则测试</span>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
</VCol>
|
</VCol>
|
||||||
</VRow>
|
</VRow>
|
||||||
@@ -184,7 +184,7 @@ const ruleTestDialog = ref(false)
|
|||||||
max-width="50rem"
|
max-width="50rem"
|
||||||
scrollable
|
scrollable
|
||||||
>
|
>
|
||||||
<VCard title="过滤规则测试">
|
<VCard title="优先级测试">
|
||||||
<DialogCloseBtn @click="ruleTestDialog = false" />
|
<DialogCloseBtn @click="ruleTestDialog = false" />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<RuleTestView />
|
<RuleTestView />
|
||||||
|
|||||||
+30
-4
@@ -6,6 +6,8 @@ import AccountSettingRule from '@/views/setting/AccountSettingRule.vue'
|
|||||||
import AccountSettingSite from '@/views/setting/AccountSettingSite.vue'
|
import AccountSettingSite from '@/views/setting/AccountSettingSite.vue'
|
||||||
import AccountSettingWords from '@/views/setting/AccountSettingWords.vue'
|
import AccountSettingWords from '@/views/setting/AccountSettingWords.vue'
|
||||||
import AccountSettingAbout from '@/views/setting/AccountSettingAbout.vue'
|
import AccountSettingAbout from '@/views/setting/AccountSettingAbout.vue'
|
||||||
|
import AccountSettingSearch from '@/views/setting/AccountSettingSearch.vue'
|
||||||
|
import AccountSettingSubscribe from '@/views/setting/AccountSettingSubscribe.vue'
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
@@ -23,6 +25,16 @@ const tabs = [
|
|||||||
icon: 'mdi-web',
|
icon: 'mdi-web',
|
||||||
tab: 'site',
|
tab: 'site',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '搜索',
|
||||||
|
icon: 'mdi-magnify',
|
||||||
|
tab: 'search',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '订阅',
|
||||||
|
icon: 'mdi-rss',
|
||||||
|
tab: 'subscribe',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '规则',
|
title: '规则',
|
||||||
icon: 'mdi-filter-cog',
|
icon: 'mdi-filter-cog',
|
||||||
@@ -64,13 +76,27 @@ const tabs = [
|
|||||||
</transition>
|
</transition>
|
||||||
</VWindowItem>
|
</VWindowItem>
|
||||||
|
|
||||||
<!-- System -->
|
<!-- 用户 -->
|
||||||
<VWindowItem value="site">
|
<VWindowItem value="site">
|
||||||
<transition name="fade-slide" appear>
|
<transition name="fade-slide" appear>
|
||||||
<AccountSettingSite />
|
<AccountSettingSite />
|
||||||
</transition>
|
</transition>
|
||||||
</VWindowItem>
|
</VWindowItem>
|
||||||
|
|
||||||
|
<!-- 搜索 -->
|
||||||
|
<VWindowItem value="search">
|
||||||
|
<transition name="fade-slide" appear>
|
||||||
|
<AccountSettingSearch />
|
||||||
|
</transition>
|
||||||
|
</VWindowItem>
|
||||||
|
|
||||||
|
<!-- 订阅 -->
|
||||||
|
<VWindowItem value="subscribe">
|
||||||
|
<transition name="fade-slide" appear>
|
||||||
|
<AccountSettingSubscribe />
|
||||||
|
</transition>
|
||||||
|
</VWindowItem>
|
||||||
|
|
||||||
<!-- Notification -->
|
<!-- Notification -->
|
||||||
<VWindowItem value="filter">
|
<VWindowItem value="filter">
|
||||||
<transition name="fade-slide" appear>
|
<transition name="fade-slide" appear>
|
||||||
@@ -78,19 +104,19 @@ const tabs = [
|
|||||||
</transition>
|
</transition>
|
||||||
</VWindowItem>
|
</VWindowItem>
|
||||||
|
|
||||||
<!-- Notification -->
|
<!-- 通知 -->
|
||||||
<VWindowItem value="notification">
|
<VWindowItem value="notification">
|
||||||
<transition name="fade-slide" appear>
|
<transition name="fade-slide" appear>
|
||||||
<AccountSettingNotification />
|
<AccountSettingNotification />
|
||||||
</transition>
|
</transition>
|
||||||
</VWindowItem>
|
</VWindowItem>
|
||||||
<!-- Words -->
|
<!-- 词表 -->
|
||||||
<VWindowItem value="words">
|
<VWindowItem value="words">
|
||||||
<transition name="fade-slide" appear>
|
<transition name="fade-slide" appear>
|
||||||
<AccountSettingWords />
|
<AccountSettingWords />
|
||||||
</transition>
|
</transition>
|
||||||
</VWindowItem>
|
</VWindowItem>
|
||||||
<!-- About -->
|
<!-- 关于 -->
|
||||||
<VWindowItem value="about">
|
<VWindowItem value="about">
|
||||||
<transition name="fade-slide" appear>
|
<transition name="fade-slide" appear>
|
||||||
<AccountSettingAbout />
|
<AccountSettingAbout />
|
||||||
|
|||||||
@@ -1,15 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useToast } from 'vue-toast-notification'
|
import { useToast } from 'vue-toast-notification'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import FilterRuleCard from '@/components/cards/FilterRuleCard.vue'
|
|
||||||
|
|
||||||
// 规则卡片类型
|
|
||||||
interface FilterCard {
|
|
||||||
// 优先级
|
|
||||||
pri: string
|
|
||||||
// 已选规则
|
|
||||||
rules: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提示框
|
// 提示框
|
||||||
const $toast = useToast()
|
const $toast = useToast()
|
||||||
@@ -23,41 +14,12 @@ const TorrentPriorityItems = [
|
|||||||
{ title: '做种数优先', value: 'seeder' },
|
{ title: '做种数优先', value: 'seeder' },
|
||||||
]
|
]
|
||||||
|
|
||||||
// 规则卡片列表
|
|
||||||
const filterCards = ref<FilterCard[]>([])
|
|
||||||
|
|
||||||
// 洗版规则卡片列表
|
|
||||||
const filterCards2 = ref<FilterCard[]>([])
|
|
||||||
|
|
||||||
// 包含与排除规则
|
// 包含与排除规则
|
||||||
const defaultIncludeExcludeFilter = ref({
|
const defaultIncludeExcludeFilter = ref({
|
||||||
include: '',
|
include: '',
|
||||||
exclude: '',
|
exclude: '',
|
||||||
})
|
})
|
||||||
|
|
||||||
// 查询已设置过滤规则
|
|
||||||
async function queryCustomFilters(ruleType: string) {
|
|
||||||
try {
|
|
||||||
const result: { [key: string]: any } = await api.get(`system/setting/${ruleType}`)
|
|
||||||
if (result.success) {
|
|
||||||
// 保存的是个字符串,需要分割成数组
|
|
||||||
const groups = result.data?.value?.split('>') ?? []
|
|
||||||
|
|
||||||
// 生成规则卡片
|
|
||||||
const cards = ruleType === 'FilterRules' ? filterCards : filterCards2
|
|
||||||
cards.value = groups?.map((group: string, index: number) => {
|
|
||||||
return {
|
|
||||||
pri: (index + 1).toString(),
|
|
||||||
rules: group.split('&'),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询种子优先规则
|
// 查询种子优先规则
|
||||||
async function queryTorrentPriority() {
|
async function queryTorrentPriority() {
|
||||||
try {
|
try {
|
||||||
@@ -86,37 +48,6 @@ async function queryIncludeExcludeFilter() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存用户设置的规则
|
|
||||||
async function saveCustomFilters(ruleType: string) {
|
|
||||||
try {
|
|
||||||
// 有值才处理
|
|
||||||
let value = ''
|
|
||||||
if (filterCards.value.length !== 0) {
|
|
||||||
// 将卡片规则接装为字符串
|
|
||||||
const cards = ruleType === 'FilterRules' ? filterCards : filterCards2
|
|
||||||
value = cards.value
|
|
||||||
.filter(card => card.rules.length > 0)
|
|
||||||
.map(card => card.rules.join('&'))
|
|
||||||
.join('>')
|
|
||||||
}
|
|
||||||
// 保存
|
|
||||||
const result: { [key: string]: any } = await api.post(
|
|
||||||
`system/setting/${ruleType}`,
|
|
||||||
value,
|
|
||||||
)
|
|
||||||
|
|
||||||
const msg = ruleType === 'FilterRules' ? '过滤规则' : '洗版规则'
|
|
||||||
|
|
||||||
if (result.success)
|
|
||||||
$toast.success(`${msg}保存成功`)
|
|
||||||
else
|
|
||||||
$toast.error(`${msg}保存失败!`)
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存种子优先规则
|
// 保存种子优先规则
|
||||||
async function saveTorrentPriority() {
|
async function saveTorrentPriority() {
|
||||||
try {
|
try {
|
||||||
@@ -153,127 +84,14 @@ async function saveIncludeExcludeFilter() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新规则卡片的值
|
|
||||||
function updateFilterCardValue(pri: string, rules: string[]) {
|
|
||||||
const card = filterCards.value.find(card => card.pri === pri)
|
|
||||||
if (card)
|
|
||||||
card.rules = rules
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新洗版规则卡片的值
|
|
||||||
function updateFilterCardValue2(pri: string, rules: string[]) {
|
|
||||||
const card = filterCards2.value.find(card => card.pri === pri)
|
|
||||||
if (card)
|
|
||||||
card.rules = rules
|
|
||||||
}
|
|
||||||
|
|
||||||
// 移除卡片
|
|
||||||
function filterCardClose(ruleType: string, pri: string) {
|
|
||||||
// 将pri对应的卡片从列表中删除,并更新剩余卡片的序号
|
|
||||||
const updatedCards = (ruleType === 'FilterRules' ? filterCards.value : filterCards2.value)
|
|
||||||
.filter(card => card.pri !== pri)
|
|
||||||
.map((card, index) => {
|
|
||||||
card.pri = (index + 1).toString()
|
|
||||||
return card
|
|
||||||
})
|
|
||||||
// 更新 filterCards.value
|
|
||||||
if (ruleType === 'FilterRules')
|
|
||||||
filterCards.value = updatedCards
|
|
||||||
else
|
|
||||||
filterCards2.value = updatedCards
|
|
||||||
}
|
|
||||||
|
|
||||||
// 增加卡片
|
|
||||||
function addFilterCard(ruleType: string) {
|
|
||||||
const cards = ruleType === 'FilterRules' ? filterCards : filterCards2
|
|
||||||
// 优先级
|
|
||||||
const pri = (cards.value.length + 1).toString()
|
|
||||||
|
|
||||||
// 新卡片
|
|
||||||
const newCard: FilterCard = { pri, rules: [] }
|
|
||||||
|
|
||||||
// 添加到列表
|
|
||||||
cards.value.push(newCard)
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
queryTorrentPriority()
|
queryTorrentPriority()
|
||||||
queryCustomFilters('FilterRules')
|
|
||||||
queryCustomFilters('FilterRules2')
|
|
||||||
queryIncludeExcludeFilter()
|
queryIncludeExcludeFilter()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VRow>
|
<VRow>
|
||||||
<VCol cols="12">
|
|
||||||
<VCard title="过滤规则">
|
|
||||||
<VCardSubtitle> 设置在搜索和订阅时默认使用的过滤规则 </VCardSubtitle>
|
|
||||||
<VCardItem>
|
|
||||||
<div class="grid gap-3 grid-filterrule-card">
|
|
||||||
<FilterRuleCard
|
|
||||||
v-for="(card, index) in filterCards"
|
|
||||||
:key="index"
|
|
||||||
:pri="card.pri"
|
|
||||||
:rules="card.rules"
|
|
||||||
@changed="updateFilterCardValue"
|
|
||||||
@close="filterCardClose('FilterRules', card.pri)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</VCardItem>
|
|
||||||
<VCardItem>
|
|
||||||
<VBtn
|
|
||||||
type="submit"
|
|
||||||
class="me-2"
|
|
||||||
@click="saveCustomFilters('FilterRules')"
|
|
||||||
>
|
|
||||||
保存
|
|
||||||
</VBtn>
|
|
||||||
<VBtn
|
|
||||||
color="success"
|
|
||||||
variant="tonal"
|
|
||||||
@click="addFilterCard('FilterRules')"
|
|
||||||
>
|
|
||||||
<VIcon icon="mdi-plus" />
|
|
||||||
<span class="d-none d-sm-block">增加规则</span>
|
|
||||||
</VBtn>
|
|
||||||
</VCardItem>
|
|
||||||
</VCard>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="12">
|
|
||||||
<VCard title="洗版规则">
|
|
||||||
<VCardSubtitle> 设置在订阅洗版时使用的过滤规则,匹配优先级1时洗版完成 </VCardSubtitle>
|
|
||||||
<VCardItem>
|
|
||||||
<div class="grid gap-3 grid-filterrule-card">
|
|
||||||
<FilterRuleCard
|
|
||||||
v-for="(card, index) in filterCards2"
|
|
||||||
:key="index"
|
|
||||||
:pri="card.pri"
|
|
||||||
:rules="card.rules"
|
|
||||||
@changed="updateFilterCardValue2"
|
|
||||||
@close="filterCardClose('FilterRules2', card.pri)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</VCardItem>
|
|
||||||
<VCardItem>
|
|
||||||
<VBtn
|
|
||||||
type="submit"
|
|
||||||
class="me-2"
|
|
||||||
@click="saveCustomFilters('FilterRules2')"
|
|
||||||
>
|
|
||||||
保存
|
|
||||||
</VBtn>
|
|
||||||
<VBtn
|
|
||||||
color="success"
|
|
||||||
variant="tonal"
|
|
||||||
@click="addFilterCard('FilterRules2')"
|
|
||||||
>
|
|
||||||
<VIcon icon="mdi-plus" />
|
|
||||||
<span class="d-none d-sm-block">增加规则</span>
|
|
||||||
</VBtn>
|
|
||||||
</VCardItem>
|
|
||||||
</VCard>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VCard title="下载优先规则">
|
<VCard title="下载优先规则">
|
||||||
<VCardText>
|
<VCardText>
|
||||||
|
|||||||
@@ -0,0 +1,226 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useToast } from 'vue-toast-notification'
|
||||||
|
import api from '@/api'
|
||||||
|
import FilterRuleCard from '@/components/cards/FilterRuleCard.vue'
|
||||||
|
import type { Site } from '@/api/types'
|
||||||
|
|
||||||
|
// 规则卡片类型
|
||||||
|
interface FilterCard {
|
||||||
|
// 优先级
|
||||||
|
pri: string
|
||||||
|
// 已选规则
|
||||||
|
rules: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提示框
|
||||||
|
const $toast = useToast()
|
||||||
|
|
||||||
|
// 规则卡片列表
|
||||||
|
const filterCards = ref<FilterCard[]>([])
|
||||||
|
|
||||||
|
// 所有站点
|
||||||
|
const allSites = ref<Site[]>([])
|
||||||
|
|
||||||
|
// 选中订阅站点
|
||||||
|
const selectedSites = ref<number[]>([])
|
||||||
|
|
||||||
|
// 查询已设置优先级规则
|
||||||
|
async function queryCustomFilters() {
|
||||||
|
try {
|
||||||
|
const result: { [key: string]: any } = await api.get('system/setting/SearchFilterRules')
|
||||||
|
if (result.success) {
|
||||||
|
// 保存的是个字符串,需要分割成数组
|
||||||
|
const groups = result.data?.value?.split('>') ?? []
|
||||||
|
|
||||||
|
// 生成规则卡片
|
||||||
|
filterCards.value = groups?.map((group: string, index: number) => {
|
||||||
|
return {
|
||||||
|
pri: (index + 1).toString(),
|
||||||
|
rules: group.split('&'),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存用户设置的规则
|
||||||
|
async function saveCustomFilters() {
|
||||||
|
try {
|
||||||
|
// 有值才处理
|
||||||
|
let value = ''
|
||||||
|
if (filterCards.value.length !== 0) {
|
||||||
|
// 将卡片规则接装为字符串
|
||||||
|
value = filterCards.value
|
||||||
|
.filter(card => card.rules.length > 0)
|
||||||
|
.map(card => card.rules.join('&'))
|
||||||
|
.join('>')
|
||||||
|
}
|
||||||
|
// 保存
|
||||||
|
const result: { [key: string]: any } = await api.post(
|
||||||
|
'system/setting/SearchFilterRules',
|
||||||
|
value,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (result.success)
|
||||||
|
$toast.success('搜索优先级保存成功')
|
||||||
|
else
|
||||||
|
$toast.error('搜索优先级保存失败!')
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新规则卡片的值
|
||||||
|
function updateFilterCardValue(pri: string, rules: string[]) {
|
||||||
|
const card = filterCards.value.find(card => card.pri === pri)
|
||||||
|
if (card)
|
||||||
|
card.rules = rules
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除卡片
|
||||||
|
function filterCardClose(pri: string) {
|
||||||
|
// 将pri对应的卡片从列表中删除,并更新剩余卡片的序号
|
||||||
|
const updatedCards = filterCards.value
|
||||||
|
.filter(card => card.pri !== pri)
|
||||||
|
.map((card, index) => {
|
||||||
|
card.pri = (index + 1).toString()
|
||||||
|
return card
|
||||||
|
})
|
||||||
|
// 更新 filterCards.value
|
||||||
|
filterCards.value = updatedCards
|
||||||
|
}
|
||||||
|
|
||||||
|
// 增加卡片
|
||||||
|
function addFilterCard() {
|
||||||
|
// 优先级
|
||||||
|
const pri = (filterCards.value.length + 1).toString()
|
||||||
|
|
||||||
|
// 新卡片
|
||||||
|
const newCard: FilterCard = { pri, rules: [] }
|
||||||
|
|
||||||
|
// 添加到列表
|
||||||
|
filterCards.value.push(newCard)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询所有站点
|
||||||
|
async function querySites() {
|
||||||
|
try {
|
||||||
|
const data: Site[] = await api.get('site')
|
||||||
|
|
||||||
|
// 过滤站点,只有启用的站点才显示
|
||||||
|
allSites.value = data.filter(item => item.is_active)
|
||||||
|
querySelectedSites()
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询用户选中的站点
|
||||||
|
async function querySelectedSites() {
|
||||||
|
try {
|
||||||
|
const result: { [key: string]: any } = await api.get('system/setting/IndexerSites')
|
||||||
|
|
||||||
|
selectedSites.value = result.data?.value ?? []
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存用户选中的站点
|
||||||
|
async function saveSelectedSites() {
|
||||||
|
try {
|
||||||
|
// 用户名密码
|
||||||
|
const result: { [key: string]: any } = await api.post('system/setting/IndexerSites', selectedSites.value)
|
||||||
|
|
||||||
|
if (result.success)
|
||||||
|
$toast.success('搜索站点保存成功')
|
||||||
|
else
|
||||||
|
$toast.error('搜索站点保存失败!')
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
queryCustomFilters()
|
||||||
|
querySites()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<VRow>
|
||||||
|
<VCol cols="12">
|
||||||
|
<VCard title="搜索站点">
|
||||||
|
<VCardSubtitle> 只有选中的站点才会在搜索中使用。</VCardSubtitle>
|
||||||
|
|
||||||
|
<VCardItem>
|
||||||
|
<VChipGroup v-model="selectedSites" column multiple>
|
||||||
|
<VChip
|
||||||
|
v-for="site in allSites"
|
||||||
|
:key="site.id"
|
||||||
|
:color="selectedSites.includes(site.id) ? 'primary' : ''"
|
||||||
|
filter
|
||||||
|
variant="outlined"
|
||||||
|
:value="site.id"
|
||||||
|
>
|
||||||
|
{{ site.name }}
|
||||||
|
</VChip>
|
||||||
|
</VChipGroup>
|
||||||
|
</VCardItem>
|
||||||
|
|
||||||
|
<VCardItem>
|
||||||
|
<VBtn type="submit" @click="saveSelectedSites">
|
||||||
|
保存
|
||||||
|
</VBtn>
|
||||||
|
</VCardItem>
|
||||||
|
</VCard>
|
||||||
|
</VCol>
|
||||||
|
<VCol cols="12">
|
||||||
|
<VCard title="搜索优先级">
|
||||||
|
<VCardSubtitle> 设置在搜索时默认使用的优先级排序,未在优先级中的资源将不在搜索结果中显示。 </VCardSubtitle>
|
||||||
|
<VCardItem>
|
||||||
|
<div class="grid gap-3 grid-filterrule-card">
|
||||||
|
<FilterRuleCard
|
||||||
|
v-for="(card, index) in filterCards"
|
||||||
|
:key="index"
|
||||||
|
:pri="card.pri"
|
||||||
|
:rules="card.rules"
|
||||||
|
@changed="updateFilterCardValue"
|
||||||
|
@close="filterCardClose(card.pri)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VCardItem>
|
||||||
|
<VCardItem>
|
||||||
|
<VBtn
|
||||||
|
type="submit"
|
||||||
|
class="me-2"
|
||||||
|
@click="saveCustomFilters()"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</VBtn>
|
||||||
|
<VBtn
|
||||||
|
color="success"
|
||||||
|
variant="tonal"
|
||||||
|
@click="addFilterCard()"
|
||||||
|
>
|
||||||
|
<VIcon icon="mdi-plus" />
|
||||||
|
</VBtn>
|
||||||
|
</VCardItem>
|
||||||
|
</VCard>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.grid-filterrule-card {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
|
||||||
|
padding-block-end: 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,19 +1,10 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useToast } from 'vue-toast-notification'
|
import { useToast } from 'vue-toast-notification'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import type { Site } from '@/api/types'
|
|
||||||
|
|
||||||
// 提示框
|
// 提示框
|
||||||
const $toast = useToast()
|
const $toast = useToast()
|
||||||
|
|
||||||
// 选中搜索站点
|
|
||||||
const selectedSites = ref<number[]>([])
|
|
||||||
// 选中订阅站点
|
|
||||||
const selectedRssSites = ref<number[]>([])
|
|
||||||
|
|
||||||
// 所有站点
|
|
||||||
const allSites = ref<Site[]>([])
|
|
||||||
|
|
||||||
// 站点重置
|
// 站点重置
|
||||||
const isConfirmResetSites = ref(false)
|
const isConfirmResetSites = ref(false)
|
||||||
|
|
||||||
@@ -23,76 +14,6 @@ const resetSitesText = ref('重置站点数据')
|
|||||||
// 站点重置按钮可用状态
|
// 站点重置按钮可用状态
|
||||||
const resetSitesDisabled = ref(false)
|
const resetSitesDisabled = ref(false)
|
||||||
|
|
||||||
// 查询所有站点
|
|
||||||
async function querySites() {
|
|
||||||
try {
|
|
||||||
const data: Site[] = await api.get('site')
|
|
||||||
|
|
||||||
// 过滤站点,只有启用的站点才显示
|
|
||||||
allSites.value = data.filter(item => item.is_active)
|
|
||||||
querySelectedSites()
|
|
||||||
querySelectedRssSites()
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询用户选中的站点
|
|
||||||
async function querySelectedSites() {
|
|
||||||
try {
|
|
||||||
const result: { [key: string]: any } = await api.get('system/setting/IndexerSites')
|
|
||||||
|
|
||||||
selectedSites.value = result.data?.value ?? []
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存用户选中的站点
|
|
||||||
async function saveSelectedSites() {
|
|
||||||
try {
|
|
||||||
// 用户名密码
|
|
||||||
const result: { [key: string]: any } = await api.post('system/setting/IndexerSites', selectedSites.value)
|
|
||||||
|
|
||||||
if (result.success)
|
|
||||||
$toast.success('搜索站点保存成功')
|
|
||||||
else
|
|
||||||
$toast.error('搜索站点保存失败!')
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询用户选中的订阅站点
|
|
||||||
async function querySelectedRssSites() {
|
|
||||||
try {
|
|
||||||
const result: { [key: string]: any } = await api.get('system/setting/RssSites')
|
|
||||||
|
|
||||||
selectedRssSites.value = result.data?.value ?? []
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存用户选中的订阅站点
|
|
||||||
async function saveSelectedRssSites() {
|
|
||||||
try {
|
|
||||||
const result: { [key: string]: any } = await api.post('system/setting/RssSites', selectedRssSites.value)
|
|
||||||
|
|
||||||
if (result.success)
|
|
||||||
$toast.success('订阅站点保存成功')
|
|
||||||
else
|
|
||||||
$toast.error('订阅站点保存失败!')
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重置站点
|
// 重置站点
|
||||||
async function resetSites() {
|
async function resetSites() {
|
||||||
try {
|
try {
|
||||||
@@ -100,13 +21,12 @@ async function resetSites() {
|
|||||||
resetSitesText.value = '正在重置...'
|
resetSitesText.value = '正在重置...'
|
||||||
|
|
||||||
const result: { [key: string]: any } = await api.get('site/reset')
|
const result: { [key: string]: any } = await api.get('site/reset')
|
||||||
if (result.success) {
|
if (result.success)
|
||||||
$toast.success('站点重置成功,请等待CookieCloud同步完成!')
|
$toast.success('站点重置成功,请等待CookieCloud同步完成!')
|
||||||
querySites()
|
|
||||||
}
|
else
|
||||||
else {
|
|
||||||
$toast.error('站点重置失败!')
|
$toast.error('站点重置失败!')
|
||||||
}
|
|
||||||
resetSitesDisabled.value = false
|
resetSitesDisabled.value = false
|
||||||
resetSitesText.value = '重置站点数据'
|
resetSitesText.value = '重置站点数据'
|
||||||
}
|
}
|
||||||
@@ -114,66 +34,10 @@ async function resetSites() {
|
|||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
querySites()
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VRow>
|
<VRow>
|
||||||
<VCol cols="12">
|
|
||||||
<VCard title="搜索站点">
|
|
||||||
<VCardSubtitle> 只有选中的站点才会在搜索中使用</VCardSubtitle>
|
|
||||||
|
|
||||||
<VCardItem>
|
|
||||||
<VChipGroup v-model="selectedSites" column multiple>
|
|
||||||
<VChip
|
|
||||||
v-for="site in allSites"
|
|
||||||
:key="site.id"
|
|
||||||
:color="selectedSites.includes(site.id) ? 'primary' : ''"
|
|
||||||
filter
|
|
||||||
variant="outlined"
|
|
||||||
:value="site.id"
|
|
||||||
>
|
|
||||||
{{ site.name }}
|
|
||||||
</VChip>
|
|
||||||
</VChipGroup>
|
|
||||||
</VCardItem>
|
|
||||||
|
|
||||||
<VCardItem>
|
|
||||||
<VBtn type="submit" @click="saveSelectedSites">
|
|
||||||
保存
|
|
||||||
</VBtn>
|
|
||||||
</VCardItem>
|
|
||||||
</VCard>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="12">
|
|
||||||
<VCard title="订阅站点">
|
|
||||||
<VCardSubtitle> 只有选中的站点才会在订阅中使用</VCardSubtitle>
|
|
||||||
|
|
||||||
<VCardItem>
|
|
||||||
<VChipGroup v-model="selectedRssSites" column multiple>
|
|
||||||
<VChip
|
|
||||||
v-for="site in allSites"
|
|
||||||
:key="site.id"
|
|
||||||
:color="selectedRssSites.includes(site.id) ? 'primary' : ''"
|
|
||||||
filter
|
|
||||||
variant="outlined"
|
|
||||||
:value="site.id"
|
|
||||||
>
|
|
||||||
{{ site.name }}
|
|
||||||
</VChip>
|
|
||||||
</VChipGroup>
|
|
||||||
</VCardItem>
|
|
||||||
|
|
||||||
<VCardItem>
|
|
||||||
<VBtn type="submit" @click="saveSelectedRssSites">
|
|
||||||
保存
|
|
||||||
</VBtn>
|
|
||||||
</VCardItem>
|
|
||||||
</VCard>
|
|
||||||
</VCol>
|
|
||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VCard title="站点重置">
|
<VCard title="站点重置">
|
||||||
<VCardText>
|
<VCardText>
|
||||||
|
|||||||
@@ -0,0 +1,277 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useToast } from 'vue-toast-notification'
|
||||||
|
import api from '@/api'
|
||||||
|
import FilterRuleCard from '@/components/cards/FilterRuleCard.vue'
|
||||||
|
import type { Site } from '@/api/types'
|
||||||
|
|
||||||
|
// 规则卡片类型
|
||||||
|
interface FilterCard {
|
||||||
|
// 优先级
|
||||||
|
pri: string
|
||||||
|
// 已选规则
|
||||||
|
rules: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提示框
|
||||||
|
const $toast = useToast()
|
||||||
|
|
||||||
|
// 订阅规则卡片列表
|
||||||
|
const subscribeFilterCards = ref<FilterCard[]>([])
|
||||||
|
|
||||||
|
// 洗版规则卡片列表
|
||||||
|
const bestVersionFilterCards = ref<FilterCard[]>([])
|
||||||
|
|
||||||
|
// 所有站点
|
||||||
|
const allSites = ref<Site[]>([])
|
||||||
|
|
||||||
|
// 选中订阅站点
|
||||||
|
const selectedRssSites = ref<number[]>([])
|
||||||
|
|
||||||
|
// 查询用户选中的订阅站点
|
||||||
|
async function querySelectedRssSites() {
|
||||||
|
try {
|
||||||
|
const result: { [key: string]: any } = await api.get('system/setting/RssSites')
|
||||||
|
|
||||||
|
selectedRssSites.value = result.data?.value ?? []
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存用户选中的订阅站点
|
||||||
|
async function saveSelectedRssSites() {
|
||||||
|
try {
|
||||||
|
const result: { [key: string]: any } = await api.post('system/setting/RssSites', selectedRssSites.value)
|
||||||
|
|
||||||
|
if (result.success)
|
||||||
|
$toast.success('订阅站点保存成功')
|
||||||
|
else
|
||||||
|
$toast.error('订阅站点保存失败!')
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询所有站点
|
||||||
|
async function querySites() {
|
||||||
|
try {
|
||||||
|
const data: Site[] = await api.get('site')
|
||||||
|
|
||||||
|
// 过滤站点,只有启用的站点才显示
|
||||||
|
allSites.value = data.filter(item => item.is_active)
|
||||||
|
querySelectedRssSites()
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询已设置优先级规则
|
||||||
|
async function queryCustomFilters(ruleType: string) {
|
||||||
|
try {
|
||||||
|
const result: { [key: string]: any } = await api.get(`system/setting/${ruleType}`)
|
||||||
|
if (result.success) {
|
||||||
|
// 保存的是个字符串,需要分割成数组
|
||||||
|
const groups = result.data?.value?.split('>') ?? []
|
||||||
|
|
||||||
|
// 生成规则卡片
|
||||||
|
const cards = ruleType === 'SubscribeFilterRules' ? subscribeFilterCards : bestVersionFilterCards
|
||||||
|
cards.value = groups?.map((group: string, index: number) => {
|
||||||
|
return {
|
||||||
|
pri: (index + 1).toString(),
|
||||||
|
rules: group.split('&'),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存用户设置的规则
|
||||||
|
async function saveCustomFilters(ruleType: string) {
|
||||||
|
try {
|
||||||
|
// 有值才处理
|
||||||
|
let value = ''
|
||||||
|
const cards = ruleType === 'SubscribeFilterRules' ? subscribeFilterCards : bestVersionFilterCards
|
||||||
|
if (cards.value.length !== 0) {
|
||||||
|
// 将卡片规则接装为字符串
|
||||||
|
value = cards.value
|
||||||
|
.filter(card => card.rules.length > 0)
|
||||||
|
.map(card => card.rules.join('&'))
|
||||||
|
.join('>')
|
||||||
|
}
|
||||||
|
// 保存
|
||||||
|
const result: { [key: string]: any } = await api.post(
|
||||||
|
`system/setting/${ruleType}`,
|
||||||
|
value,
|
||||||
|
)
|
||||||
|
|
||||||
|
const msg = ruleType === 'SubscribeFilterRules' ? '订阅优先级' : '洗版优先级'
|
||||||
|
|
||||||
|
if (result.success)
|
||||||
|
$toast.success(`${msg}保存成功`)
|
||||||
|
else
|
||||||
|
$toast.error(`${msg}保存失败!`)
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新规则卡片的值
|
||||||
|
function updateFilterCardValue(pri: string, rules: string[]) {
|
||||||
|
const card = subscribeFilterCards.value.find(card => card.pri === pri)
|
||||||
|
if (card)
|
||||||
|
card.rules = rules
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新洗版规则卡片的值
|
||||||
|
function updateFilterCardValue2(pri: string, rules: string[]) {
|
||||||
|
const card = bestVersionFilterCards.value.find(card => card.pri === pri)
|
||||||
|
if (card)
|
||||||
|
card.rules = rules
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除卡片
|
||||||
|
function filterCardClose(ruleType: string, pri: string) {
|
||||||
|
// 将pri对应的卡片从列表中删除,并更新剩余卡片的序号
|
||||||
|
const updatedCards = (ruleType === 'SubscribeFilterRules' ? subscribeFilterCards.value : bestVersionFilterCards.value)
|
||||||
|
.filter(card => card.pri !== pri)
|
||||||
|
.map((card, index) => {
|
||||||
|
card.pri = (index + 1).toString()
|
||||||
|
return card
|
||||||
|
})
|
||||||
|
// 更新 subscribeFilterCards.value
|
||||||
|
if (ruleType === 'SubscribeFilterRules')
|
||||||
|
subscribeFilterCards.value = updatedCards
|
||||||
|
else
|
||||||
|
bestVersionFilterCards.value = updatedCards
|
||||||
|
}
|
||||||
|
|
||||||
|
// 增加卡片
|
||||||
|
function addFilterCard(ruleType: string) {
|
||||||
|
const cards = ruleType === 'SubscribeFilterRules' ? subscribeFilterCards : bestVersionFilterCards
|
||||||
|
// 优先级
|
||||||
|
const pri = (cards.value.length + 1).toString()
|
||||||
|
|
||||||
|
// 新卡片
|
||||||
|
const newCard: FilterCard = { pri, rules: [] }
|
||||||
|
|
||||||
|
// 添加到列表
|
||||||
|
cards.value.push(newCard)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
querySites()
|
||||||
|
queryCustomFilters('SubscribeFilterRules')
|
||||||
|
queryCustomFilters('BestVersionFilterRules')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<VRow>
|
||||||
|
<VCol cols="12">
|
||||||
|
<VCard title="订阅站点">
|
||||||
|
<VCardSubtitle> 只有选中的站点才会在订阅中使用。</VCardSubtitle>
|
||||||
|
|
||||||
|
<VCardItem>
|
||||||
|
<VChipGroup v-model="selectedRssSites" column multiple>
|
||||||
|
<VChip
|
||||||
|
v-for="site in allSites"
|
||||||
|
:key="site.id"
|
||||||
|
:color="selectedRssSites.includes(site.id) ? 'primary' : ''"
|
||||||
|
filter
|
||||||
|
variant="outlined"
|
||||||
|
:value="site.id"
|
||||||
|
>
|
||||||
|
{{ site.name }}
|
||||||
|
</VChip>
|
||||||
|
</VChipGroup>
|
||||||
|
</VCardItem>
|
||||||
|
|
||||||
|
<VCardItem>
|
||||||
|
<VBtn type="submit" @click="saveSelectedRssSites">
|
||||||
|
保存
|
||||||
|
</VBtn>
|
||||||
|
</VCardItem>
|
||||||
|
</VCard>
|
||||||
|
</VCol>
|
||||||
|
<VCol cols="12">
|
||||||
|
<VCard title="订阅优先级">
|
||||||
|
<VCardSubtitle> 设置在正常订阅时默认使用的优先级,未在优先级中的资源将不会自动下载。 </VCardSubtitle>
|
||||||
|
<VCardItem>
|
||||||
|
<div class="grid gap-3 grid-filterrule-card">
|
||||||
|
<FilterRuleCard
|
||||||
|
v-for="(card, index) in subscribeFilterCards"
|
||||||
|
:key="index"
|
||||||
|
:pri="card.pri"
|
||||||
|
:rules="card.rules"
|
||||||
|
@changed="updateFilterCardValue"
|
||||||
|
@close="filterCardClose('SubscribeFilterRules', card.pri)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VCardItem>
|
||||||
|
<VCardItem>
|
||||||
|
<VBtn
|
||||||
|
type="submit"
|
||||||
|
class="me-2"
|
||||||
|
@click="saveCustomFilters('SubscribeFilterRules')"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</VBtn>
|
||||||
|
<VBtn
|
||||||
|
color="success"
|
||||||
|
variant="tonal"
|
||||||
|
@click="addFilterCard('SubscribeFilterRules')"
|
||||||
|
>
|
||||||
|
<VIcon icon="mdi-plus" />
|
||||||
|
</VBtn>
|
||||||
|
</VCardItem>
|
||||||
|
</VCard>
|
||||||
|
</VCol>
|
||||||
|
<VCol cols="12">
|
||||||
|
<VCard title="洗版优先级">
|
||||||
|
<VCardSubtitle> 设置在订阅洗版时使用的优先级,匹配优先级1时洗版完成。 </VCardSubtitle>
|
||||||
|
<VCardItem>
|
||||||
|
<div class="grid gap-3 grid-filterrule-card">
|
||||||
|
<FilterRuleCard
|
||||||
|
v-for="(card, index) in bestVersionFilterCards"
|
||||||
|
:key="index"
|
||||||
|
:pri="card.pri"
|
||||||
|
:rules="card.rules"
|
||||||
|
@changed="updateFilterCardValue2"
|
||||||
|
@close="filterCardClose('BestVersionFilterRules', card.pri)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</VCardItem>
|
||||||
|
<VCardItem>
|
||||||
|
<VBtn
|
||||||
|
type="submit"
|
||||||
|
class="me-2"
|
||||||
|
@click="saveCustomFilters('BestVersionFilterRules')"
|
||||||
|
>
|
||||||
|
保存
|
||||||
|
</VBtn>
|
||||||
|
<VBtn
|
||||||
|
color="success"
|
||||||
|
variant="tonal"
|
||||||
|
@click="addFilterCard('BestVersionFilterRules')"
|
||||||
|
>
|
||||||
|
<VIcon icon="mdi-plus" />
|
||||||
|
</VBtn>
|
||||||
|
</VCardItem>
|
||||||
|
</VCard>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.grid-filterrule-card {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
|
||||||
|
padding-block-end: 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -69,11 +69,14 @@ async function ruleTest() {
|
|||||||
v-model="ruleTestForm.ruletype"
|
v-model="ruleTestForm.ruletype"
|
||||||
label="规则类型"
|
label="规则类型"
|
||||||
:items="[{
|
:items="[{
|
||||||
title: '默认规则',
|
title: '订阅优先级',
|
||||||
value: '1',
|
value: '1',
|
||||||
}, {
|
}, {
|
||||||
title: '洗版规则',
|
title: '洗版优先级',
|
||||||
value: '2',
|
value: '2',
|
||||||
|
}, {
|
||||||
|
title: '搜索优先级',
|
||||||
|
value: '3',
|
||||||
}]"
|
}]"
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
|
|||||||
Reference in New Issue
Block a user