支持更多订阅自定义属性

This commit is contained in:
jxxghp
2024-10-09 15:20:25 +08:00
parent 5577e4cf62
commit b639369846
5 changed files with 218 additions and 147 deletions
+2 -4
View File
@@ -114,10 +114,8 @@ function changeTheme(theme: string) {
currentThemeName.value = nextTheme currentThemeName.value = nextTheme
// 保存主题到服务端 // 保存主题到服务端
try { try {
api.post('/user/config/theme', nextTheme, { api.post('/user/config/Layout', {
headers: { theme: nextTheme
'Content-Type': 'text/plain',
},
}) })
} catch (e) { } catch (e) {
console.error('保存主题到服务端失败') console.error('保存主题到服务端失败')
+6
View File
@@ -65,6 +65,12 @@ export interface Subscribe {
show_edit_dialog: boolean show_edit_dialog: boolean
// 编辑框打开状态 // 编辑框打开状态
page_open?: boolean page_open?: boolean
// 自定义识别词
custom_words?: string
// 自定义媒体类别
media_category?: string
// 过滤规则组
filter_groups?: string[]
} }
// 历史记录 // 历史记录
+1 -2
View File
@@ -3,8 +3,7 @@ import { useToast } from 'vue-toast-notification'
import { useConfirm } from 'vuetify-use-dialog' import { useConfirm } from 'vuetify-use-dialog'
import SubscribeEditDialog from '../dialog/SubscribeEditDialog.vue' import SubscribeEditDialog from '../dialog/SubscribeEditDialog.vue'
import SubscribeFilesDialog from '../dialog/SubscribeFilesDialog.vue' import SubscribeFilesDialog from '../dialog/SubscribeFilesDialog.vue'
import { formatDateDifference } from '@/@core/utils/formatters' import { formatDateDifference, formatSeason } from '@/@core/utils/formatters'
import { formatSeason } from '@/@core/utils/formatters'
import api from '@/api' import api from '@/api'
import type { Subscribe } from '@/api/types' import type { Subscribe } from '@/api/types'
import router from '@/router' import router from '@/router'
+207 -139
View File
@@ -2,9 +2,10 @@
import { useToast } from 'vue-toast-notification' import { useToast } from 'vue-toast-notification'
import { numberValidator } from '@/@validators' import { numberValidator } from '@/@validators'
import api from '@/api' import api from '@/api'
import type { Site, Subscribe, TransferDirectoryConf } from '@/api/types' import type { FilterRuleGroup, Site, Subscribe, TransferDirectoryConf } from '@/api/types'
import { useDisplay } from 'vuetify' import { useDisplay } from 'vuetify'
import { useConfirm } from 'vuetify-use-dialog' import { useConfirm } from 'vuetify-use-dialog'
import { VTextarea, VTextField } from 'vuetify/lib/components/index.mjs'
// 显示器宽度 // 显示器宽度
const display = useDisplay() const display = useDisplay()
@@ -22,6 +23,8 @@ const props = defineProps({
// 定义触发的自定义事件 // 定义触发的自定义事件
const emit = defineEmits(['remove', 'save', 'close']) const emit = defineEmits(['remove', 'save', 'close'])
const activeTab = ref('basic')
// 站点数据列表 // 站点数据列表
const siteList = ref<Site[]>([]) const siteList = ref<Site[]>([])
@@ -31,29 +34,22 @@ const downloadDirectories = ref<TransferDirectoryConf[]>([])
// 站点选择下载框 // 站点选择下载框
const selectSitesOptions = ref<{ [key: number]: string }[]>([]) const selectSitesOptions = ref<{ [key: number]: string }[]>([])
// 所有规则组列表
const filterRuleGroups = ref<FilterRuleGroup[]>([])
// 订阅编辑表单 // 订阅编辑表单
const subscribeForm = ref<Subscribe>({ const subscribeForm = ref<Subscribe>({
id: props.subid ?? 0, id: props.subid ?? 0,
keyword: '',
quality: '',
resolution: '',
effect: '',
include: '',
exclude: '',
total_episode: 0,
start_episode: 0,
best_version: 0,
search_imdbid: 0,
sites: [],
type: '',
name: '', name: '',
year: '', year: '',
type: '',
tmdbid: 0, tmdbid: 0,
state: '', state: '',
last_update: '', last_update: '',
username: '', username: '',
sites: [],
best_version: undefined,
current_priority: 0, current_priority: 0,
save_path: undefined,
date: '', date: '',
show_edit_dialog: false, show_edit_dialog: false,
}) })
@@ -61,6 +57,24 @@ const subscribeForm = ref<Subscribe>({
// 提示框 // 提示框
const $toast = useToast() const $toast = useToast()
// 加载规则组
async function queryFilterRuleGroups() {
try {
const result: { [key: string]: any } = await api.get('system/setting/UserFilterRuleGroups')
filterRuleGroups.value = result.data?.value ?? []
} catch (error) {
console.log(error)
}
}
// 过滤规则组选择项
const filterRuleGroupOptions = computed(() => {
return filterRuleGroups.value.map(item => ({
title: item.name,
value: item.name,
}))
})
// 调用API修改订阅 // 调用API修改订阅
async function updateSubscribeInfo() { async function updateSubscribeInfo() {
try { try {
@@ -274,6 +288,7 @@ const effectOptions = ref([
]) ])
onMounted(() => { onMounted(() => {
queryFilterRuleGroups()
loadDownloadDirectories() loadDownloadDirectories()
getSiteList() getSiteList()
if (props.subid) getSubscribeInfo() if (props.subid) getSubscribeInfo()
@@ -291,134 +306,187 @@ onMounted(() => {
}`" }`"
class="rounded-t" class="rounded-t"
> >
<VDivider />
<VCardText> <VCardText>
<DialogCloseBtn @click="emit('close')" /> <DialogCloseBtn @click="emit('close')" />
<VForm @submit.prevent="() => {}"> <VForm @submit.prevent="() => {}">
<VRow> <VTabs v-model="activeTab" show-arrows>
<VCol cols="12" md="8"> <VTab value="basic">
<VTextField <div>基础</div>
v-if="!props.default" </VTab>
v-model="subscribeForm.keyword" <VTab value="advance">
label="搜索关键词" <div>进阶</div>
hint="指定搜索站点时使用的关键词" </VTab>
persistent-hint </VTabs>
/> <VWindow v-model="activeTab" class="mt-5 disable-tab-transition" :touch="false">
</VCol> <VWindowItem value="basic">
<VCol v-if="subscribeForm.type === '电视剧'" cols="12" md="2"> <div>
<VTextField <VRow>
v-model="subscribeForm.total_episode" <VCol cols="12" md="6">
label="总集数" <VTextField
:rules="[numberValidator]" v-if="!props.default"
hint="剧集总集数" v-model="subscribeForm.keyword"
persistent-hint label="搜索关键词"
/> hint="指定搜索站点时使用的关键词"
</VCol> persistent-hint
<VCol v-if="subscribeForm.type === '电视剧'" cols="12" md="2"> />
<VTextField </VCol>
v-model="subscribeForm.start_episode" <VCol v-if="subscribeForm.type === '电视剧'" cols="12" md="3">
label="开始集数" <VTextField
:rules="[numberValidator]" v-model="subscribeForm.total_episode"
hint="开始订阅集数" label="集数"
persistent-hint :rules="[numberValidator]"
/> hint="剧集总集数"
</VCol> persistent-hint
</VRow> />
<VRow> </VCol>
<VCol cols="12" md="4"> <VCol v-if="subscribeForm.type === '电视剧'" cols="12" md="3">
<VSelect <VTextField
v-model="subscribeForm.quality" v-model="subscribeForm.start_episode"
label="质量" label="开始集数"
:items="qualityOptions" :rules="[numberValidator]"
hint="订阅资源质量" hint="开始订阅集数"
persistent-hint persistent-hint
/> />
</VCol> </VCol>
<VCol cols="12" md="4"> </VRow>
<VSelect <VRow>
v-model="subscribeForm.resolution" <VCol cols="12" md="6">
label="分辨率" <VSelect
:items="resolutionOptions" v-model="subscribeForm.filter_groups"
hint="订阅资源分辨率" :items="filterRuleGroupOptions"
persistent-hint chips
/> multiple
</VCol> label="优先级规则组"
<VCol cols="12" md="4"> hint="按选定的过滤规则组对订阅进行过滤"
<VSelect persistent-hint
v-model="subscribeForm.effect" />
label="特效" </VCol>
:items="effectOptions" <VCol cols="12" md="6">
hint="订阅资源特效" <VSelect
persistent-hint v-model="subscribeForm.sites"
/> :items="selectSitesOptions"
</VCol> chips
</VRow> label="订阅站点"
<VRow> multiple
<VCol cols="12" md="4"> hint="订阅的站点范围,不选使用系统设置"
<VTextField persistent-hint
v-model="subscribeForm.include" />
label="包含(关键字、正则式)" </VCol>
hint="包含规则,支持正则表达式" </VRow>
persistent-hint <VRow>
/> <VCol cols="12" md="6">
</VCol> <VTextField
<VCol cols="12" md="4"> v-model="subscribeForm.media_category"
<VTextField label="自定义类别"
v-model="subscribeForm.exclude" hint="指定类别名称,留空自动识别"
label="排除(关键字、正则式)" persistent-hint
hint="排除规则,支持正则表达式" />
persistent-hint </VCol>
/> <VCol cols="12" md="6">
</VCol> <VCombobox
<VCol cols="12" md="4"> v-model="subscribeForm.save_path"
<VSelect :items="targetDirectories"
v-model="subscribeForm.sites" label="自定义保存路径"
:items="selectSitesOptions" hint="指定该订阅的下载保存路径,留空自动使用设定的下载目录"
chips persistent-hint
label="订阅站点" />
multiple </VCol>
hint="订阅的站点范围,不选使用系统设置" </VRow>
persistent-hint <VRow>
/> <VCol cols="12" md="4">
</VCol> <VSwitch
</VRow> v-model="subscribeForm.best_version"
<VRow> label="洗版"
<VCol cols="12"> hint="根据洗版优先级进行洗版订阅"
<VCombobox persistent-hint
v-model="subscribeForm.save_path" />
:items="targetDirectories" </VCol>
label="保存路径" <VCol cols="12" md="4">
hint="指定该订阅的下载保存路径,留空自动使用设定的下载目录" <VSwitch
persistent-hint v-model="subscribeForm.search_imdbid"
/> label="使用 ImdbID 搜索"
</VCol> hint="开使用 ImdbID 精确搜索资源"
</VRow> persistent-hint
<VRow> />
<VCol cols="12" md="4"> </VCol>
<VSwitch <VCol v-if="props.default" cols="12" md="4">
v-model="subscribeForm.best_version" <VSwitch
label="洗版" v-model="subscribeForm.show_edit_dialog"
hint="根据洗版优先级进行洗版订阅" label="订阅时编辑更多规则"
persistent-hint hint="添加订阅时显示此编辑订阅对话框"
/> persistent-hint
</VCol> />
<VCol cols="12" md="4"> </VCol>
<VSwitch </VRow>
v-model="subscribeForm.search_imdbid" </div>
label="使用 ImdbID 搜索" </VWindowItem>
hint="开使用 ImdbID 精确搜索资源" <VWindowItem value="advance">
persistent-hint <div>
/> <VRow>
</VCol> <VCol cols="12" md="4">
<VCol v-if="props.default" cols="12" md="4"> <VSelect
<VSwitch v-model="subscribeForm.quality"
v-model="subscribeForm.show_edit_dialog" label="质量"
label="订阅时编辑更多规则" :items="qualityOptions"
hint="添加订阅时显示此编辑订阅对话框" hint="订阅资源质量"
persistent-hint persistent-hint
/> />
</VCol> </VCol>
</VRow> <VCol cols="12" md="4">
<VSelect
v-model="subscribeForm.resolution"
label="分辨率"
:items="resolutionOptions"
hint="订阅资源分辨率"
persistent-hint
/>
</VCol>
<VCol cols="12" md="4">
<VSelect
v-model="subscribeForm.effect"
label="特效"
:items="effectOptions"
hint="订阅资源特效"
persistent-hint
/>
</VCol>
</VRow>
<VRow>
<VCol cols="12" md="6">
<VTextField
v-model="subscribeForm.include"
label="包含(关键字、正则式)"
hint="包含规则,支持正则表达式"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="subscribeForm.exclude"
label="排除(关键字、正则式)"
hint="排除规则,支持正则表达式"
persistent-hint
/>
</VCol>
</VRow>
<VRow>
<VCol cols="12">
<VTextarea
v-model="subscribeForm.custom_words"
label="自定义识别词"
hint="只对该订阅使用的识别词"
persistent-hint
placeholder="屏蔽词
被替换词 => 替换词
前定位词 <> 后定位词 >> 集偏移量(EP
被替换词 => 替换词 && 前定位词 <> 后定位词 >> 集偏移量(EP
其中替换词支持格式:{[tmdbid/doubanid=xxx;type=movie/tv;s=xxx;e=xxx]} 直接指定TMDBID/豆瓣ID识别,其中s、e为季数和集数(可选)"
/>
</VCol>
</VRow>
</div>
</VWindowItem>
</VWindow>
</VForm> </VForm>
</VCardText> </VCardText>
<VCardActions class="pt-3"> <VCardActions class="pt-3">
+2 -2
View File
@@ -92,9 +92,9 @@ const fetchOTP = debounce(async () => {
// 获取用户主题配置 // 获取用户主题配置
async function fetchThemeConfig() { async function fetchThemeConfig() {
const response = await api.get('/user/config/theme') const response = await api.get('/user/config/Layout')
if (response && response.data && response.data.value) { if (response && response.data && response.data.value) {
return response.data.value return response.data.value?.theme
} }
return null return null
} }