From 0a5b553bb84dc58a7f7be83b19e6dd0fa2a56856 Mon Sep 17 00:00:00 2001
From: Aqr-K <95741669+Aqr-K@users.noreply.github.com>
Date: Thu, 24 Oct 2024 17:16:47 +0800
Subject: [PATCH 01/21] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20network=20?=
=?UTF-8?q?=E6=A0=87=E7=AD=BE=E9=A1=B5=EF=BC=8C=E8=B0=83=E6=95=B4=E6=A0=87?=
=?UTF-8?q?=E7=AD=BE=E5=AF=B9=E9=BD=90=E6=96=B9=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/pages/setting.vue | 12 +-
src/router/menu.ts | 6 +
src/views/setting/AccountSettingNetwork.vue | 262 ++++++++++++++++++++
3 files changed, 279 insertions(+), 1 deletion(-)
create mode 100644 src/views/setting/AccountSettingNetwork.vue
diff --git a/src/pages/setting.vue b/src/pages/setting.vue
index 9fc87a16..6d704dd7 100644
--- a/src/pages/setting.vue
+++ b/src/pages/setting.vue
@@ -11,6 +11,7 @@ import AccountSettingService from '@/views/setting/AccountSettingService.vue'
import AccountSettingSystem from '@/views/setting/AccountSettingSystem.vue'
import AccountSettingDirectory from '@/views/setting/AccountSettingDirectory.vue'
import AccountSettingRule from '@/views/setting/AccountSettingRule.vue'
+import AccountSettingNetwork from '@/views/setting/AccountSettingNetwork.vue'
import { SettingTabs } from '@/router/menu'
const route = useRoute()
@@ -32,7 +33,7 @@ function jumpTab(tab: string) {
@click="jumpTab(item.tab)"
selected-class="v-slide-group-item--active v-tab--selected"
>
-
+
{{ item.title }}
@@ -49,6 +50,15 @@ function jumpTab(tab: string) {
+
+
+
+
+
+
+
diff --git a/src/router/menu.ts b/src/router/menu.ts
index 38b48bd0..675fece9 100644
--- a/src/router/menu.ts
+++ b/src/router/menu.ts
@@ -133,6 +133,12 @@ export const SettingTabs = [
tab: 'system',
description: '下载器(Qbittorrent、Transmission)、媒体服务器(Emby、Jellyfin、Plex)',
},
+ {
+ title: '网络',
+ icon: 'mdi-access-point-network',
+ tab: 'network',
+ description: 'Github、PIP、OCR、DOH',
+ },
{
title: '存储 & 目录',
icon: 'mdi-folder',
diff --git a/src/views/setting/AccountSettingNetwork.vue b/src/views/setting/AccountSettingNetwork.vue
new file mode 100644
index 00000000..568e5c7d
--- /dev/null
+++ b/src/views/setting/AccountSettingNetwork.vue
@@ -0,0 +1,262 @@
+
+
+
+
+
+
+
+
+ 基础设置
+ 设置DNS over HTTPS服务器,对特定域名使用DOH解析以避免DNS污染。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {}">
+
+ 保存
+
+
+
+
+
+
+
+
+
+
+ Github 与 PIP
+ 设置PIP加速站、Github加速站、Github Token增加连接的限流阈值,保证连通性。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {}">
+
+ 保存
+
+
+
+
+
+
+
From c72fcbd10d147b0e4aa53f36acc0472f1c9f1309 Mon Sep 17 00:00:00 2001
From: Aqr-K <95741669+Aqr-K@users.noreply.github.com>
Date: Fri, 25 Oct 2024 11:31:10 +0800
Subject: [PATCH 02/21] =?UTF-8?q?feat:=20=E7=BD=91=E7=BB=9C=E5=A2=9E?=
=?UTF-8?q?=E5=8A=A0=E9=AB=98=E7=BA=A7=E8=AE=BE=E7=BD=AE=E5=BC=B9=E7=AA=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/views/setting/AccountSettingNetwork.vue | 168 +++++++++++++++-----
1 file changed, 128 insertions(+), 40 deletions(-)
diff --git a/src/views/setting/AccountSettingNetwork.vue b/src/views/setting/AccountSettingNetwork.vue
index 568e5c7d..859b5324 100644
--- a/src/views/setting/AccountSettingNetwork.vue
+++ b/src/views/setting/AccountSettingNetwork.vue
@@ -1,25 +1,32 @@
@@ -149,7 +166,7 @@ onDeactivated(() => {
-
+
{
{}">
- 保存
+ 保存
@@ -232,7 +249,8 @@ onDeactivated(() => {
persistent-hint
clearable
active
- />
+ >
+
{
{}">
- 保存
+ 保存
+
+
+
+
+
+ 网络高级设置
+ 修改前,请先了解清除这些设置的作用。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 默认值
+
+
+ 确定
+
+
+
+
From bd9169bcd1c74a52b785fd189dba6f8dbcae164f Mon Sep 17 00:00:00 2001
From: Aqr-K <95741669+Aqr-K@users.noreply.github.com>
Date: Thu, 31 Oct 2024 03:38:01 +0800
Subject: [PATCH 03/21] feat(settings): add new AccountSettingsSystem.vue
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 将 原system更名为service,原service更名为scheduler
- 增加新的 AccountSettingSystem.vue。
- 调整 menu.ts 与settings.vue,适配新的 system 标签页
---
src/pages/setting.vue | 14 +-
src/router/menu.ts | 18 +-
src/views/setting/AccountSettingNetwork.vue | 350 -----------
src/views/setting/AccountSettingScheduler.vue | 124 ++++
src/views/setting/AccountSettingService.vue | 434 ++++++++++---
src/views/setting/AccountSettingSystem.vue | 584 ++++++++++--------
6 files changed, 815 insertions(+), 709 deletions(-)
delete mode 100644 src/views/setting/AccountSettingNetwork.vue
create mode 100644 src/views/setting/AccountSettingScheduler.vue
diff --git a/src/pages/setting.vue b/src/pages/setting.vue
index 6d704dd7..43899608 100644
--- a/src/pages/setting.vue
+++ b/src/pages/setting.vue
@@ -9,9 +9,9 @@ import AccountSettingSearch from '@/views/setting/AccountSettingSearch.vue'
import AccountSettingSubscribe from '@/views/setting/AccountSettingSubscribe.vue'
import AccountSettingService from '@/views/setting/AccountSettingService.vue'
import AccountSettingSystem from '@/views/setting/AccountSettingSystem.vue'
+import AccountSettingScheduler from '@/views/setting/AccountSettingScheduler.vue'
import AccountSettingDirectory from '@/views/setting/AccountSettingDirectory.vue'
import AccountSettingRule from '@/views/setting/AccountSettingRule.vue'
-import AccountSettingNetwork from '@/views/setting/AccountSettingNetwork.vue'
import { SettingTabs } from '@/router/menu'
const route = useRoute()
@@ -41,7 +41,7 @@ function jumpTab(tab: string) {
-
+
@@ -50,11 +50,11 @@ function jumpTab(tab: string) {
-
-
+
+
@@ -103,10 +103,10 @@ function jumpTab(tab: string) {
-
+
diff --git a/src/router/menu.ts b/src/router/menu.ts
index f5ebe33b..807570e6 100644
--- a/src/router/menu.ts
+++ b/src/router/menu.ts
@@ -132,16 +132,16 @@ export const UserfulMenus = [
// 设定标签页
export const SettingTabs = [
{
- title: '连接',
- icon: 'mdi-server-network',
+ title: '系统',
+ icon: 'mdi-cog',
tab: 'system',
- description: '下载器(Qbittorrent、Transmission)、媒体服务器(Emby、Jellyfin、Plex)',
+ description: '基本设定、网络设定、高级设定',
},
{
- title: '网络',
- icon: 'mdi-access-point-network',
- tab: 'network',
- description: 'Github、PIP、OCR、DOH',
+ title: '连接',
+ icon: 'mdi-server-network',
+ tab: 'service',
+ description: '下载器(Qbittorrent、Transmission)、媒体服务器(Emby、Jellyfin、Plex)',
},
{
title: '存储 & 目录',
@@ -174,9 +174,9 @@ export const SettingTabs = [
description: '订阅站点、订阅模式、订阅优先级、洗版优先级、默认过滤规则',
},
{
- title: '服务',
+ title: '调度',
icon: 'mdi-list-box',
- tab: 'service',
+ tab: 'scheduler',
description: '定时作业',
},
{
diff --git a/src/views/setting/AccountSettingNetwork.vue b/src/views/setting/AccountSettingNetwork.vue
deleted file mode 100644
index 859b5324..00000000
--- a/src/views/setting/AccountSettingNetwork.vue
+++ /dev/null
@@ -1,350 +0,0 @@
-
-
-
-
-
-
-
-
- 基础设置
- 设置DNS over HTTPS服务器,对特定域名使用DOH解析以避免DNS污染。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {}">
-
- 保存
-
-
-
-
-
-
-
-
-
-
- Github 与 PIP
- 设置PIP加速站、Github加速站、Github Token增加连接的限流阈值,保证连通性。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {}">
-
- 保存
-
-
-
-
-
-
-
-
-
-
- 网络高级设置
- 修改前,请先了解清除这些设置的作用。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 默认值
-
-
- 确定
-
-
-
-
-
-
diff --git a/src/views/setting/AccountSettingScheduler.vue b/src/views/setting/AccountSettingScheduler.vue
new file mode 100644
index 00000000..30b0aa1f
--- /dev/null
+++ b/src/views/setting/AccountSettingScheduler.vue
@@ -0,0 +1,124 @@
+
+
+
+
+
+ 定时作业
+ 包含系统内置服务以及插件提供的服务,手动执行不会影响作业正常的时间表。
+
+
+
+
+ | 提供者 |
+ 任务名称 |
+ 任务状态 |
+ 下一次执行时间 |
+ |
+
+
+
+
+ |
+ {{ scheduler.provider }}
+ |
+
+ {{ scheduler.name }}
+ |
+
+
+ {{ scheduler.status }}
+
+ |
+
+ {{ scheduler.next_run }}
+ |
+
+
+
+ mdi-play
+
+ 执行
+
+ |
+
+
+ | 没有后台服务 |
+
+
+
+
+
diff --git a/src/views/setting/AccountSettingService.vue b/src/views/setting/AccountSettingService.vue
index 30b0aa1f..bde3a50e 100644
--- a/src/views/setting/AccountSettingService.vue
+++ b/src/views/setting/AccountSettingService.vue
@@ -1,124 +1,356 @@
+
-
-
- 定时作业
- 包含系统内置服务以及插件提供的服务,手动执行不会影响作业正常的时间表。
-
-
-
-
- | 提供者 |
- 任务名称 |
- 任务状态 |
- 下一次执行时间 |
- |
-
-
-
-
- |
- {{ scheduler.provider }}
- |
-
- {{ scheduler.name }}
- |
-
-
- {{ scheduler.status }}
-
- |
-
- {{ scheduler.next_run }}
- |
-
-
-
- mdi-play
-
- 执行
-
- |
-
-
- | 没有后台服务 |
-
-
-
-
+
+
+
+
+ 基础设置
+ 设置服务器的全局功能。
+
+
+
+
+
+
+
+
+
+
+
+ {}">
+
+ 保存
+
+
+
+
+
+
+
+
+ 下载器
+ 只有默认下载器才会被默认使用。
+
+
+
+
+
+
+
+
+
+ {}">
+
+ 保存
+
+
+
+
+
+ Qbittorrent
+
+
+ Transmission
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 媒体服务器
+ 所有启用的媒体服务器都会被使用。
+
+
+
+
+
+
+
+
+
+ {}">
+
+ 保存
+
+
+
+
+
+ Emby
+
+
+ Jellyfin
+
+
+ Plex
+
+
+
+
+
+
+
+
+
+
diff --git a/src/views/setting/AccountSettingSystem.vue b/src/views/setting/AccountSettingSystem.vue
index 332bd704..b7663404 100644
--- a/src/views/setting/AccountSettingSystem.vue
+++ b/src/views/setting/AccountSettingSystem.vue
@@ -1,106 +1,68 @@
-
+
- 系统
- 设置服务使用的域名等基础信息。
+ 基础系统设置
+ 设置用户辅助认证、登录首页壁纸、访问域名、插件市场等基础化设置。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -227,109 +274,162 @@ onDeactivated(() => {
{}">
- 保存
-
-
-
-
-
-
-
-
- 下载器
- 只有默认下载器才会被默认使用。
-
-
-
-
-
-
-
-
-
- {}">
-
- 保存
-
-
-
-
-
- Qbittorrent
-
-
- Transmission
-
-
-
-
+ 保存
+
- 媒体服务器
- 所有启用的媒体服务器都会被使用。
+ 基础网络设置
+ 设置DOH、PIP加速站、Github加速站、Github Token等,增加网络稳定性,保证连通性。
-
-
-
-
-
+
+
+
+
+
+
+
+
+ 当前已成功配置 PROXY_HOST ,建议关闭 DOH 功能。
+ 暂未配置 PROXY_HOST,如出现网络连通性问题,可考虑开启 DOH 功能。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{}">
- 保存
-
-
-
-
-
- Emby
-
-
- Jellyfin
-
-
- Plex
-
-
-
-
+ 保存
+
+
+
+
+
+
From c90ed003f7d560720893e51980fa0f943ffeb283 Mon Sep 17 00:00:00 2001
From: Aqr-K <95741669+Aqr-K@users.noreply.github.com>
Date: Thu, 31 Oct 2024 04:15:12 +0800
Subject: [PATCH 04/21] feat(settings): add systemSettingsDialog
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 增加 AdvancedNetworkSettingsDialog 与 AdvancedSystemSettingsDialog,适配 system 预设的高级设置弹窗。
---
.../dialog/AdvancedNetworkSettingsDialog.vue | 98 +++++++++++++++++++
.../dialog/AdvancedSystemSettingsDialog.vue | 93 ++++++++++++++++++
2 files changed, 191 insertions(+)
create mode 100644 src/components/dialog/AdvancedNetworkSettingsDialog.vue
create mode 100644 src/components/dialog/AdvancedSystemSettingsDialog.vue
diff --git a/src/components/dialog/AdvancedNetworkSettingsDialog.vue b/src/components/dialog/AdvancedNetworkSettingsDialog.vue
new file mode 100644
index 00000000..c0c69a74
--- /dev/null
+++ b/src/components/dialog/AdvancedNetworkSettingsDialog.vue
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+ 高级网络设置
+ 修改前,请先了解清楚这些设置的作用。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {}">
+
+
+ 恢复默认值
+
+
+ 确定
+
+
+
+
+
+
+
diff --git a/src/components/dialog/AdvancedSystemSettingsDialog.vue b/src/components/dialog/AdvancedSystemSettingsDialog.vue
new file mode 100644
index 00000000..41e15ab5
--- /dev/null
+++ b/src/components/dialog/AdvancedSystemSettingsDialog.vue
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+ 高级系统设置
+ 修改前,请先了解清楚这些设置的作用。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {}">
+
+
+ 确定
+
+
+
+
+
+
+
From eab2f0df20d3b638a1bf4b7afd180ac1e4e2041e Mon Sep 17 00:00:00 2001
From: Aqr-K <95741669+Aqr-K@users.noreply.github.com>
Date: Thu, 31 Oct 2024 16:46:05 +0800
Subject: [PATCH 05/21] feat(settings): AccountSettingNotification
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 增加防抖。
- `card` 从父组件获取到的值改为深复制,解决 `card` 内修改数据,会直接导致在父组件中同步更新的问题。
- 微调图标位置。
---
.../cards/NotificationChannelCard.vue | 32 +++++++++----------
.../setting/AccountSettingNotification.vue | 31 ++++++++++++------
2 files changed, 36 insertions(+), 27 deletions(-)
diff --git a/src/components/cards/NotificationChannelCard.vue b/src/components/cards/NotificationChannelCard.vue
index 3e767b1a..93af2bde 100644
--- a/src/components/cards/NotificationChannelCard.vue
+++ b/src/components/cards/NotificationChannelCard.vue
@@ -7,6 +7,7 @@ import synologychat_image from '@images/logos/synologychat.png'
import slack_image from '@images/logos/slack.webp'
import chrome_image from '@images/logos/chrome.png'
import { useToast } from 'vue-toast-notification'
+import { cloneDeep } from "lodash"
// 定义输入
const props = defineProps({
@@ -31,9 +32,6 @@ const $toast = useToast()
// 通知详情弹窗
const notificationInfoDialog = ref(false)
-// 通知名称
-const notificationName = ref('')
-
// 通知详情
const notificationInfo = ref({
name: '',
@@ -66,26 +64,26 @@ const notificationTypes = [
// 打开详情弹窗
function openNotificationInfoDialog() {
- notificationInfo.value = props.notification
- notificationName.value = props.notification.name
+ // 替换成深复制,避免修改时影响原数据
+ notificationInfo.value = cloneDeep(props.notification)
+ console.log(`当前卡片的通知信息:${JSON.stringify(notificationInfo.value)}`)
notificationInfoDialog.value = true
}
// 保存详情数据
function saveNotificationInfo() {
// 为空不保存,跳出警告框
- if (!notificationName.value) {
+ if (!notificationInfo.value.name) {
$toast.error('名称不能为空,请输入后再确定')
return
}
// 重名判断
- if (props.notifications.some(item => item.name === notificationName.value && item !== props.notification)) {
- $toast.error(`【${notificationName.value}】已存在,请替换为其他名称`)
+ if (props.notifications.some(item => item.name === notificationInfo.value.name && item !== props.notification)) {
+ $toast.error(`通知渠道【${notificationInfo.value.name}】已存在,请替换`)
return
}
notificationInfoDialog.value = false
- notificationInfo.value.name = notificationName.value
- emit('change', notificationInfo.value)
+ emit('change', notificationInfo.value, props.notification.name)
emit('done')
}
@@ -131,7 +129,7 @@ function onClose() {
{{ notificationTypeNames[notification.type] }}
-
+
@@ -160,7 +158,7 @@ function onClose() {
([])
+// 防抖时间
+const debounceTime = 500
+
// 提示框
const $toast = useToast()
@@ -58,8 +62,8 @@ async function reloadSystem() {
}
}
-// 添加媒体服务器
-function addNotification(notification: string) {
+// 添加通知渠道
+const addNotification = debounce((notification: string) => {
let name = `通知${notifications.value.length + 1}`;
while (notifications.value.some(item => item.name === name)) {
name = `通知${parseInt(name.split('通知')[1]) + 1}`;
@@ -70,15 +74,15 @@ function addNotification(notification: string) {
enabled: false,
config: {},
})
-}
+}, debounceTime)
-// 移除媒体服务器
+// 移除通知渠道
function removeNotification(notification: NotificationConf) {
const index = notifications.value.indexOf(notification)
if (index > -1) notifications.value.splice(index, 1)
}
-// 调用API查询通知设置
+// 调用API查询通知渠道设置
async function loadNotificationSetting() {
try {
const result: { [key: string]: any } = await api.get('system/setting/Notifications')
@@ -89,7 +93,7 @@ async function loadNotificationSetting() {
}
// 调用API保存通知设置
-async function saveNotificationSetting() {
+const saveNotificationSetting = debounce(async () => {
try {
const result: { [key: string]: any } = await api.post('system/setting/Notifications', notifications.value)
if (result.success) {
@@ -99,6 +103,12 @@ async function saveNotificationSetting() {
} catch (error) {
console.log(error)
}
+}, debounceTime)
+
+// 通知渠道设置变化时赋值
+function changNotificationSetting(notification: NotificationConf, name: string) {
+ const index = notifications.value.findIndex(item => item.name === name)
+ if (index !== -1) notifications.value[index] = notification
}
// 加载消息类型开关
@@ -112,7 +122,7 @@ async function loadNotificationSwitchs() {
}
// 保存消息类型开关
-async function saveNotificationSwitchs() {
+const saveNotificationSwitchs = debounce(async () => {
try {
const result: { [key: string]: any } = await api.post(
'system/setting/NotificationSwitchs',
@@ -123,7 +133,7 @@ async function saveNotificationSwitchs() {
} catch (error) {
console.log(error)
}
-}
+}, debounceTime)
// 加载数据
onMounted(() => {
@@ -152,6 +162,7 @@ onMounted(() => {
@@ -161,7 +172,7 @@ onMounted(() => {
{}">
保存
-
+
@@ -225,7 +236,7 @@ onMounted(() => {
{}">
- 保存
+ 保存
From db0325a59ce4099f32b39689b7e6a96f6ad58027 Mon Sep 17 00:00:00 2001
From: Aqr-K <95741669+Aqr-K@users.noreply.github.com>
Date: Thu, 31 Oct 2024 17:08:23 +0800
Subject: [PATCH 06/21] feat(settings): AccountSettingRule
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 增加防抖。
- `card` 从父组件获取到的值改为深复制,解决 `card` 内修改数据,会直接导致在父组件中同步更新的问题。
- 修复 规则id与name 只缺少一项时,仍能正常确定的问题。
- 保存前增加一次检查,避免通过分享导入的规则存在重名与空名引发的错误。
---
src/components/cards/CustomRuleCard.vue | 38 ++++-------
src/components/cards/FilterRuleGroupCard.vue | 30 ++++----
src/views/setting/AccountSettingRule.vue | 72 +++++++++++++++-----
3 files changed, 81 insertions(+), 59 deletions(-)
diff --git a/src/components/cards/CustomRuleCard.vue b/src/components/cards/CustomRuleCard.vue
index 83ed6863..87682acf 100644
--- a/src/components/cards/CustomRuleCard.vue
+++ b/src/components/cards/CustomRuleCard.vue
@@ -2,6 +2,7 @@
import { CustomRule } from '@/api/types'
import { useToast } from 'vue-toast-notification'
import filter_svg from '@images/svg/filter.svg'
+import { cloneDeep } from 'lodash'
// 输入参数
const props = defineProps({
@@ -37,50 +38,41 @@ const ruleInfo = ref({
publish_time: '',
})
-// 规则ID
-const ruleId = ref('')
-
-// 规则名称
-const ruleName = ref('')
-
// 打开详情弹窗
function openRuleInfoDialog() {
- ruleInfo.value = props.rule
- ruleId.value = props.rule.id
- ruleName.value = props.rule.name
+ // 深复制
+ ruleInfo.value = cloneDeep(props.rule)
ruleInfoDialog.value = true
}
// 保存详情数据
function saveRuleInfo() {
// 有空值
- if (!ruleId.value && !ruleName.value) {
- if (!ruleId.value && ruleName.value) {
+ if (!ruleInfo.value.id || !ruleInfo.value.name) {
+ if (!ruleInfo.value.id && ruleInfo.value.name) {
$toast.error('规则ID不能为空')
}
- if (ruleId.value && !ruleName.value) {
+ if (ruleInfo.value.id && !ruleInfo.value.name) {
$toast.error('规则名称不能为空')
}
- if (!ruleId.value && !ruleName.value) {
+ if (!ruleInfo.value.id && !ruleInfo.value.name) {
$toast.error('规则ID和规则名称不能为空')
}
return
}
// ID已存在
- if (ruleId.value !== props.rule.id && props.rules.find(rule => rule.id === ruleId.value)) {
- $toast.error(`规则ID【${ruleId.value}】已存在,请替换`)
+ if (ruleInfo.value.id !== props.rule.id && props.rules.find(rule => rule.id === ruleInfo.value.id)) {
+ $toast.error(`规则ID【${ruleInfo.value.id}】已存在,请替换`)
return
}
// 规则名称已存在
- if (ruleName.value !== props.rule.name && props.rules.find(rule => rule.name === ruleName.value)) {
- $toast.error(`规则名称【${ruleName.value}】已存在,请替换`)
+ if (ruleInfo.value.name !== props.rule.name && props.rules.find(rule => rule.name === ruleInfo.value.name)) {
+ $toast.error(`规则名称【${ruleInfo.value.name}】已存在,请替换`)
return
}
// 保存数据
ruleInfoDialog.value = false
- ruleInfo.value.id = ruleId.value
- ruleInfo.value.name = ruleName.value
- emit('change', ruleInfo.value)
+ emit('change', ruleInfo.value, props.rule.id)
emit('done')
}
@@ -107,7 +99,7 @@ function onClose() {
-
+
@@ -116,7 +108,7 @@ function onClose() {
({
category: props.group?.category,
})
-// 规则组名称
-const groupName = ref('')
-
// 媒体类型字典
const mediaTypeItems = [
{ title: '通用', value: '' },
@@ -88,15 +86,12 @@ function updateFilterCardValue(pri: string, rules: string[]) {
// 移除卡片
function filterCardClose(pri: string) {
- // 将pri对应的卡片从列表中删除,并更新剩余卡片的序号
- const updatedCards = filterRuleCards.value
+ filterRuleCards.value = filterRuleCards.value
.filter(card => card.pri !== pri)
.map((card, index) => {
card.pri = (index + 1).toString()
return card
})
- // 更新 filterRuleCards.value
- filterRuleCards.value = updatedCards
}
// 分享规则
@@ -163,8 +158,8 @@ function dragOrderEnd() {
// 打开详情弹窗
function opengroupInfoDialog() {
- groupInfo.value = props.group
- groupName.value = props.group.name
+ // 深复制
+ groupInfo.value = cloneDeep(props.group)
if (props.group.rule_string) {
filterRuleCards.value = props.group.rule_string.split('>').map((group: string, index: number) => {
return {
@@ -177,26 +172,25 @@ function opengroupInfoDialog() {
}
// 保存详情数据
-function savegroupInfo() {
+function saveGroupInfo() {
// 为空
- if (!groupName.value) {
+ if (!groupInfo.value.name) {
$toast.error('规则组名称不能为空')
return
}
// 重名判断
- if (props.groups.some(item => item.name === groupName.value && item !== props.group)) {
- $toast.error(`规则组名称【${groupName.value}】已存在,请替换`)
+ if (props.groups.some(item => item.name === groupInfo.value.name && item !== props.group)) {
+ $toast.error(`规则组名称【${groupInfo.value.name}】已存在,请替换`)
return
}
// 保存
groupInfoDialog.value = false
- groupInfo.value.name = groupName.value
// 更新到 groupInfo的rule_string
groupInfo.value.rule_string = filterRuleCards.value
.filter(card => card.rules.length > 0)
.map(card => card.rules.join('&'))
.join('>')
- emit('change', groupInfo.value)
+ emit('change', groupInfo.value, props.group.name)
emit('done')
}
@@ -226,7 +220,7 @@ function onClose() {
-
+
@@ -234,7 +228,7 @@ function onClose() {
- 确定
+ 确定
diff --git a/src/views/setting/AccountSettingRule.vue b/src/views/setting/AccountSettingRule.vue
index 5db32609..97be59a5 100644
--- a/src/views/setting/AccountSettingRule.vue
+++ b/src/views/setting/AccountSettingRule.vue
@@ -9,6 +9,10 @@ import { CustomRule, FilterRuleGroup } from '@/api/types'
import CustomerRuleCard from '@/components/cards/CustomRuleCard.vue'
import FilterRuleGroupCard from '@/components/cards/FilterRuleGroupCard.vue'
import ImportCodeDialog from '@/components/dialog/ImportCodeDialog.vue'
+import debounce from 'lodash/debounce'
+
+// 防抖时间
+const debounceTime = 500
// 自定义规则列表
const customRules = ref([])
@@ -52,7 +56,29 @@ async function loadMediaCategories() {
}
// 保存自定义规则
-async function saveCustomRules() {
+const saveCustomRules = debounce(async () => {
+ // 检查是否存在空id规则
+ if (customRules.value.some(item => !item.id)) {
+ $toast.error('存在空ID的规则!无法保存,请修改!')
+ return
+ }
+ // 检查是否存在空的规则名称
+ if (customRules.value.some(item => !item.name)) {
+ $toast.error('存在空名字的规则!无法保存,请修改!')
+ return
+ }
+ // 检查是否存在重名的规则ID
+ const ids = customRules.value.map(item => item.id)
+ if (new Set(ids).size !== ids.length) {
+ $toast.error('存在重复规则ID!无法保存,请修改!')
+ return
+ }
+ // 检查是否存在重名规
+ const names = customRules.value.map(item => item.name)
+ if (new Set(names).size !== names.length) {
+ $toast.error('存在重复规则名称!无法保存,请修改!')
+ return
+ }
try {
const result: { [key: string]: any } = await api.post('system/setting/CustomFilterRules', customRules.value)
if (result.success) $toast.success('自定义规则保存成功')
@@ -60,10 +86,10 @@ async function saveCustomRules() {
} catch (error) {
console.log(error)
}
-}
+}, debounceTime)
// 添加自定义规则
-function addCustomRule() {
+const addCustomRule = debounce(async () => {
let id = `RULE${customRules.value.length + 1}`
while (customRules.value.some(item => item.id === id)) {
id = `RULE${parseInt(id.split('RULE')[1]) + 1}`
@@ -78,7 +104,7 @@ function addCustomRule() {
include: '',
exclude: '',
})
-}
+}, debounceTime)
// 移除自定义规则
function removeCustomRule(rule: CustomRule) {
@@ -97,7 +123,18 @@ async function queryFilterRuleGroups() {
}
// 保存规则组
-async function saveFilterRuleGroups() {
+const saveFilterRuleGroups = debounce(async () => {
+ // 检查是否存在空的规则组名称
+ if (filterRuleGroups.value.some(item => !item.name)) {
+ $toast.error('存在空名字的规则组!无法保存,请修改!')
+ return
+ }
+ // 检查是否存在重名规则组
+ const names = filterRuleGroups.value.map(item => item.name)
+ if (new Set(names).size !== names.length) {
+ $toast.error('存在重复规则组名称!无法保存,请修改!')
+ return
+ }
try {
const result: { [key: string]: any } = await api.post('system/setting/UserFilterRuleGroups', filterRuleGroups.value)
if (result.success) $toast.success('优先级规则组保存成功')
@@ -105,10 +142,10 @@ async function saveFilterRuleGroups() {
} catch (error) {
console.log(error)
}
-}
+}, debounceTime)
// 添加规则组
-function addFilterRuleGroup() {
+const addFilterRuleGroup = debounce(() => {
let name = `规则组${filterRuleGroups.value.length + 1}`
while (filterRuleGroups.value.some(item => item.name === name)) {
name = `规则组${parseInt(name.split('规则组')[1]) + 1}`
@@ -119,10 +156,11 @@ function addFilterRuleGroup() {
media_type: '',
category: '',
})
-}
+}, debounceTime)
// 分享规则
-function shareRules(rules: CustomRule[] | FilterRuleGroup[]) {
+// function shareRules(rules: CustomRule[] | FilterRuleGroup[]) {
+const shareRules = debounce((rules: CustomRule[] | FilterRuleGroup[]) => {
if (!rules || rules.length === 0) return
// 将卡片规则接装为字符串
@@ -135,7 +173,7 @@ function shareRules(rules: CustomRule[] | FilterRuleGroup[]) {
} catch (error) {
$toast.error('优先级规则复制失败!')
}
-}
+}, debounceTime)
// 导入规则
async function importRules(ruleType: string) {
@@ -179,8 +217,8 @@ watchEffect(() => {
})
// 规则变化时赋值
-function onRuleChange(rule: CustomRule) {
- const index = customRules.value.findIndex(item => item.id === rule.id)
+function onRuleChange(rule: CustomRule, id: string) {
+ const index = customRules.value.findIndex(item => item.id === id)
if (index !== -1) customRules.value[index] = rule
}
@@ -191,8 +229,8 @@ function removeFilterRuleGroup(rule: FilterRuleGroup) {
}
// 规则组变化时赋值
-function changeRuleGroup(group: FilterRuleGroup) {
- const index = filterRuleGroups.value.findIndex(item => item.name === group.name)
+function changeRuleGroup(group: FilterRuleGroup, name: string) {
+ const index = filterRuleGroups.value.findIndex(item => item.name === name)
if (index !== -1) filterRuleGroups.value[index] = group
}
@@ -218,20 +256,18 @@ async function queryCustomRules() {
}
// 保存种子优先规则
-async function saveTorrentPriority() {
+const saveTorrentPriority = debounce(async () => {
try {
- // 用户名密码
const result: { [key: string]: any } = await api.post(
'system/setting/TorrentsPriority',
selectedTorrentPriority.value,
)
-
if (result.success) $toast.success('优先规则保存成功')
else $toast.error('优先规则保存失败!')
} catch (error) {
console.log(error)
}
-}
+}, debounceTime)
// 加载数据
onMounted(() => {
From 6bc420d57f215caebccd6ea2f9b2cb03ff16d600 Mon Sep 17 00:00:00 2001
From: Aqr-K <95741669+Aqr-K@users.noreply.github.com>
Date: Thu, 31 Oct 2024 17:53:45 +0800
Subject: [PATCH 07/21] feat(settings): AccountSettingService
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 增加防抖。
- `card` 从父组件获取到的值改为深复制,解决 `card` 内修改数据,会直接导致在父组件中同步更新的问题。
---
src/components/cards/DownloaderCard.vue | 23 +++++++++------------
src/components/cards/MediaServerCard.vue | 23 +++++++++------------
src/views/setting/AccountSettingService.vue | 22 ++++++++++----------
3 files changed, 31 insertions(+), 37 deletions(-)
diff --git a/src/components/cards/DownloaderCard.vue b/src/components/cards/DownloaderCard.vue
index 0c8e3196..01f27ada 100644
--- a/src/components/cards/DownloaderCard.vue
+++ b/src/components/cards/DownloaderCard.vue
@@ -6,6 +6,7 @@ import { useToast } from 'vue-toast-notification'
import type { DownloaderInfo } from '@/api/types'
import qbittorrent_image from '@images/logos/qbittorrent.png'
import transmission_image from '@images/logos/transmission.png'
+import {cloneDeep} from "lodash";
// 定义输入
const props = defineProps({
@@ -44,9 +45,6 @@ const download_rate = ref(0)
// 下载器详情弹窗
const downloaderInfoDialog = ref(false)
-// 下载器名称
-const downloaderName = ref('')
-
// 下载器详情
const downloaderInfo = ref({
name: '',
@@ -84,21 +82,21 @@ async function loadDownloaderInfo() {
// 打开详情弹窗
function openDownloaderInfoDialog() {
- downloaderInfo.value = props.downloader
- downloaderName.value = props.downloader.name
+ // 深复制
+ downloaderInfo.value = cloneDeep(props.downloader)
downloaderInfoDialog.value = true
}
// 保存详情数据
function saveDownloaderInfo() {
// 为空不保存,跳出警告框
- if (!downloaderName.value) {
+ if (!downloaderInfo.value.name) {
$toast.error('名称不能为空,请输入后再确定')
return
}
// 重名判断
- if (props.downloaders.some(item => item.name === downloaderName.value && item !== props.downloader)) {
- $toast.error(`【${downloaderName.value}】已存在,请替换为其他名称`)
+ if (props.downloaders.some(item => item.name === downloaderInfo.value.name && item !== props.downloader)) {
+ $toast.error(`【${downloaderInfo.value.name}】已存在,请替换为其他名称`)
return
}
// 默认下载器去重
@@ -106,14 +104,13 @@ function saveDownloaderInfo() {
props.downloaders.forEach(item => {
if (item.default && item !== props.downloader) {
item.default = false
- $toast.info(`【${item.name}】存在默认下载器,已替换成【${downloaderName.value}】`)
+ $toast.info(`【${item.name}】存在默认下载器,已替换成【${downloaderInfo.value.name}】`)
}
})
}
// 执行保存
downloaderInfoDialog.value = false
- downloaderInfo.value.name = downloaderName.value
- emit('change', downloaderInfo.value)
+ emit('change', downloaderInfo.value, props.downloader.name)
emit('done')
}
@@ -192,7 +189,7 @@ onUnmounted(() => {
{
([
// 媒体服务器详情弹窗
const mediaServerInfoDialog = ref(false)
-// 媒体服务器名称
-const mediaServerName = ref('')
-
// 媒体服务器详情
const mediaServerInfo = ref({
name: '',
@@ -70,8 +68,8 @@ const mediaServerInfo = ref({
// 打开详情弹窗
function openMediaServerInfoDialog() {
loadLibrary(props.mediaserver.name)
- mediaServerInfo.value = props.mediaserver
- mediaServerName.value = props.mediaserver.name
+ // 深复制
+ mediaServerInfo.value = cloneDeep(props.mediaserver)
mediaServerInfoDialog.value = true
if (!props.mediaserver.sync_libraries) {
mediaServerInfo.value.sync_libraries = ['all']
@@ -81,19 +79,18 @@ function openMediaServerInfoDialog() {
// 保存详情数据
function saveMediaServerInfo() {
// 为空不保存,跳出警告框
- if (!mediaServerName.value) {
+ if (!mediaServerInfo.value.name) {
$toast.error('名称不能为空,请输入后再确定')
return
}
// 重名判断
- if (props.mediaservers.some(item => item.name === mediaServerName.value && item !== props.mediaserver)) {
- $toast.error(`【${mediaServerName.value}】已存在,请替换为其他名称`)
+ if (props.mediaservers.some(item => item.name === mediaServerInfo.value.name && item !== props.mediaserver)) {
+ $toast.error(`【${mediaServerInfo.value.name}】已存在,请替换为其他名称`)
return
}
// 执行保存
mediaServerInfoDialog.value = false
- mediaServerInfo.value.name = mediaServerName.value
- emit('change', mediaServerInfo.value)
+ emit('change', mediaServerInfo.value, props.mediaserver.name)
emit('done')
}
@@ -202,7 +199,7 @@ onMounted(() => {
{
{
{
const index = downloaders.value.indexOf(ele)
downloaders.value.splice(index, 1)
-}
+}, debounceTime)
// 下载器变化
-function onDownloaderChange(downloader: DownloaderConf) {
- const index = downloaders.value.findIndex(item => item.name === downloader.name)
- downloaders.value[index] = downloader
+function onDownloaderChange(downloader: DownloaderConf, name: string) {
+ const index = downloaders.value.findIndex(item => item.name === name)
+ if (index !== -1) downloaders.value[index] = downloader
}
// 添加媒体服务器
@@ -181,15 +181,15 @@ const addMediaServer = debounce( (mediaserver: string) => {
}, debounceTime)
// 删除媒体服务器
-function removeMediaServer(ele: MediaServerConf) {
+const removeMediaServer = debounce((ele: MediaServerConf) => {
const index = mediaServers.value.indexOf(ele)
- mediaServers.value.splice(index, 1)
-}
+ if (index !== -1) mediaServers.value.splice(index, 1)
+}, debounceTime)
// 变更媒体服务器
-function onMediaServerChange(mediaserver: MediaServerConf) {
- const index = mediaServers.value.findIndex(item => item.name === mediaserver.name)
- mediaServers.value[index] = mediaserver
+function onMediaServerChange(mediaserver: MediaServerConf, name: string) {
+ const index = mediaServers.value.findIndex(item => item.name === name)
+ if (index !== -1) mediaServers.value[index] = mediaserver
}
// 禁止保存
From 6a4a2181524784e0fa682e48f01cfe5a758ba745 Mon Sep 17 00:00:00 2001
From: Aqr-K <95741669+Aqr-K@users.noreply.github.com>
Date: Thu, 31 Oct 2024 18:05:15 +0800
Subject: [PATCH 08/21] fix(settings): AccountSettingSite bug
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 拆分 CC 与 站点刷新,解决CC保存时,站点刷新也会被提交保存的问题。
---
src/views/setting/AccountSettingSite.vue | 108 +++++++++++++----------
1 file changed, 59 insertions(+), 49 deletions(-)
diff --git a/src/views/setting/AccountSettingSite.vue b/src/views/setting/AccountSettingSite.vue
index 8df2f888..d43fa9b5 100644
--- a/src/views/setting/AccountSettingSite.vue
+++ b/src/views/setting/AccountSettingSite.vue
@@ -1,6 +1,10 @@
diff --git a/src/views/setting/AccountSettingRule.vue b/src/views/setting/AccountSettingRule.vue
index b0fee07f..86cd7ad9 100644
--- a/src/views/setting/AccountSettingRule.vue
+++ b/src/views/setting/AccountSettingRule.vue
@@ -159,7 +159,6 @@ const addFilterRuleGroup = debounce(() => {
}, debounceTime)
// 分享规则
-// function shareRules(rules: CustomRule[] | FilterRuleGroup[]) {
const shareRules = debounce((rules: CustomRule[] | FilterRuleGroup[]) => {
if (!rules || rules.length === 0) return
@@ -369,7 +368,7 @@ onMounted(() => {
-
+
diff --git a/src/views/setting/AccountSettingSubscribe.vue b/src/views/setting/AccountSettingSubscribe.vue
index 70a2bbaa..4be77acf 100644
--- a/src/views/setting/AccountSettingSubscribe.vue
+++ b/src/views/setting/AccountSettingSubscribe.vue
@@ -21,6 +21,9 @@ const selectedBestVersionRuleGroup = ref([])
// 是否开启订阅定时搜索
const enableIntervalSearch = ref(false)
+// 是否检查本地媒体库是否存在资源
+const enableDirExistsSearch = ref(false)
+
// 订阅模式选择项
const subscribeModeItems = [
{ title: '自动', value: 'spider' },
@@ -118,6 +121,9 @@ async function querySubscribeSetting() {
// 查询洗版规则组
const result5: { [key: string]: any } = await api.get('system/setting/BestVersionFilterRuleGroups')
if (result5.success) selectedBestVersionRuleGroup.value = result5.data?.value
+ // 查询检查本地媒体库是否存在资源开关
+ const result6: { [key: string]: any } = await api.get('system/setting/LOCAL_EXISTS_SEARCH')
+ if (result6.success) enableDirExistsSearch.value = result6.data?.value
} catch (error) {
console.log(error)
}
@@ -148,7 +154,12 @@ async function saveSubscribeSetting() {
selectedBestVersionRuleGroup.value,
)
- if (result1.success && result2.success && result3.success && result4.success && result5.success)
+ const result6: { [key: string]: any } = await api.post(
+ 'system/setting/LOCAL_EXISTS_SEARCH',
+ enableDirExistsSearch.value,
+ )
+
+ if (result1.success && result2.success && result3.success && result4.success && result5.success && result6.success)
$toast.success('订阅设置保存成功')
else $toast.error('订阅设置保存失败!')
} catch (error) {
@@ -222,11 +233,19 @@ onMounted(() => {
+
+
+
From 39c7e723ba4d9e3867bf77b4d5a5a2efedb672b6 Mon Sep 17 00:00:00 2001
From: Aqr-K <95741669+Aqr-K@users.noreply.github.com>
Date: Thu, 31 Oct 2024 22:42:07 +0800
Subject: [PATCH 16/21] feat(settings): AccountSettingRule
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 增加对于 内置规则 的判断,避免与内置规则使用同一名称与ID。
---
src/components/cards/CustomRuleCard.vue | 52 +++++++++++++++++++++
src/views/setting/AccountSettingRule.vue | 59 ++++++++++++++++++++++--
2 files changed, 108 insertions(+), 3 deletions(-)
diff --git a/src/components/cards/CustomRuleCard.vue b/src/components/cards/CustomRuleCard.vue
index 87682acf..af74910b 100644
--- a/src/components/cards/CustomRuleCard.vue
+++ b/src/components/cards/CustomRuleCard.vue
@@ -38,6 +38,48 @@ const ruleInfo = ref({
publish_time: '',
})
+// 内置的规则
+const selectFilterOptions = ref<{ [key: string]: string }[]>([
+ { title: '特效字幕', value: ' SPECSUB ' },
+ { title: '中文字幕', value: ' CNSUB ' },
+ { title: '国语配音', value: ' CNVOI ' },
+ { title: '官种', value: ' GZ ' },
+ { title: '排除: 国语配音', value: ' !CNVOI ' },
+ { title: '粤语配音', value: ' HKVOI ' },
+ { title: '排除: 粤语配音', value: ' !HKVOI ' },
+ { title: '促销: 免费', value: ' FREE ' },
+ { title: '分辨率: 4K', value: ' 4K ' },
+ { title: '分辨率: 1080P', value: ' 1080P ' },
+ { title: '分辨率: 720P', value: ' 720P ' },
+ { title: '排除: 720P', value: ' !720P ' },
+ { title: '质量: 蓝光原盘', value: ' BLU ' },
+ { title: '排除: 蓝光原盘', value: ' !BLU ' },
+ { title: '质量: BLURAY', value: ' BLURAY ' },
+ { title: '排除: BLURAY', value: ' !BLURAY ' },
+ { title: '质量: UHD', value: ' UHD ' },
+ { title: '排除: UHD', value: ' !UHD ' },
+ { title: '质量: REMUX', value: ' REMUX ' },
+ { title: '排除: REMUX', value: ' !REMUX ' },
+ { title: '质量: WEB-DL', value: ' WEBDL ' },
+ { title: '排除: WEB-DL', value: ' !WEBDL ' },
+ { title: '质量: 60fps', value: ' 60FPS ' },
+ { title: '排除: 60fps', value: ' !60FPS ' },
+ { title: '编码: H265', value: ' H265 ' },
+ { title: '排除: H265', value: ' !H265 ' },
+ { title: '编码: H264', value: ' H264 ' },
+ { title: '排除: H264', value: ' !H264 ' },
+ { title: '效果: 杜比视界', value: ' DOLBY ' },
+ { title: '排除: 杜比视界', value: ' !DOLBY ' },
+ { title: '效果: 杜比全景声', value: ' ATMOS ' },
+ { title: '排除: 杜比全景声', value: ' !ATMOS ' },
+ { title: '效果: HDR', value: ' HDR ' },
+ { title: '排除: HDR', value: ' !HDR ' },
+ { title: '效果: SDR', value: ' SDR ' },
+ { title: '排除: SDR', value: ' !SDR ' },
+ { title: '效果: 3D', value: ' 3D ' },
+ { title: '排除: 3D', value: ' !3D ' },
+])
+
// 打开详情弹窗
function openRuleInfoDialog() {
// 深复制
@@ -60,6 +102,16 @@ function saveRuleInfo() {
}
return
}
+ // 检查ID是否在内置的规则中
+ if (selectFilterOptions.value.find(option => option.value === ruleInfo.value.id)) {
+ $toast.error('当前规则ID已被内置规则占用,请替换')
+ return
+ }
+ // 检查规则名称是否在内置的规则中
+ if (selectFilterOptions.value.find(option => option.title === ruleInfo.value.name)) {
+ $toast.error('当前规则名称已被内置规则占用,请替换')
+ return
+ }
// ID已存在
if (ruleInfo.value.id !== props.rule.id && props.rules.find(rule => rule.id === ruleInfo.value.id)) {
$toast.error(`规则ID【${ruleInfo.value.id}】已存在,请替换`)
diff --git a/src/views/setting/AccountSettingRule.vue b/src/views/setting/AccountSettingRule.vue
index 86cd7ad9..eff86ef4 100644
--- a/src/views/setting/AccountSettingRule.vue
+++ b/src/views/setting/AccountSettingRule.vue
@@ -46,6 +46,48 @@ const TorrentPriorityItems = [
{ title: '资源做种数', value: 'seeder' },
]
+// 内置的规则
+const selectFilterOptions = ref<{ [key: string]: string }[]>([
+ { title: '特效字幕', value: ' SPECSUB ' },
+ { title: '中文字幕', value: ' CNSUB ' },
+ { title: '国语配音', value: ' CNVOI ' },
+ { title: '官种', value: ' GZ ' },
+ { title: '排除: 国语配音', value: ' !CNVOI ' },
+ { title: '粤语配音', value: ' HKVOI ' },
+ { title: '排除: 粤语配音', value: ' !HKVOI ' },
+ { title: '促销: 免费', value: ' FREE ' },
+ { title: '分辨率: 4K', value: ' 4K ' },
+ { title: '分辨率: 1080P', value: ' 1080P ' },
+ { title: '分辨率: 720P', value: ' 720P ' },
+ { title: '排除: 720P', value: ' !720P ' },
+ { title: '质量: 蓝光原盘', value: ' BLU ' },
+ { title: '排除: 蓝光原盘', value: ' !BLU ' },
+ { title: '质量: BLURAY', value: ' BLURAY ' },
+ { title: '排除: BLURAY', value: ' !BLURAY ' },
+ { title: '质量: UHD', value: ' UHD ' },
+ { title: '排除: UHD', value: ' !UHD ' },
+ { title: '质量: REMUX', value: ' REMUX ' },
+ { title: '排除: REMUX', value: ' !REMUX ' },
+ { title: '质量: WEB-DL', value: ' WEBDL ' },
+ { title: '排除: WEB-DL', value: ' !WEBDL ' },
+ { title: '质量: 60fps', value: ' 60FPS ' },
+ { title: '排除: 60fps', value: ' !60FPS ' },
+ { title: '编码: H265', value: ' H265 ' },
+ { title: '排除: H265', value: ' !H265 ' },
+ { title: '编码: H264', value: ' H264 ' },
+ { title: '排除: H264', value: ' !H264 ' },
+ { title: '效果: 杜比视界', value: ' DOLBY ' },
+ { title: '排除: 杜比视界', value: ' !DOLBY ' },
+ { title: '效果: 杜比全景声', value: ' ATMOS ' },
+ { title: '排除: 杜比全景声', value: ' !ATMOS ' },
+ { title: '效果: HDR', value: ' HDR ' },
+ { title: '排除: HDR', value: ' !HDR ' },
+ { title: '效果: SDR', value: ' SDR ' },
+ { title: '排除: SDR', value: ' !SDR ' },
+ { title: '效果: 3D', value: ' 3D ' },
+ { title: '排除: 3D', value: ' !3D ' },
+])
+
// 调用API查询自动分类配置
async function loadMediaCategories() {
try {
@@ -67,14 +109,25 @@ const saveCustomRules = debounce(async () => {
$toast.error('存在空名字的规则!无法保存,请修改!')
return
}
- // 检查是否存在重名的规则ID
+ // 获取所有规则ID和名称
const ids = customRules.value.map(item => item.id)
+ const names = customRules.value.map(item => item.name)
+ // 检查是否存在有规则ID是否已经被内置规则使用,如果有则提示,并提示出具体是哪个规则ID
+ if (ids.some(id => selectFilterOptions.value.some(option => option.value === id))) {
+ $toast.error('存在规则ID与内置规则ID重复!无法保存,请修改!')
+ return
+ }
+ // 检查是否存在有规则名称是否已经被内置规则使用,如果有则提示,并提示出具体是哪个规则名称
+ if (names.some(name => selectFilterOptions.value.some(option => option.title === name))) {
+ $toast.error('存在规则名称与内置规则名称重复!无法保存,请修改!')
+ return
+ }
+ // 检查是否存在重名的规则ID
if (new Set(ids).size !== ids.length) {
$toast.error('存在重复规则ID!无法保存,请修改!')
return
}
- // 检查是否存在重名规
- const names = customRules.value.map(item => item.name)
+ // 检查是否存在重名规则名称
if (new Set(names).size !== names.length) {
$toast.error('存在重复规则名称!无法保存,请修改!')
return
From 0fb06529191d89b5c78f7f1eab5340aac5bd75a5 Mon Sep 17 00:00:00 2001
From: Aqr-K <95741669+Aqr-K@users.noreply.github.com>
Date: Thu, 31 Oct 2024 22:55:11 +0800
Subject: [PATCH 17/21] =?UTF-8?q?=E7=BB=9F=E4=B8=80settings=E7=9A=84?=
=?UTF-8?q?=E5=8C=BA=E5=9F=9F=E8=A7=84=E8=8C=83?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/views/setting/AccountSettingDirectory.vue | 2 ++
src/views/setting/AccountSettingRule.vue | 4 ++++
src/views/setting/AccountSettingSearch.vue | 2 ++
src/views/setting/AccountSettingService.vue | 2 ++
src/views/setting/AccountSettingSite.vue | 6 ++++--
src/views/setting/AccountSettingSubscribe.vue | 2 ++
src/views/setting/AccountSettingWords.vue | 6 ++++++
7 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/src/views/setting/AccountSettingDirectory.vue b/src/views/setting/AccountSettingDirectory.vue
index 4c0339c8..381b973d 100644
--- a/src/views/setting/AccountSettingDirectory.vue
+++ b/src/views/setting/AccountSettingDirectory.vue
@@ -172,6 +172,8 @@ onMounted(() => {
+
+
diff --git a/src/views/setting/AccountSettingRule.vue b/src/views/setting/AccountSettingRule.vue
index eff86ef4..9e5a2ec1 100644
--- a/src/views/setting/AccountSettingRule.vue
+++ b/src/views/setting/AccountSettingRule.vue
@@ -376,6 +376,8 @@ onMounted(() => {
+
+
@@ -425,6 +427,8 @@ onMounted(() => {
+
+
diff --git a/src/views/setting/AccountSettingSearch.vue b/src/views/setting/AccountSettingSearch.vue
index a0cad948..fcd4a192 100644
--- a/src/views/setting/AccountSettingSearch.vue
+++ b/src/views/setting/AccountSettingSearch.vue
@@ -183,6 +183,8 @@ onMounted(() => {
+
+
diff --git a/src/views/setting/AccountSettingService.vue b/src/views/setting/AccountSettingService.vue
index 88aae499..dd4391c2 100644
--- a/src/views/setting/AccountSettingService.vue
+++ b/src/views/setting/AccountSettingService.vue
@@ -249,6 +249,8 @@ onDeactivated(() => {
+
+
diff --git a/src/views/setting/AccountSettingSite.vue b/src/views/setting/AccountSettingSite.vue
index d43fa9b5..f6243b94 100644
--- a/src/views/setting/AccountSettingSite.vue
+++ b/src/views/setting/AccountSettingSite.vue
@@ -205,7 +205,8 @@ onMounted(() => {
-
+
+
@@ -232,7 +233,8 @@ onMounted(() => {
-
+
+
diff --git a/src/views/setting/AccountSettingSubscribe.vue b/src/views/setting/AccountSettingSubscribe.vue
index 4be77acf..663749a4 100644
--- a/src/views/setting/AccountSettingSubscribe.vue
+++ b/src/views/setting/AccountSettingSubscribe.vue
@@ -258,6 +258,8 @@ onMounted(() => {
+
+
diff --git a/src/views/setting/AccountSettingWords.vue b/src/views/setting/AccountSettingWords.vue
index cb87bcf0..e9103644 100644
--- a/src/views/setting/AccountSettingWords.vue
+++ b/src/views/setting/AccountSettingWords.vue
@@ -170,6 +170,8 @@ onMounted(() => {
+
+
@@ -194,6 +196,8 @@ onMounted(() => {
+
+
@@ -218,6 +222,8 @@ onMounted(() => {
+
+
From 51deb291453ed52e0b9b40f2fe8d8b29c5d456fc Mon Sep 17 00:00:00 2001
From: Aqr-K <95741669+Aqr-K@users.noreply.github.com>
Date: Sat, 2 Nov 2024 04:51:44 +0800
Subject: [PATCH 18/21] style(aettings): AdvancedSystemSettingsDialog
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 调整开关宽度
---
src/components/dialog/AdvancedSystemSettingsDialog.vue | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/components/dialog/AdvancedSystemSettingsDialog.vue b/src/components/dialog/AdvancedSystemSettingsDialog.vue
index 41e15ab5..41d402e4 100644
--- a/src/components/dialog/AdvancedSystemSettingsDialog.vue
+++ b/src/components/dialog/AdvancedSystemSettingsDialog.vue
@@ -28,7 +28,7 @@ function saveAdvancedSettings() {
-
+
-
+
-
+
Date: Sat, 2 Nov 2024 10:53:02 +0800
Subject: [PATCH 19/21] feat(settings): AccountSettingSearch
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 增加 整合多名称资源搜索结果、下载站点字幕、交互式搜索自动下载用户
---
src/views/setting/AccountSettingSearch.vue | 121 ++++++++++++++++++++-
1 file changed, 117 insertions(+), 4 deletions(-)
diff --git a/src/views/setting/AccountSettingSearch.vue b/src/views/setting/AccountSettingSearch.vue
index fcd4a192..5fd0f713 100644
--- a/src/views/setting/AccountSettingSearch.vue
+++ b/src/views/setting/AccountSettingSearch.vue
@@ -16,6 +16,18 @@ const allSites = ref([])
// 选中订阅站点
const selectedSites = ref([])
+// 系统设置
+const SystemSettings = ref({
+ Basis: {
+
+ },
+ Advanced: {
+ SEARCH_MULTIPLE_NAME: false,
+ DOWNLOAD_SUBTITLE: false,
+ AUTO_DOWNLOAD_USER: '',
+ },
+})
+
// 媒体信息数据源字典
const mediaSourcesDict = [
{
@@ -95,7 +107,7 @@ const saveSelectedSites = debounce(async () => {
}
}, debounceTime)
-// 调用API查询下载器设置
+// 调用API查询设置
async function loadSearchSetting() {
try {
const result1: { [key: string]: any } = await api.get('system/setting/SEARCH_SOURCE')
@@ -121,20 +133,76 @@ const saveSearchSetting = debounce(async () => {
)
if (result1.success && result2.success) {
- $toast.success('保存媒体数据源设置成功')
+ $toast.success('保存设置成功')
+ await reloadSystem()
} else {
- $toast.error('保存媒体数据源设置失败!')
+ $toast.error('保存设置失败!')
}
} catch (error) {
console.log(error)
}
}, debounceTime)
+// 加载系统设置
+async function loadSystemSettings() {
+ try {
+ const result: { [key: string]: any } = await api.get('system/env')
+ if (result.success) {
+ // 将API返回的值赋值给SystemSettings
+ for (const sectionKey of Object.keys(SystemSettings.value) as Array) {
+ Object.keys(SystemSettings.value[sectionKey]).forEach((key: string) => {
+ let v: any
+ if (result.data.hasOwnProperty(key)) {
+ v = result.data[key]
+ // 空字符串转为null,避免空字符串导致前端显示问题
+ if (v === '') {
+ v = null
+ }
+ (SystemSettings.value[sectionKey] as any)[key] = v
+ }
+ })
+ }
+ } else $toast.error('加载设置失败!')
+ } catch (error) {
+ console.log(error)
+ }
+}
+
+// 保存设置
+const saveSystemSettings = debounce(async (value: any) => {
+ try {
+ const result: { [key: string]: any } = await api.post('system/env', value)
+ if (result.success) {
+ $toast.success('保存设置成功')
+ await reloadSystem()
+ await loadSystemSettings()
+ } else {
+ $toast.error('保存设置失败!')
+ }
+ } catch (error) {
+ console.log(error)
+ }
+}, debounceTime)
+
+// 重载系统生效配置
+async function reloadSystem() {
+ try {
+ const result: { [key: string]: any } = await api.get('system/reload')
+ if (result.success) {
+ $toast.success('系统配置已生效')
+ await loadSystemSettings()
+ } else $toast.error('重载系统失败!')
+ } catch (error) {
+ console.log(error)
+ }
+}
+
onMounted(() => {
querySites()
queryFilterRuleGroups()
querySelectedSites()
loadSearchSetting()
+ loadSystemSettings()
})
@@ -155,7 +223,7 @@ onMounted(() => {
clearable
chips
:items="mediaSourcesDict"
- label="媒体数据源"
+ label="媒体搜索数据源"
hint="搜索媒体信息时使用的数据源以及排序"
persistent-hint
/>
@@ -215,4 +283,49 @@ onMounted(() => {
+
+
+
+
+ 高级设置
+ 设置交互搜索自动下载用户ID、字幕。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {}">
+
+ 保存
+
+
+
+
+
+
From 1c4d806e5814353123d89ad8401a80ab70c9c25a Mon Sep 17 00:00:00 2001
From: Aqr-K <95741669+Aqr-K@users.noreply.github.com>
Date: Sat, 2 Nov 2024 10:54:27 +0800
Subject: [PATCH 20/21] feat(settings): add AccountSettingTransfer.vue
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 增加 整理标签页,增加相关设置功能。
---
src/pages/setting.vue | 10 +
src/router/menu.ts | 6 +
src/views/setting/AccountSettingTransfer.vue | 194 +++++++++++++++++++
3 files changed, 210 insertions(+)
create mode 100644 src/views/setting/AccountSettingTransfer.vue
diff --git a/src/pages/setting.vue b/src/pages/setting.vue
index 43899608..4f996d0a 100644
--- a/src/pages/setting.vue
+++ b/src/pages/setting.vue
@@ -12,6 +12,7 @@ import AccountSettingSystem from '@/views/setting/AccountSettingSystem.vue'
import AccountSettingScheduler from '@/views/setting/AccountSettingScheduler.vue'
import AccountSettingDirectory from '@/views/setting/AccountSettingDirectory.vue'
import AccountSettingRule from '@/views/setting/AccountSettingRule.vue'
+import AccountSettingTransfer from "@/views/setting/AccountSettingTransfer.vue"
import { SettingTabs } from '@/router/menu'
const route = useRoute()
@@ -93,6 +94,15 @@ function jumpTab(tab: string) {
+
+
+
+
+
+
+
diff --git a/src/router/menu.ts b/src/router/menu.ts
index 807570e6..7ca7c2ae 100644
--- a/src/router/menu.ts
+++ b/src/router/menu.ts
@@ -167,6 +167,12 @@ export const SettingTabs = [
tab: 'search',
description: '媒体数据源(TheMovieDb、豆瓣、Bangumi)、搜索站点、搜索优先级、默认过滤规则',
},
+ {
+ title: '整理',
+ icon: 'mdi-folder-multiple-outline',
+ tab: 'transfer',
+ description: '转移重命名、刮削来源',
+ },
{
title: '订阅',
icon: 'mdi-rss',
diff --git a/src/views/setting/AccountSettingTransfer.vue b/src/views/setting/AccountSettingTransfer.vue
new file mode 100644
index 00000000..62028f82
--- /dev/null
+++ b/src/views/setting/AccountSettingTransfer.vue
@@ -0,0 +1,194 @@
+
+
+
+
+
+
+
+ 基础设置
+ 设置通用的整理转移功能。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Jinja2语法参考:
+
+ https://jinja.palletsprojects.com/en/3.0.x/templates
+
+
+
+
+
+
+ {}">
+
+ 保存
+
+
+
+
+
+
+
+
From 9cbafdfab85c9b1ecdef1886bbb4f606641818f7 Mon Sep 17 00:00:00 2001
From: Aqr-K <95741669+Aqr-K@users.noreply.github.com>
Date: Sun, 3 Nov 2024 18:28:07 +0800
Subject: [PATCH 21/21] feat(user): Add file type check and size determination
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 增加 文件类型检查
- 增加 文件大小限制,800KB
---
src/components/dialog/UserAddEditDialog.vue | 18 ++++++++++++++++--
src/views/user/UserProfileView.vue | 18 +++++++++++++++---
2 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/src/components/dialog/UserAddEditDialog.vue b/src/components/dialog/UserAddEditDialog.vue
index e732831c..cf42e778 100644
--- a/src/components/dialog/UserAddEditDialog.vue
+++ b/src/components/dialog/UserAddEditDialog.vue
@@ -82,10 +82,24 @@ function changeAvatar(file: Event) {
const fileReader = new FileReader()
const { files } = file.target as HTMLInputElement
if (files && files.length > 0) {
- fileReader.readAsDataURL(files[0])
+ const selectedFile = files[0]
+ const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
+ const maxSize = 800 * 1024
+ // 检查文件是否为图片
+ if (!allowedTypes.includes(selectedFile.type)) {
+ $toast.error('上传的文件不符合要求,请重新选择头像');
+ return;
+ }
+ // 检查文件大小
+ if (selectedFile.size > maxSize) {
+ $toast.error('文件大小不得大于800KB')
+ return
+ }
+ fileReader.readAsDataURL(selectedFile)
fileReader.onload = () => {
if (typeof fileReader.result === 'string') {
currentAvatar.value = fileReader.result
+ $toast.success('新头像上传成功,待保存后生效!')
}
}
}
@@ -289,7 +303,7 @@ onMounted(() => {
- 允许 JPG、PNG、GIF 格式, 最大尺寸 800K。
+ 允许 JPG、PNG、GIF 格式, 最大尺寸 800KB。
diff --git a/src/views/user/UserProfileView.vue b/src/views/user/UserProfileView.vue
index 13b42ba8..f65bb5c0 100644
--- a/src/views/user/UserProfileView.vue
+++ b/src/views/user/UserProfileView.vue
@@ -73,9 +73,21 @@ const qrCode = ref('')
function changeAvatar(file: Event) {
const fileReader = new FileReader()
const { files } = file.target as HTMLInputElement
-
if (files && files.length > 0) {
- fileReader.readAsDataURL(files[0])
+ const selectedFile = files[0]
+ const allowedTypes = ['image/jpeg', 'image/png', 'image/gif']
+ const maxSize = 800 * 1024
+ // 检查文件是否为图片
+ if (!allowedTypes.includes(selectedFile.type)) {
+ $toast.error('上传的文件不符合要求,请重新选择头像');
+ return;
+ }
+ // 检查文件大小
+ if (selectedFile.size > maxSize) {
+ $toast.error('文件大小不得大于800KB')
+ return
+ }
+ fileReader.readAsDataURL(selectedFile)
fileReader.onload = () => {
if (typeof fileReader.result === 'string') {
currentAvatar.value = fileReader.result
@@ -285,7 +297,7 @@ watch(
- 允许 JPG、PNG、GIF 格式, 最大尺寸 800K。
+ 允许 JPG、PNG、GIF 格式, 最大尺寸 800KB。