mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 23:56:42 +08:00
更新国际化支持:在多个组件中引入 vue-i18n,优化文本翻译和结构
This commit is contained in:
+51
-38
@@ -387,6 +387,7 @@ export default {
|
|||||||
currentVersion: 'Current Version',
|
currentVersion: 'Current Version',
|
||||||
viewChangelog: 'View Changelog',
|
viewChangelog: 'View Changelog',
|
||||||
changelog: 'Changelog',
|
changelog: 'Changelog',
|
||||||
|
dataDirectory: '/moviepilot',
|
||||||
},
|
},
|
||||||
system: {
|
system: {
|
||||||
basicSettings: 'Basic Settings',
|
basicSettings: 'Basic Settings',
|
||||||
@@ -439,6 +440,11 @@ export default {
|
|||||||
copyFailed: 'Copy failed: browser may not support or user blocked!',
|
copyFailed: 'Copy failed: browser may not support or user blocked!',
|
||||||
copyError: 'Copy failed!',
|
copyError: 'Copy failed!',
|
||||||
reloading: 'Applying configuration...',
|
reloading: 'Applying configuration...',
|
||||||
|
qbittorrent: 'Qbittorrent',
|
||||||
|
transmission: 'Transmission',
|
||||||
|
emby: 'Emby',
|
||||||
|
jellyfin: 'Jellyfin',
|
||||||
|
plex: 'Plex',
|
||||||
},
|
},
|
||||||
site: {
|
site: {
|
||||||
siteSync: 'Site Synchronization',
|
siteSync: 'Site Synchronization',
|
||||||
@@ -517,6 +523,11 @@ export default {
|
|||||||
manualProcess: 'Manual Process',
|
manualProcess: 'Manual Process',
|
||||||
plugin: 'Plugin',
|
plugin: 'Plugin',
|
||||||
other: 'Other',
|
other: 'Other',
|
||||||
|
telegram: 'Telegram',
|
||||||
|
slack: 'Slack',
|
||||||
|
synologyChat: 'SynologyChat',
|
||||||
|
voceChat: 'VoceChat',
|
||||||
|
webPush: 'WebPush',
|
||||||
},
|
},
|
||||||
words: {
|
words: {
|
||||||
customIdentifiers: 'Custom Identifiers',
|
customIdentifiers: 'Custom Identifiers',
|
||||||
@@ -586,11 +597,16 @@ export default {
|
|||||||
downloadUser: 'Remote Search Auto Download User List',
|
downloadUser: 'Remote Search Auto Download User List',
|
||||||
downloadUserHint:
|
downloadUserHint:
|
||||||
'Whether to automatically download when searching with Telegram, WeChat, etc., comma separated, set to all to represent all users auto-download',
|
'Whether to automatically download when searching with Telegram, WeChat, etc., comma separated, set to all to represent all users auto-download',
|
||||||
|
downloadUserPlaceholder: 'UserID1,UserID2',
|
||||||
multipleNameSearch: 'Multiple Name Resource Search',
|
multipleNameSearch: 'Multiple Name Resource Search',
|
||||||
multipleNameSearchHint:
|
multipleNameSearchHint:
|
||||||
'Search site resources using multiple names (Chinese, English, etc.) and merge search results, will increase site access frequency',
|
'Search site resources using multiple names (Chinese, English, etc.) and merge search results, will increase site access frequency',
|
||||||
downloadSubtitle: 'Download Site Subtitles',
|
downloadSubtitle: 'Download Site Subtitles',
|
||||||
downloadSubtitleHint: 'Check if site resources have separate subtitle files and download them automatically',
|
downloadSubtitleHint: 'Check if site resources have separate subtitle files and download them automatically',
|
||||||
|
mediaSource: 'Media Search Data Source',
|
||||||
|
mediaSourceHint: 'Data sources and sorting used when searching for media information',
|
||||||
|
filterRuleGroupHint: 'Filter results by selected filter rule groups when searching for media information',
|
||||||
|
downloadLabelPlaceholder: 'MOVIEPILOT',
|
||||||
},
|
},
|
||||||
directory: {
|
directory: {
|
||||||
storage: 'Storage',
|
storage: 'Storage',
|
||||||
@@ -620,24 +636,29 @@ export default {
|
|||||||
priorityRuleGroups: 'Priority Rule Groups',
|
priorityRuleGroups: 'Priority Rule Groups',
|
||||||
priorityRuleGroupsDesc: 'Preset priority rule groups for use in search and subscription.',
|
priorityRuleGroupsDesc: 'Preset priority rule groups for use in search and subscription.',
|
||||||
downloadRules: 'Download Rules',
|
downloadRules: 'Download Rules',
|
||||||
downloadRulesDesc: 'Prioritize downloads when multiple resources match.',
|
downloadRulesDesc: 'Choose the best option when multiple resources are matched.',
|
||||||
|
resourcePriority: 'Resource Priority',
|
||||||
|
sitePriority: 'Site Priority',
|
||||||
|
siteUpload: 'Site Upload',
|
||||||
|
resourceSeeder: 'Resource Seeders',
|
||||||
|
emptyIdError: 'A rule has an empty ID, cannot save. Please modify!',
|
||||||
|
emptyNameError: 'A rule has an empty name, cannot save. Please modify!',
|
||||||
|
duplicateIdError: 'Duplicate rule IDs exist! Cannot save, please modify!',
|
||||||
|
duplicateNameError: 'Duplicate rule names exist! Cannot save, please modify!',
|
||||||
|
customRuleSaveSuccess: 'Custom rules saved successfully',
|
||||||
|
customRuleSaveFailed: 'Failed to save custom rules!',
|
||||||
|
emptyGroupNameError: 'A rule group has an empty name! Cannot save, please modify!',
|
||||||
|
duplicateGroupNameError: 'Duplicate rule group names exist! Cannot save, please modify!',
|
||||||
|
ruleGroupSaveSuccess: 'Priority rule groups saved successfully',
|
||||||
|
ruleGroupSaveFailed: 'Failed to save priority rule groups!',
|
||||||
|
customRuleCopySuccess: 'Custom rules copied to clipboard!',
|
||||||
|
customRuleCopyFailed: 'Failed to copy custom rules: browser may not support or user blocked!',
|
||||||
|
customRuleCopyError: 'Failed to copy custom rules!',
|
||||||
|
ruleGroupCopySuccess: 'Priority rule groups copied to clipboard!',
|
||||||
|
ruleGroupCopyFailed: 'Failed to copy priority rule groups: browser may not support or user blocked!',
|
||||||
|
ruleGroupCopyError: 'Failed to copy priority rule groups!',
|
||||||
currentPriorityRules: 'Current Download Priority Rules',
|
currentPriorityRules: 'Current Download Priority Rules',
|
||||||
currentPriorityRulesHint: 'Higher priority for items at the front, unselected items are not included in sorting',
|
currentPriorityRulesHint: 'Higher priority for items at the front, unselected items are not included in sorting',
|
||||||
saveSuccess: 'Custom rules saved successfully',
|
|
||||||
saveFailed: 'Failed to save custom rules!',
|
|
||||||
groupSaveSuccess: 'Priority rule groups saved successfully',
|
|
||||||
groupSaveFailed: 'Failed to save priority rule groups!',
|
|
||||||
prioritySaveSuccess: 'Priority rules saved successfully',
|
|
||||||
prioritySaveFailed: 'Failed to save priority rules!',
|
|
||||||
emptyRuleId: 'Rules with empty IDs exist! Cannot save, please modify!',
|
|
||||||
emptyRuleName: 'Rules with empty names exist! Cannot save, please modify!',
|
|
||||||
duplicateRuleId: 'Duplicate rule IDs exist! Cannot save, please modify!',
|
|
||||||
duplicateRuleName: 'Duplicate rule names exist! Cannot save, please modify!',
|
|
||||||
emptyGroupName: 'Rule groups with empty names exist! Cannot save, please modify!',
|
|
||||||
duplicateGroupName: 'Duplicate rule group names exist! Cannot save, please modify!',
|
|
||||||
copySuccess: 'Copied to clipboard!',
|
|
||||||
copyFailed: 'Copy failed: browser may not support or user blocked!',
|
|
||||||
copyError: 'Copy failed!',
|
|
||||||
importCustomRules: 'Import Custom Rules',
|
importCustomRules: 'Import Custom Rules',
|
||||||
importRuleGroups: 'Import Priority Rule Groups',
|
importRuleGroups: 'Import Priority Rule Groups',
|
||||||
importFailed: 'Failed to import rules! Cannot parse input data!',
|
importFailed: 'Failed to import rules! Cannot parse input data!',
|
||||||
@@ -645,33 +666,27 @@ export default {
|
|||||||
duplicateValue: 'Duplicate values exist',
|
duplicateValue: 'Duplicate values exist',
|
||||||
importNoId: 'Import failed! Found rules without IDs, may belong to priority rule groups!',
|
importNoId: 'Import failed! Found rules without IDs, may belong to priority rule groups!',
|
||||||
importHasId: 'Import failed! Found rules with IDs, may belong to custom rules!',
|
importHasId: 'Import failed! Found rules with IDs, may belong to custom rules!',
|
||||||
torrentPriority: {
|
|
||||||
torrent: 'Resource Priority',
|
|
||||||
site: 'Site Priority',
|
|
||||||
upload: 'Site Upload Amount',
|
|
||||||
seeder: 'Resource Seeders',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
scheduler: {
|
scheduler: {
|
||||||
scheduledTasks: 'Scheduled Tasks',
|
title: 'Scheduled Jobs',
|
||||||
scheduledTasksDesc:
|
subtitle:
|
||||||
'Includes system built-in services and plugin-provided services. Manual execution will not affect the normal schedule of tasks.',
|
"Includes built-in system services and plugin services. Manual execution will not affect the job's normal schedule.",
|
||||||
provider: 'Provider',
|
provider: 'Provider',
|
||||||
taskName: 'Task Name',
|
taskName: 'Task Name',
|
||||||
taskStatus: 'Task Status',
|
taskStatus: 'Task Status',
|
||||||
nextRunTime: 'Next Run Time',
|
nextRunTime: 'Next Run Time',
|
||||||
execute: 'Execute',
|
execute: 'Execute',
|
||||||
noServices: 'No background services',
|
noService: 'No background services',
|
||||||
submitSuccess: 'Task execution request submitted successfully!',
|
running: 'Running',
|
||||||
status: {
|
stopped: 'Stopped',
|
||||||
running: 'Running',
|
waiting: 'Waiting',
|
||||||
stopped: 'Stopped',
|
executeSuccess: 'Scheduled job execution request submitted successfully!',
|
||||||
waiting: 'Waiting',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
subscribe: {
|
subscribe: {
|
||||||
basicSettings: 'Basic Settings',
|
basicSettings: 'Basic Settings',
|
||||||
basicSettingsDesc: 'Set subscription mode, cycle and other basic settings',
|
basicSettingsDesc: 'Set subscription mode, cycle and other basic settings',
|
||||||
|
subscribeSites: 'Subscribe Sites',
|
||||||
|
subscribeSitesDesc: 'Only selected sites will be used in subscriptions.',
|
||||||
mode: 'Subscription Mode',
|
mode: 'Subscription Mode',
|
||||||
modeHint: 'Auto: automatically crawl site homepage, Site RSS: subscribe via site RSS link',
|
modeHint: 'Auto: automatically crawl site homepage, Site RSS: subscribe via site RSS link',
|
||||||
rssInterval: 'Site RSS Interval',
|
rssInterval: 'Site RSS Interval',
|
||||||
@@ -684,12 +699,6 @@ export default {
|
|||||||
timedSearchHint: 'Search all sites every 24 hours to supplement resources that may be missed by subscription',
|
timedSearchHint: 'Search all sites every 24 hours to supplement resources that may be missed by subscription',
|
||||||
checkLocalMedia: 'Check Local Media Library',
|
checkLocalMedia: 'Check Local Media Library',
|
||||||
checkLocalMediaHint: 'Check if resources exist on storage disk to avoid duplicate downloads',
|
checkLocalMediaHint: 'Check if resources exist on storage disk to avoid duplicate downloads',
|
||||||
subscribeSites: 'Subscription Sites',
|
|
||||||
subscribeSitesDesc: 'Only selected sites will be used in subscription.',
|
|
||||||
saveSuccess: 'Subscription sites saved successfully',
|
|
||||||
saveFailed: 'Failed to save subscription sites!',
|
|
||||||
settingsSaveSuccess: 'Subscription basic settings saved successfully',
|
|
||||||
settingsSaveFailed: 'Failed to save subscription basic settings!',
|
|
||||||
modes: {
|
modes: {
|
||||||
auto: 'Auto',
|
auto: 'Auto',
|
||||||
rss: 'Site RSS',
|
rss: 'Site RSS',
|
||||||
@@ -703,6 +712,10 @@ export default {
|
|||||||
hour12: '12 hours',
|
hour12: '12 hours',
|
||||||
day1: '1 day',
|
day1: '1 day',
|
||||||
},
|
},
|
||||||
|
saveSuccess: 'Subscription sites saved successfully',
|
||||||
|
saveFailed: 'Failed to save subscription sites!',
|
||||||
|
settingsSaveSuccess: 'Subscription basic settings saved successfully',
|
||||||
|
settingsSaveFailed: 'Failed to save subscription basic settings!',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
+91
-77
@@ -326,47 +326,6 @@ export default {
|
|||||||
site: {
|
site: {
|
||||||
noSites: '没有站点',
|
noSites: '没有站点',
|
||||||
sitesWillBeShownHere: '已添加并支持的站点将会在这里显示。',
|
sitesWillBeShownHere: '已添加并支持的站点将会在这里显示。',
|
||||||
siteSync: '站点同步',
|
|
||||||
siteSyncDesc: '从CookieCloud快速同步站点数据。',
|
|
||||||
enableLocalCookieCloud: '启用本地CookieCloud服务器',
|
|
||||||
enableLocalCookieCloudHint: '使用内建CookieCloud服务同步站点数据,服务地址为:http://localhost:3000/cookiecloud',
|
|
||||||
serviceAddress: '服务地址',
|
|
||||||
serviceAddressPlaceholder: 'https://movie-pilot.org/cookiecloud',
|
|
||||||
serviceAddressHint: '远端CookieCloud服务地址,格式:https://movie-pilot.org/cookiecloud',
|
|
||||||
userKey: '用户KEY',
|
|
||||||
userKeyHint: 'CookieCloud浏览器插件生成的用户KEY',
|
|
||||||
e2ePassword: '端对端加密密码',
|
|
||||||
e2ePasswordHint: 'CookieCloud浏览器插件生成的端对端加密密码',
|
|
||||||
autoSyncInterval: '自动同步间隔',
|
|
||||||
autoSyncIntervalHint: '从CookieCloud服务器自动同步站点Cookie到MoviePilot的时间间隔',
|
|
||||||
syncBlacklist: '同步域名黑名单',
|
|
||||||
syncBlacklistPlaceholder: '多个域名,分割',
|
|
||||||
syncBlacklistHint: 'CookieCloud同步域名黑名单,多个域名,分割',
|
|
||||||
userAgent: '浏览器User-Agent',
|
|
||||||
userAgentHint: 'CookieCloud插件所在的浏览器的User-Agent',
|
|
||||||
siteDataRefresh: '站点数据刷新',
|
|
||||||
siteDataRefreshInterval: '站点数据刷新间隔',
|
|
||||||
siteDataRefreshIntervalHint: '刷新站点用户上传下载等数据的时间间隔',
|
|
||||||
readSiteMessage: '阅读站点消息',
|
|
||||||
readSiteMessageHint: '刷新数据时读取站点消息并发送通知',
|
|
||||||
siteReset: '站点重置',
|
|
||||||
confirmReset: '确认删除所有站点数据并重新同步。',
|
|
||||||
confirmResetHint: '删除所有站点数据并重新从CookieCloud同步,操作请先清空涉及站点的相关设置。',
|
|
||||||
resetSites: '重置站点数据',
|
|
||||||
resettingSites: '正在重置...',
|
|
||||||
syncInterval: {
|
|
||||||
hourly: '每小时',
|
|
||||||
every6Hours: '每6小时',
|
|
||||||
every12Hours: '每12小时',
|
|
||||||
daily: '每天',
|
|
||||||
weekly: '每周',
|
|
||||||
monthly: '每月',
|
|
||||||
never: '永不',
|
|
||||||
},
|
|
||||||
saveSuccess: '保存站点设置成功',
|
|
||||||
saveFailed: '站点设置保存失败!',
|
|
||||||
resetSuccess: '站点重置成功,请等待CookieCloud同步完成!',
|
|
||||||
resetFailed: '站点重置失败!',
|
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
loadMore: '加载更多',
|
loadMore: '加载更多',
|
||||||
@@ -426,6 +385,7 @@ export default {
|
|||||||
currentVersion: '当前版本',
|
currentVersion: '当前版本',
|
||||||
viewChangelog: '查看变更日志',
|
viewChangelog: '查看变更日志',
|
||||||
changelog: '变更日志',
|
changelog: '变更日志',
|
||||||
|
dataDirectory: '/moviepilot',
|
||||||
},
|
},
|
||||||
system: {
|
system: {
|
||||||
basicSettings: '基础设置',
|
basicSettings: '基础设置',
|
||||||
@@ -478,6 +438,54 @@ export default {
|
|||||||
copyFailed: '复制失败:可能是浏览器不支持或被用户阻止!',
|
copyFailed: '复制失败:可能是浏览器不支持或被用户阻止!',
|
||||||
copyError: '复制失败!',
|
copyError: '复制失败!',
|
||||||
reloading: '正在应用配置...',
|
reloading: '正在应用配置...',
|
||||||
|
qbittorrent: 'Qbittorrent',
|
||||||
|
transmission: 'Transmission',
|
||||||
|
emby: 'Emby',
|
||||||
|
jellyfin: 'Jellyfin',
|
||||||
|
plex: 'Plex',
|
||||||
|
},
|
||||||
|
site: {
|
||||||
|
siteSync: '站点同步',
|
||||||
|
siteSyncDesc: '从CookieCloud快速同步站点数据。',
|
||||||
|
enableLocalCookieCloud: '启用本地CookieCloud服务器',
|
||||||
|
enableLocalCookieCloudHint: '使用内建CookieCloud服务同步站点数据,服务地址为:http://localhost:3000/cookiecloud',
|
||||||
|
serviceAddress: '服务地址',
|
||||||
|
serviceAddressPlaceholder: 'https://movie-pilot.org/cookiecloud',
|
||||||
|
serviceAddressHint: '远端CookieCloud服务地址,格式:https://movie-pilot.org/cookiecloud',
|
||||||
|
userKey: '用户KEY',
|
||||||
|
userKeyHint: 'CookieCloud浏览器插件生成的用户KEY',
|
||||||
|
e2ePassword: '端对端加密密码',
|
||||||
|
e2ePasswordHint: 'CookieCloud浏览器插件生成的端对端加密密码',
|
||||||
|
autoSyncInterval: '自动同步间隔',
|
||||||
|
autoSyncIntervalHint: '从CookieCloud服务器自动同步站点Cookie到MoviePilot的时间间隔',
|
||||||
|
syncBlacklist: '同步域名黑名单',
|
||||||
|
syncBlacklistPlaceholder: '多个域名,分割',
|
||||||
|
syncBlacklistHint: 'CookieCloud同步域名黑名单,多个域名,分割',
|
||||||
|
userAgent: '浏览器User-Agent',
|
||||||
|
userAgentHint: 'CookieCloud插件所在的浏览器的User-Agent',
|
||||||
|
siteDataRefresh: '站点数据刷新',
|
||||||
|
siteDataRefreshInterval: '站点数据刷新间隔',
|
||||||
|
siteDataRefreshIntervalHint: '刷新站点用户上传下载等数据的时间间隔',
|
||||||
|
readSiteMessage: '阅读站点消息',
|
||||||
|
readSiteMessageHint: '刷新数据时读取站点消息并发送通知',
|
||||||
|
siteReset: '站点重置',
|
||||||
|
confirmReset: '确认删除所有站点数据并重新同步。',
|
||||||
|
confirmResetHint: '删除所有站点数据并重新从CookieCloud同步,操作请先清空涉及站点的相关设置。',
|
||||||
|
resetSites: '重置站点数据',
|
||||||
|
resettingSites: '正在重置...',
|
||||||
|
syncInterval: {
|
||||||
|
hourly: '每小时',
|
||||||
|
every6Hours: '每6小时',
|
||||||
|
every12Hours: '每12小时',
|
||||||
|
daily: '每天',
|
||||||
|
weekly: '每周',
|
||||||
|
monthly: '每月',
|
||||||
|
never: '永不',
|
||||||
|
},
|
||||||
|
saveSuccess: '保存站点设置成功',
|
||||||
|
saveFailed: '站点设置保存失败!',
|
||||||
|
resetSuccess: '站点重置成功,请等待CookieCloud同步完成!',
|
||||||
|
resetFailed: '站点重置失败!',
|
||||||
},
|
},
|
||||||
notification: {
|
notification: {
|
||||||
channels: '通知渠道',
|
channels: '通知渠道',
|
||||||
@@ -510,6 +518,11 @@ export default {
|
|||||||
manualProcess: '手动处理',
|
manualProcess: '手动处理',
|
||||||
plugin: '插件',
|
plugin: '插件',
|
||||||
other: '其它',
|
other: '其它',
|
||||||
|
telegram: 'Telegram',
|
||||||
|
slack: 'Slack',
|
||||||
|
synologyChat: 'SynologyChat',
|
||||||
|
voceChat: 'VoceChat',
|
||||||
|
webPush: 'WebPush',
|
||||||
},
|
},
|
||||||
words: {
|
words: {
|
||||||
customIdentifiers: '自定义识别词',
|
customIdentifiers: '自定义识别词',
|
||||||
@@ -572,12 +585,16 @@ export default {
|
|||||||
tvCategory: '电视剧',
|
tvCategory: '电视剧',
|
||||||
animeCategory: '动漫',
|
animeCategory: '动漫',
|
||||||
downloadUser: '远程搜索自动下载用户',
|
downloadUser: '远程搜索自动下载用户',
|
||||||
downloadUserHint:
|
|
||||||
'使用Telegram、微信等远程搜索时是否自动下载,多个用户使用英文逗号分隔,设置为all代表所有用户自动下载',
|
|
||||||
multipleNameSearch: '多名称资源搜索',
|
multipleNameSearch: '多名称资源搜索',
|
||||||
multipleNameSearchHint: '使用多个名称(中文、英文等)搜索站点资源并合并搜索结果,会增加站点访问频率',
|
multipleNameSearchHint: '使用多个名称(中文、英文等)搜索站点资源并合并搜索结果,会增加站点访问频率',
|
||||||
downloadSubtitle: '下载站点字幕',
|
downloadSubtitle: '下载站点字幕',
|
||||||
downloadSubtitleHint: '检查站点资源是否有单独的字幕文件并自动下载',
|
downloadSubtitleHint: '检查站点资源是否有单独的字幕文件并自动下载',
|
||||||
|
mediaSource: '媒体搜索数据源',
|
||||||
|
mediaSourceHint: '搜索媒体信息时使用的数据源以及排序',
|
||||||
|
filterRuleGroupHint: '搜索媒体信息时按选定的过滤规则组对结果进行过滤',
|
||||||
|
downloadUserPlaceholder: '用户ID1,用户ID2',
|
||||||
|
downloadUserHint: '使用Telegram、微信等搜索时是否自动下载,使用逗号分割,设置为 all 代表所有用户自动择优下载',
|
||||||
|
downloadLabelPlaceholder: 'MOVIEPILOT',
|
||||||
},
|
},
|
||||||
directory: {
|
directory: {
|
||||||
storage: '存储',
|
storage: '存储',
|
||||||
@@ -607,23 +624,28 @@ export default {
|
|||||||
priorityRuleGroupsDesc: '预设优先级规则组,以便在搜索和订阅中使用。',
|
priorityRuleGroupsDesc: '预设优先级规则组,以便在搜索和订阅中使用。',
|
||||||
downloadRules: '下载规则',
|
downloadRules: '下载规则',
|
||||||
downloadRulesDesc: '同时命中多个资源时择优下载。',
|
downloadRulesDesc: '同时命中多个资源时择优下载。',
|
||||||
|
resourcePriority: '资源优先级',
|
||||||
|
sitePriority: '站点优先级',
|
||||||
|
siteUpload: '站点上传量',
|
||||||
|
resourceSeeder: '资源做种数',
|
||||||
|
emptyIdError: '存在空ID的规则,无法保存,请修改!',
|
||||||
|
emptyNameError: '存在空名字的规则,无法保存,请修改!',
|
||||||
|
duplicateIdError: '存在重复规则ID!无法保存,请修改!',
|
||||||
|
duplicateNameError: '存在重复规则名称!无法保存,请修改!',
|
||||||
|
customRuleSaveSuccess: '自定义规则保存成功',
|
||||||
|
customRuleSaveFailed: '自定义规则保存失败!',
|
||||||
|
emptyGroupNameError: '存在空名字的规则组!无法保存,请修改!',
|
||||||
|
duplicateGroupNameError: '存在重复规则组名称!无法保存,请修改!',
|
||||||
|
ruleGroupSaveSuccess: '优先级规则组保存成功',
|
||||||
|
ruleGroupSaveFailed: '优先级规则组保存失败!',
|
||||||
|
customRuleCopySuccess: '自定义规则已复制到剪贴板!',
|
||||||
|
customRuleCopyFailed: '自定义规则复制失败:可能是浏览器不支持或被用户阻止!',
|
||||||
|
customRuleCopyError: '自定义规则复制失败!',
|
||||||
|
ruleGroupCopySuccess: '优先级规则组已复制到剪贴板!',
|
||||||
|
ruleGroupCopyFailed: '优先级规则组复制失败:可能是浏览器不支持或被用户阻止!',
|
||||||
|
ruleGroupCopyError: '优先级规则组复制失败!',
|
||||||
currentPriorityRules: '当前使用下载优先规则',
|
currentPriorityRules: '当前使用下载优先规则',
|
||||||
currentPriorityRulesHint: '排在前面的优先级越高,未选择的项不纳入排序',
|
currentPriorityRulesHint: '排在前面的优先级越高,未选择的项不纳入排序',
|
||||||
saveSuccess: '自定义规则保存成功',
|
|
||||||
saveFailed: '自定义规则保存失败!',
|
|
||||||
groupSaveSuccess: '优先级规则组保存成功',
|
|
||||||
groupSaveFailed: '优先级规则组保存失败!',
|
|
||||||
prioritySaveSuccess: '优先规则保存成功',
|
|
||||||
prioritySaveFailed: '优先规则保存失败!',
|
|
||||||
emptyRuleId: '存在空ID的规则,无法保存,请修改!',
|
|
||||||
emptyRuleName: '存在空名字的规则,无法保存,请修改!',
|
|
||||||
duplicateRuleId: '存在重复规则ID!无法保存,请修改!',
|
|
||||||
duplicateRuleName: '存在重复规则名称!无法保存,请修改!',
|
|
||||||
emptyGroupName: '存在空名字的规则组!无法保存,请修改!',
|
|
||||||
duplicateGroupName: '存在重复规则组名称!无法保存,请修改!',
|
|
||||||
copySuccess: '已复制到剪贴板!',
|
|
||||||
copyFailed: '复制失败:可能是浏览器不支持或被用户阻止!',
|
|
||||||
copyError: '复制失败!',
|
|
||||||
importCustomRules: '导入自定义规则',
|
importCustomRules: '导入自定义规则',
|
||||||
importRuleGroups: '导入优先级规则组',
|
importRuleGroups: '导入优先级规则组',
|
||||||
importFailed: '导入规则失败!无法解析输入的数据!',
|
importFailed: '导入规则失败!无法解析输入的数据!',
|
||||||
@@ -631,12 +653,6 @@ export default {
|
|||||||
duplicateValue: '存在重名值',
|
duplicateValue: '存在重名值',
|
||||||
importNoId: '导入失败!发现有规则不存在ID,可能属于优先级规则组!',
|
importNoId: '导入失败!发现有规则不存在ID,可能属于优先级规则组!',
|
||||||
importHasId: '导入失败!发现有规则存在相同ID,可能属于自定义规则!',
|
importHasId: '导入失败!发现有规则存在相同ID,可能属于自定义规则!',
|
||||||
torrentPriority: {
|
|
||||||
torrent: '资源优先级',
|
|
||||||
site: '站点优先级',
|
|
||||||
upload: '站点上传量',
|
|
||||||
seeder: '资源做种数',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
scheduler: {
|
scheduler: {
|
||||||
scheduledTasks: '定时作业',
|
scheduledTasks: '定时作业',
|
||||||
@@ -646,17 +662,17 @@ export default {
|
|||||||
taskStatus: '任务状态',
|
taskStatus: '任务状态',
|
||||||
nextRunTime: '下一次执行时间',
|
nextRunTime: '下一次执行时间',
|
||||||
execute: '执行',
|
execute: '执行',
|
||||||
noServices: '没有后台服务',
|
noService: '没有后台服务',
|
||||||
submitSuccess: '定时作业执行请求提交成功!',
|
running: '正在运行',
|
||||||
status: {
|
stopped: '已停止',
|
||||||
running: '正在运行',
|
waiting: '等待',
|
||||||
stopped: '已停止',
|
executeSuccess: '定时作业执行请求提交成功!',
|
||||||
waiting: '等待',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
subscribe: {
|
subscribe: {
|
||||||
basicSettings: '基础设置',
|
basicSettings: '基础设置',
|
||||||
basicSettingsDesc: '设定订阅模式、周期等基础设置',
|
basicSettingsDesc: '设定订阅模式、周期等基础设置',
|
||||||
|
subscribeSites: '订阅站点',
|
||||||
|
subscribeSitesDesc: '只有选中的站点才会在订阅中使用。',
|
||||||
mode: '订阅模式',
|
mode: '订阅模式',
|
||||||
modeHint: '自动:自动爬取站点首页,站点RSS:通过站点RSS链接订阅',
|
modeHint: '自动:自动爬取站点首页,站点RSS:通过站点RSS链接订阅',
|
||||||
rssInterval: '站点RSS周期',
|
rssInterval: '站点RSS周期',
|
||||||
@@ -669,12 +685,6 @@ export default {
|
|||||||
timedSearchHint: '每隔24小时全站搜索,以补全订阅可能漏掉的资源',
|
timedSearchHint: '每隔24小时全站搜索,以补全订阅可能漏掉的资源',
|
||||||
checkLocalMedia: '检查本地媒体库资源',
|
checkLocalMedia: '检查本地媒体库资源',
|
||||||
checkLocalMediaHint: '检查存储盘是否存在资源,以避免重复下载',
|
checkLocalMediaHint: '检查存储盘是否存在资源,以避免重复下载',
|
||||||
subscribeSites: '订阅站点',
|
|
||||||
subscribeSitesDesc: '只有选中的站点才会在订阅中使用。',
|
|
||||||
saveSuccess: '订阅站点保存成功',
|
|
||||||
saveFailed: '订阅站点保存失败!',
|
|
||||||
settingsSaveSuccess: '订阅基础设置保存成功',
|
|
||||||
settingsSaveFailed: '订阅基础设置保存失败!',
|
|
||||||
modes: {
|
modes: {
|
||||||
auto: '自动',
|
auto: '自动',
|
||||||
rss: '站点RSS',
|
rss: '站点RSS',
|
||||||
@@ -688,6 +698,10 @@ export default {
|
|||||||
hour12: '12小时',
|
hour12: '12小时',
|
||||||
day1: '1天',
|
day1: '1天',
|
||||||
},
|
},
|
||||||
|
saveSuccess: '订阅站点保存成功',
|
||||||
|
saveFailed: '订阅站点保存失败!',
|
||||||
|
settingsSaveSuccess: '订阅基础设置保存成功',
|
||||||
|
settingsSaveFailed: '订阅基础设置保存失败!',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,9 @@ onMounted(() => {
|
|||||||
<div class="max-w-6xl py-4 sm:grid sm:grid-cols-3 sm:gap-4">
|
<div class="max-w-6xl py-4 sm:grid sm:grid-cols-3 sm:gap-4">
|
||||||
<dt class="block text-sm font-bold">{{ t('setting.about.dataDir') }}</dt>
|
<dt class="block text-sm font-bold">{{ t('setting.about.dataDir') }}</dt>
|
||||||
<dd class="flex text-sm sm:col-span-2 sm:mt-0">
|
<dd class="flex text-sm sm:col-span-2 sm:mt-0">
|
||||||
<span class="flex-grow undefined"><code>/moviepilot</code></span>
|
<span class="flex-grow undefined"
|
||||||
|
><code>{{ t('setting.about.dataDirectory') }}</code></span
|
||||||
|
>
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ import { TransferDirectoryConf, StorageConf } from '@/api/types'
|
|||||||
import DirectoryCard from '@/components/cards/DirectoryCard.vue'
|
import DirectoryCard from '@/components/cards/DirectoryCard.vue'
|
||||||
import StorageCard from '@/components/cards/StorageCard.vue'
|
import StorageCard from '@/components/cards/StorageCard.vue'
|
||||||
import ProgressDialog from '@/components/dialog/ProgressDialog.vue'
|
import ProgressDialog from '@/components/dialog/ProgressDialog.vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
// 所有下载目录
|
// 所有下载目录
|
||||||
const directories = ref<TransferDirectoryConf[]>([])
|
const directories = ref<TransferDirectoryConf[]>([])
|
||||||
@@ -195,8 +198,8 @@ onMounted(() => {
|
|||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VCard>
|
<VCard>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>存储</VCardTitle>
|
<VCardTitle>{{ t('setting.directory.storage') }}</VCardTitle>
|
||||||
<VCardSubtitle>设置本地或网盘存储。</VCardSubtitle>
|
<VCardSubtitle>{{ t('setting.directory.storageDesc') }}</VCardSubtitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<draggable
|
<draggable
|
||||||
@@ -214,7 +217,7 @@ onMounted(() => {
|
|||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||||
<VBtn type="submit" class="me-2" @click="saveStorages"> 保存 </VBtn>
|
<VBtn type="submit" class="me-2" @click="saveStorages"> {{ t('common.save') }} </VBtn>
|
||||||
</div>
|
</div>
|
||||||
</VForm>
|
</VForm>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
@@ -225,8 +228,8 @@ onMounted(() => {
|
|||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VCard>
|
<VCard>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>目录</VCardTitle>
|
<VCardTitle>{{ t('setting.directory.directory') }}</VCardTitle>
|
||||||
<VCardSubtitle>设置媒体文件整理目录结构,按先后顺序依次匹配。</VCardSubtitle>
|
<VCardSubtitle>{{ t('setting.directory.directoryDesc') }}</VCardSubtitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<draggable
|
<draggable
|
||||||
@@ -250,7 +253,7 @@ onMounted(() => {
|
|||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||||
<VBtn type="submit" @click="saveDirectories"> 保存 </VBtn>
|
<VBtn type="submit" @click="saveDirectories"> {{ t('common.save') }} </VBtn>
|
||||||
<VBtn color="success" variant="tonal" @click="addDirectory">
|
<VBtn color="success" variant="tonal" @click="addDirectory">
|
||||||
<VIcon icon="mdi-plus" />
|
<VIcon icon="mdi-plus" />
|
||||||
</VBtn>
|
</VBtn>
|
||||||
@@ -264,8 +267,8 @@ onMounted(() => {
|
|||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VCard>
|
<VCard>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>整理 & 刮削</VCardTitle>
|
<VCardTitle>{{ t('setting.directory.organizeAndScrap') }}</VCardTitle>
|
||||||
<VCardSubtitle>设置重命名格式、刮削选项等。</VCardSubtitle>
|
<VCardSubtitle>{{ t('setting.directory.organizeAndScrapDesc') }}</VCardSubtitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VRow>
|
<VRow>
|
||||||
@@ -273,16 +276,16 @@ onMounted(() => {
|
|||||||
<VSelect
|
<VSelect
|
||||||
v-model="SystemSettings.Basic.SCRAP_SOURCE"
|
v-model="SystemSettings.Basic.SCRAP_SOURCE"
|
||||||
:items="sourceItems"
|
:items="sourceItems"
|
||||||
label="刮削数据源"
|
:label="t('setting.directory.scrapSource')"
|
||||||
hint="刮削时的元数据来源"
|
:hint="t('setting.directory.scrapSourceHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VTextarea
|
<VTextarea
|
||||||
v-model="SystemSettings.Basic.MOVIE_RENAME_FORMAT"
|
v-model="SystemSettings.Basic.MOVIE_RENAME_FORMAT"
|
||||||
label="电影重命名格式"
|
:label="t('setting.directory.movieRenameFormat')"
|
||||||
hint="使用Jinja2语法,格式参考:https://jinja.palletsprojects.com/en/3.0.x/templates"
|
:hint="t('setting.directory.movieRenameFormatHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
clearable
|
clearable
|
||||||
active
|
active
|
||||||
@@ -291,8 +294,8 @@ onMounted(() => {
|
|||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VTextarea
|
<VTextarea
|
||||||
v-model="SystemSettings.Basic.TV_RENAME_FORMAT"
|
v-model="SystemSettings.Basic.TV_RENAME_FORMAT"
|
||||||
label="电视剧重命名格式"
|
:label="t('setting.directory.tvRenameFormat')"
|
||||||
hint="使用Jinja2语法,格式参考:https://jinja.palletsprojects.com/en/3.0.x/templates"
|
:hint="t('setting.directory.tvRenameFormatHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
clearable
|
clearable
|
||||||
active
|
active
|
||||||
@@ -303,7 +306,7 @@ onMounted(() => {
|
|||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||||
<VBtn type="submit" @click="saveSystemSettings(SystemSettings.Basic)"> 保存</VBtn>
|
<VBtn type="submit" @click="saveSystemSettings(SystemSettings.Basic)"> {{ t('common.save') }}</VBtn>
|
||||||
</div>
|
</div>
|
||||||
</VForm>
|
</VForm>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
@@ -311,5 +314,5 @@ onMounted(() => {
|
|||||||
</VCol>
|
</VCol>
|
||||||
</VRow>
|
</VRow>
|
||||||
<!-- 进度框 -->
|
<!-- 进度框 -->
|
||||||
<ProgressDialog v-if="progressDialog" v-model="progressDialog" text="正在应用配置..." />
|
<ProgressDialog v-if="progressDialog" v-model="progressDialog" :text="t('setting.system.reloading')" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -216,19 +216,19 @@ onMounted(() => {
|
|||||||
<VListItemTitle>{{ t('setting.notification.wechat') }}</VListItemTitle>
|
<VListItemTitle>{{ t('setting.notification.wechat') }}</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
<VListItem @click="addNotification('telegram')">
|
<VListItem @click="addNotification('telegram')">
|
||||||
<VListItemTitle>Telegram</VListItemTitle>
|
<VListItemTitle>{{ t('setting.notification.telegram') }}</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
<VListItem @click="addNotification('slack')">
|
<VListItem @click="addNotification('slack')">
|
||||||
<VListItemTitle>Slack</VListItemTitle>
|
<VListItemTitle>{{ t('setting.notification.slack') }}</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
<VListItem @click="addNotification('synologychat')">
|
<VListItem @click="addNotification('synologychat')">
|
||||||
<VListItemTitle>SynologyChat</VListItemTitle>
|
<VListItemTitle>{{ t('setting.notification.synologyChat') }}</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
<VListItem @click="addNotification('vocechat')">
|
<VListItem @click="addNotification('vocechat')">
|
||||||
<VListItemTitle>VoceChat</VListItemTitle>
|
<VListItemTitle>{{ t('setting.notification.voceChat') }}</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
<VListItem @click="addNotification('webpush')">
|
<VListItem @click="addNotification('webpush')">
|
||||||
<VListItemTitle>WebPush</VListItemTitle>
|
<VListItemTitle>{{ t('setting.notification.webPush') }}</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
</VList>
|
</VList>
|
||||||
</VMenu>
|
</VMenu>
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ import { CustomRule, FilterRuleGroup } from '@/api/types'
|
|||||||
import CustomerRuleCard from '@/components/cards/CustomRuleCard.vue'
|
import CustomerRuleCard from '@/components/cards/CustomRuleCard.vue'
|
||||||
import FilterRuleGroupCard from '@/components/cards/FilterRuleGroupCard.vue'
|
import FilterRuleGroupCard from '@/components/cards/FilterRuleGroupCard.vue'
|
||||||
import ImportCodeDialog from '@/components/dialog/ImportCodeDialog.vue'
|
import ImportCodeDialog from '@/components/dialog/ImportCodeDialog.vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
// 国际化
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
// 自定义规则列表
|
// 自定义规则列表
|
||||||
const customRules = ref<CustomRule[]>([])
|
const customRules = ref<CustomRule[]>([])
|
||||||
@@ -32,10 +36,10 @@ const $toast = useToast()
|
|||||||
|
|
||||||
// 种子优先规则下拉框
|
// 种子优先规则下拉框
|
||||||
const TorrentPriorityItems = [
|
const TorrentPriorityItems = [
|
||||||
{ title: '资源优先级', value: 'torrent' },
|
{ title: t('setting.rule.resourcePriority'), value: 'torrent' },
|
||||||
{ title: '站点优先级', value: 'site' },
|
{ title: t('setting.rule.sitePriority'), value: 'site' },
|
||||||
{ title: '站点上传量', value: 'upload' },
|
{ title: t('setting.rule.siteUpload'), value: 'upload' },
|
||||||
{ title: '资源做种数', value: 'seeder' },
|
{ title: t('setting.rule.resourceSeeder'), value: 'seeder' },
|
||||||
]
|
]
|
||||||
|
|
||||||
// 调用API查询自动分类配置
|
// 调用API查询自动分类配置
|
||||||
@@ -51,12 +55,12 @@ async function loadMediaCategories() {
|
|||||||
async function saveCustomRules() {
|
async function saveCustomRules() {
|
||||||
// 检查是否存在空id规则
|
// 检查是否存在空id规则
|
||||||
if (customRules.value.some(item => !item.id)) {
|
if (customRules.value.some(item => !item.id)) {
|
||||||
$toast.error('存在空ID的规则,无法保存,请修改!')
|
$toast.error(t('setting.rule.emptyIdError'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 检查是否存在空的规则名称
|
// 检查是否存在空的规则名称
|
||||||
if (customRules.value.some(item => !item.name)) {
|
if (customRules.value.some(item => !item.name)) {
|
||||||
$toast.error('存在空名字的规则,无法保存,请修改!')
|
$toast.error(t('setting.rule.emptyNameError'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 获取所有规则ID和名称
|
// 获取所有规则ID和名称
|
||||||
@@ -64,18 +68,18 @@ async function saveCustomRules() {
|
|||||||
const names = customRules.value.map(item => item.name)
|
const names = customRules.value.map(item => item.name)
|
||||||
// 检查是否存在重名的规则ID
|
// 检查是否存在重名的规则ID
|
||||||
if (new Set(ids).size !== ids.length) {
|
if (new Set(ids).size !== ids.length) {
|
||||||
$toast.error('存在重复规则ID!无法保存,请修改!')
|
$toast.error(t('setting.rule.duplicateIdError'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 检查是否存在重名规则名称
|
// 检查是否存在重名规则名称
|
||||||
if (new Set(names).size !== names.length) {
|
if (new Set(names).size !== names.length) {
|
||||||
$toast.error('存在重复规则名称!无法保存,请修改!')
|
$toast.error(t('setting.rule.duplicateNameError'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const result: { [key: string]: any } = await api.post('system/setting/CustomFilterRules', customRules.value)
|
const result: { [key: string]: any } = await api.post('system/setting/CustomFilterRules', customRules.value)
|
||||||
if (result.success) $toast.success('自定义规则保存成功')
|
if (result.success) $toast.success(t('setting.rule.customRuleSaveSuccess'))
|
||||||
else $toast.error('自定义规则保存失败!')
|
else $toast.error(t('setting.rule.customRuleSaveFailed'))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
@@ -117,19 +121,19 @@ async function queryFilterRuleGroups() {
|
|||||||
async function saveFilterRuleGroups() {
|
async function saveFilterRuleGroups() {
|
||||||
// 检查是否存在空的规则组名称
|
// 检查是否存在空的规则组名称
|
||||||
if (filterRuleGroups.value.some(item => !item.name)) {
|
if (filterRuleGroups.value.some(item => !item.name)) {
|
||||||
$toast.error('存在空名字的规则组!无法保存,请修改!')
|
$toast.error(t('setting.rule.emptyGroupNameError'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 检查是否存在重名规则组
|
// 检查是否存在重名规则组
|
||||||
const names = filterRuleGroups.value.map(item => item.name)
|
const names = filterRuleGroups.value.map(item => item.name)
|
||||||
if (new Set(names).size !== names.length) {
|
if (new Set(names).size !== names.length) {
|
||||||
$toast.error('存在重复规则组名称!无法保存,请修改!')
|
$toast.error(t('setting.rule.duplicateGroupNameError'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const result: { [key: string]: any } = await api.post('system/setting/UserFilterRuleGroups', filterRuleGroups.value)
|
const result: { [key: string]: any } = await api.post('system/setting/UserFilterRuleGroups', filterRuleGroups.value)
|
||||||
if (result.success) $toast.success('优先级规则组保存成功')
|
if (result.success) $toast.success(t('setting.rule.ruleGroupSaveSuccess'))
|
||||||
else $toast.error('优先级规则组保存失败!')
|
else $toast.error(t('setting.rule.ruleGroupSaveFailed'))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
@@ -157,10 +161,14 @@ async function shareRules(rules: CustomRule[] | FilterRuleGroup[], type: string)
|
|||||||
try {
|
try {
|
||||||
let success
|
let success
|
||||||
success = copyToClipboard(value)
|
success = copyToClipboard(value)
|
||||||
if (await success) $toast.success(`${type === 'custom' ? '自定义规则' : '优先级规则组'}已复制到剪贴板!`)
|
if (await success)
|
||||||
else $toast.error(`${type === 'custom' ? '自定义规则' : '优先级规则组'}复制失败:可能是浏览器不支持或被用户阻止!`)
|
$toast.success(
|
||||||
|
type === 'custom' ? t('setting.rule.customRuleCopySuccess') : t('setting.rule.ruleGroupCopySuccess'),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
$toast.error(type === 'custom' ? t('setting.rule.customRuleCopyFailed') : t('setting.rule.ruleGroupCopyFailed'))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
$toast.error(`${type === 'custom' ? '自定义规则' : '优先级规则组'}复制失败!`)
|
$toast.error(type === 'custom' ? t('setting.rule.customRuleCopyError') : t('setting.rule.ruleGroupCopyError'))
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,7 +186,7 @@ function saveCodeString(type: string, codeString: any) {
|
|||||||
try {
|
try {
|
||||||
parsedCode = JSON.parse(codeString.value)
|
parsedCode = JSON.parse(codeString.value)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
$toast.error('导入规则失败!无法解析输入的数据!')
|
$toast.error(t('setting.rule.importFailed'))
|
||||||
console.error(e)
|
console.error(e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -194,10 +202,10 @@ function saveCodeString(type: string, codeString: any) {
|
|||||||
const newFilterRuleGroups = extractFilterRuleGroups(parsedCode) || []
|
const newFilterRuleGroups = extractFilterRuleGroups(parsedCode) || []
|
||||||
filterRuleGroups.value = [...filterRuleGroups.value, ...newFilterRuleGroups]
|
filterRuleGroups.value = [...filterRuleGroups.value, ...newFilterRuleGroups]
|
||||||
} else {
|
} else {
|
||||||
$toast.error('导入规则失败!未知的数据类型!')
|
$toast.error(t('setting.rule.importUnknownType'))
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
$toast.error('导入规则失败!')
|
$toast.error(t('setting.rule.importFailed'))
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -272,8 +280,8 @@ function isValidValue(value: any, type: string): boolean {
|
|||||||
|
|
||||||
function validateCustomRule(hasName: boolean, hasId: boolean, noDuplicates: boolean): boolean {
|
function validateCustomRule(hasName: boolean, hasId: boolean, noDuplicates: boolean): boolean {
|
||||||
if (!hasName || !hasId || !noDuplicates) {
|
if (!hasName || !hasId || !noDuplicates) {
|
||||||
if (!noDuplicates) $toast.warning(`存在重名值`)
|
if (!noDuplicates) $toast.warning(t('setting.rule.duplicateValue'))
|
||||||
if (!hasId) $toast.error(`导入失败!发现有规则不存在ID,可能属于优先级规则组!`)
|
if (!hasId) $toast.error(t('setting.rule.importNoId'))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -281,8 +289,8 @@ function validateCustomRule(hasName: boolean, hasId: boolean, noDuplicates: bool
|
|||||||
|
|
||||||
function validateGroupRule(hasName: boolean, hasId: boolean, noDuplicates: boolean): boolean {
|
function validateGroupRule(hasName: boolean, hasId: boolean, noDuplicates: boolean): boolean {
|
||||||
if (!hasName || hasId || !noDuplicates) {
|
if (!hasName || hasId || !noDuplicates) {
|
||||||
if (!noDuplicates) $toast.warning(`存在重名值`)
|
if (!noDuplicates) $toast.warning(t('setting.rule.duplicateValue'))
|
||||||
if (hasId) $toast.error(`导入失败!发现有规则存在相同ID,可能属于自定义规则!`)
|
if (hasId) $toast.error(t('setting.rule.importHasId'))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -367,8 +375,8 @@ onMounted(() => {
|
|||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VCard>
|
<VCard>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>自定义规则</VCardTitle>
|
<VCardTitle>{{ t('setting.rule.customRules') }}</VCardTitle>
|
||||||
<VCardSubtitle>自定义优先级规则项</VCardSubtitle>
|
<VCardSubtitle>{{ t('setting.rule.customRulesDesc') }}</VCardSubtitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<draggable
|
<draggable
|
||||||
@@ -391,7 +399,7 @@ onMounted(() => {
|
|||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||||
<VBtn type="submit" class="me-2" @click="saveCustomRules"> 保存 </VBtn>
|
<VBtn type="submit" class="me-2" @click="saveCustomRules"> {{ t('common.save') }} </VBtn>
|
||||||
<VBtnGroup density="comfortable">
|
<VBtnGroup density="comfortable">
|
||||||
<VBtn color="success" variant="tonal" @click="addCustomRule">
|
<VBtn color="success" variant="tonal" @click="addCustomRule">
|
||||||
<VIcon icon="mdi-plus" />
|
<VIcon icon="mdi-plus" />
|
||||||
@@ -416,8 +424,8 @@ onMounted(() => {
|
|||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VCard>
|
<VCard>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>优先级规则组</VCardTitle>
|
<VCardTitle>{{ t('setting.rule.priorityRuleGroups') }}</VCardTitle>
|
||||||
<VCardSubtitle>预设优先级规则组,以便在搜索和订阅中使用。</VCardSubtitle>
|
<VCardSubtitle>{{ t('setting.rule.priorityRuleGroupsDesc') }}</VCardSubtitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<draggable
|
<draggable
|
||||||
@@ -442,7 +450,7 @@ onMounted(() => {
|
|||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||||
<VBtn type="submit" class="me-2" @click="saveFilterRuleGroups"> 保存 </VBtn>
|
<VBtn type="submit" class="me-2" @click="saveFilterRuleGroups"> {{ t('common.save') }} </VBtn>
|
||||||
<VBtnGroup density="comfortable">
|
<VBtnGroup density="comfortable">
|
||||||
<VBtn color="success" variant="tonal" @click="addFilterRuleGroup">
|
<VBtn color="success" variant="tonal" @click="addFilterRuleGroup">
|
||||||
<VIcon icon="mdi-plus" />
|
<VIcon icon="mdi-plus" />
|
||||||
@@ -466,7 +474,7 @@ onMounted(() => {
|
|||||||
<ImportCodeDialog
|
<ImportCodeDialog
|
||||||
v-if="importCodeDialog"
|
v-if="importCodeDialog"
|
||||||
v-model="importCodeDialog"
|
v-model="importCodeDialog"
|
||||||
:title="`导入${importCodeType === 'custom' ? '自定义规则' : '优先级规则组'}`"
|
:title="importCodeType === 'custom' ? t('setting.rule.importCustomRules') : t('setting.rule.importRuleGroups')"
|
||||||
:dataType="importCodeType"
|
:dataType="importCodeType"
|
||||||
@close="importCodeDialog = false"
|
@close="importCodeDialog = false"
|
||||||
@save="saveCodeString"
|
@save="saveCodeString"
|
||||||
@@ -475,8 +483,8 @@ onMounted(() => {
|
|||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VCard>
|
<VCard>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>下载规则</VCardTitle>
|
<VCardTitle>{{ t('setting.rule.downloadRules') }}</VCardTitle>
|
||||||
<VCardSubtitle>同时命中多个资源时择优下载。</VCardSubtitle>
|
<VCardSubtitle>{{ t('setting.rule.downloadRulesDesc') }}</VCardSubtitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm>
|
<VForm>
|
||||||
@@ -488,8 +496,8 @@ onMounted(() => {
|
|||||||
multiple
|
multiple
|
||||||
clearable
|
clearable
|
||||||
chips
|
chips
|
||||||
label="当前使用下载优先规则"
|
:label="t('setting.rule.currentPriorityRules')"
|
||||||
hint="排在前面的优先级越高,未选择的项不纳入排序"
|
:hint="t('setting.rule.currentPriorityRulesHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
@@ -499,7 +507,7 @@ onMounted(() => {
|
|||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||||
<VBtn type="submit" @click="saveTorrentPriority"> 保存 </VBtn>
|
<VBtn type="submit" @click="saveTorrentPriority"> {{ t('common.save') }} </VBtn>
|
||||||
</div>
|
</div>
|
||||||
</VForm>
|
</VForm>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
import { useToast } from 'vue-toast-notification'
|
import { useToast } from 'vue-toast-notification'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import type { ScheduleInfo } from '@/api/types'
|
import type { ScheduleInfo } from '@/api/types'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
// 国际化
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
// 提示框
|
// 提示框
|
||||||
const $toast = useToast()
|
const $toast = useToast()
|
||||||
@@ -26,11 +30,11 @@ async function loadSchedulerList() {
|
|||||||
// 任务状态颜色
|
// 任务状态颜色
|
||||||
function getSchedulerColor(status: string) {
|
function getSchedulerColor(status: string) {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case '正在运行':
|
case t('setting.scheduler.running'):
|
||||||
return 'success'
|
return 'success'
|
||||||
case '已停止':
|
case t('setting.scheduler.stopped'):
|
||||||
return 'error'
|
return 'error'
|
||||||
case '等待':
|
case t('setting.scheduler.waiting'):
|
||||||
return ''
|
return ''
|
||||||
default:
|
default:
|
||||||
return ''
|
return ''
|
||||||
@@ -46,7 +50,7 @@ function runCommand(id: string) {
|
|||||||
jobid: id,
|
jobid: id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
$toast.success('定时作业执行请求提交成功!')
|
$toast.success(t('setting.scheduler.executeSuccess'))
|
||||||
// 1秒后刷新数据
|
// 1秒后刷新数据
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
loadSchedulerList()
|
loadSchedulerList()
|
||||||
@@ -77,16 +81,16 @@ onUnmounted(() => {
|
|||||||
<template>
|
<template>
|
||||||
<VCard>
|
<VCard>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>定时作业</VCardTitle>
|
<VCardTitle>{{ t('setting.scheduler.title') }}</VCardTitle>
|
||||||
<VCardSubtitle>包含系统内置服务以及插件提供的服务,手动执行不会影响作业正常的时间表。</VCardSubtitle>
|
<VCardSubtitle>{{ t('setting.scheduler.subtitle') }}</VCardSubtitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VTable class="text-no-wrap">
|
<VTable class="text-no-wrap">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">提供者</th>
|
<th scope="col">{{ t('setting.scheduler.provider') }}</th>
|
||||||
<th scope="col">任务名称</th>
|
<th scope="col">{{ t('setting.scheduler.taskName') }}</th>
|
||||||
<th scope="col">任务状态</th>
|
<th scope="col">{{ t('setting.scheduler.taskStatus') }}</th>
|
||||||
<th scope="col">下一次执行时间</th>
|
<th scope="col">{{ t('setting.scheduler.nextRunTime') }}</th>
|
||||||
<th scope="col" />
|
<th scope="col" />
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -107,16 +111,20 @@ onUnmounted(() => {
|
|||||||
{{ scheduler.next_run }}
|
{{ scheduler.next_run }}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<VBtn size="small" :disabled="scheduler.status === '正在运行'" @click="runCommand(scheduler.id)">
|
<VBtn
|
||||||
|
size="small"
|
||||||
|
:disabled="scheduler.status === t('setting.scheduler.running')"
|
||||||
|
@click="runCommand(scheduler.id)"
|
||||||
|
>
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<VIcon>mdi-play</VIcon>
|
<VIcon>mdi-play</VIcon>
|
||||||
</template>
|
</template>
|
||||||
执行
|
{{ t('setting.scheduler.execute') }}
|
||||||
</VBtn>
|
</VBtn>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="schedulerList.length === 0">
|
<tr v-if="schedulerList.length === 0">
|
||||||
<td colspan="4" class="text-center">没有后台服务</td>
|
<td colspan="4" class="text-center">{{ t('setting.scheduler.noService') }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</VTable>
|
</VTable>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { useToast } from 'vue-toast-notification'
|
import { useToast } from 'vue-toast-notification'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import type { FilterRuleGroup, Site } from '@/api/types'
|
import type { FilterRuleGroup, Site } from '@/api/types'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
// 提示框
|
// 提示框
|
||||||
const $toast = useToast()
|
const $toast = useToast()
|
||||||
@@ -172,6 +173,8 @@ async function loadSystemSettings() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
querySites()
|
querySites()
|
||||||
queryFilterRuleGroups()
|
queryFilterRuleGroups()
|
||||||
@@ -186,8 +189,8 @@ onMounted(() => {
|
|||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VCard>
|
<VCard>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>基础设置</VCardTitle>
|
<VCardTitle>{{ t('setting.search.basicSettings') }}</VCardTitle>
|
||||||
<VCardSubtitle>设定数据源、规则组等基础信息。</VCardSubtitle>
|
<VCardSubtitle>{{ t('setting.search.basicSettingsDesc') }}</VCardSubtitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VRow>
|
<VRow>
|
||||||
@@ -198,8 +201,8 @@ onMounted(() => {
|
|||||||
clearable
|
clearable
|
||||||
chips
|
chips
|
||||||
:items="mediaSourcesDict"
|
:items="mediaSourcesDict"
|
||||||
label="媒体搜索数据源"
|
:label="t('setting.search.mediaSource')"
|
||||||
hint="搜索媒体信息时使用的数据源以及排序"
|
:hint="t('setting.search.mediaSourceHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
@@ -210,8 +213,8 @@ onMounted(() => {
|
|||||||
clearable
|
clearable
|
||||||
chips
|
chips
|
||||||
:items="filterRuleGroupOptions"
|
:items="filterRuleGroupOptions"
|
||||||
label="优先级规则组"
|
:label="t('setting.search.filterRuleGroup')"
|
||||||
hint="搜索媒体信息时按选定的过滤规则组对结果进行过滤"
|
:hint="t('setting.search.filterRuleGroupHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
@@ -220,34 +223,34 @@ onMounted(() => {
|
|||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VTextField
|
<VTextField
|
||||||
v-model="SystemSettings.Basic.TORRENT_TAG"
|
v-model="SystemSettings.Basic.TORRENT_TAG"
|
||||||
label="下载任务标签"
|
:label="t('setting.search.downloadLabel')"
|
||||||
placeholder="MOVIEPILOT"
|
placeholder="MOVIEPILOT"
|
||||||
hint="MoviePilot添加的下载任务标签"
|
:hint="t('setting.search.downloadLabelHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VCombobox
|
<VCombobox
|
||||||
v-model="SystemSettings.Basic.AUTO_DOWNLOAD_USER"
|
v-model="SystemSettings.Basic.AUTO_DOWNLOAD_USER"
|
||||||
label="远程搜索自动下载用户名单"
|
:label="t('setting.search.downloadUser')"
|
||||||
placeholder="用户ID1,用户ID2"
|
:placeholder="t('setting.search.downloadUserPlaceholder')"
|
||||||
hint="使用Telegram、微信等搜索时是否自动下载,使用逗号分割,设置为 all 代表所有用户自动择优下载"
|
:hint="t('setting.search.downloadUserHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VSwitch
|
<VSwitch
|
||||||
v-model="SystemSettings.Basic.SEARCH_MULTIPLE_NAME"
|
v-model="SystemSettings.Basic.SEARCH_MULTIPLE_NAME"
|
||||||
label="多名称资源搜索"
|
:label="t('setting.search.multipleNameSearch')"
|
||||||
hint="使用中英文等多个名称搜索站点资源并合并搜索结果,将会增加站点访问频率"
|
:hint="t('setting.search.multipleNameSearchHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VSwitch
|
<VSwitch
|
||||||
v-model="SystemSettings.Basic.DOWNLOAD_SUBTITLE"
|
v-model="SystemSettings.Basic.DOWNLOAD_SUBTITLE"
|
||||||
label="下载站点字幕"
|
:label="t('setting.search.downloadSubtitle')"
|
||||||
hint="检查站点资源是否有独立的字幕文件,有则自动下载"
|
:hint="t('setting.search.downloadSubtitleHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
@@ -256,7 +259,7 @@ onMounted(() => {
|
|||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||||
<VBtn type="submit" @click="saveSearchSetting"> 保存 </VBtn>
|
<VBtn type="submit" @click="saveSearchSetting"> {{ t('common.save') }} </VBtn>
|
||||||
</div>
|
</div>
|
||||||
</VForm>
|
</VForm>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
@@ -267,8 +270,8 @@ onMounted(() => {
|
|||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VCard>
|
<VCard>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>搜索站点</VCardTitle>
|
<VCardTitle>{{ t('setting.search.downloadSite') }}</VCardTitle>
|
||||||
<VCardSubtitle> 只有选中的站点才会在搜索中使用。</VCardSubtitle>
|
<VCardSubtitle>{{ t('setting.search.downloadSiteDesc') }}</VCardSubtitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VChipGroup v-model="selectedSites" column multiple>
|
<VChipGroup v-model="selectedSites" column multiple>
|
||||||
@@ -287,7 +290,7 @@ onMounted(() => {
|
|||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||||
<VBtn type="submit" @click="saveSelectedSites"> 保存 </VBtn>
|
<VBtn type="submit" @click="saveSelectedSites"> {{ t('common.save') }} </VBtn>
|
||||||
</div>
|
</div>
|
||||||
</VForm>
|
</VForm>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { useToast } from 'vue-toast-notification'
|
|||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import type { FilterRuleGroup, Site } from '@/api/types'
|
import type { FilterRuleGroup, Site } from '@/api/types'
|
||||||
import ProgressDialog from '@/components/dialog/ProgressDialog.vue'
|
import ProgressDialog from '@/components/dialog/ProgressDialog.vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
// 提示框
|
// 提示框
|
||||||
const $toast = useToast()
|
const $toast = useToast()
|
||||||
@@ -24,8 +25,8 @@ const selectedBestVersionRuleGroup = ref([])
|
|||||||
|
|
||||||
// 订阅模式选择项
|
// 订阅模式选择项
|
||||||
const subscribeModeItems = [
|
const subscribeModeItems = [
|
||||||
{ title: '自动', value: 'spider' },
|
{ title: t('setting.subscribe.modes.auto'), value: 'spider' },
|
||||||
{ title: '站点RSS', value: 'rss' },
|
{ title: t('setting.subscribe.modes.rss'), value: 'rss' },
|
||||||
]
|
]
|
||||||
|
|
||||||
// 所有规则组列表
|
// 所有规则组列表
|
||||||
@@ -41,13 +42,13 @@ const filterRuleGroupOptions = computed(() => {
|
|||||||
|
|
||||||
// RSS运行周期选择项
|
// RSS运行周期选择项
|
||||||
const rssIntervalItems = [
|
const rssIntervalItems = [
|
||||||
{ title: '5分钟', value: 5 },
|
{ title: t('setting.subscribe.intervals.min5'), value: 5 },
|
||||||
{ title: '10分钟', value: 10 },
|
{ title: t('setting.subscribe.intervals.min10'), value: 10 },
|
||||||
{ title: '20分钟', value: 20 },
|
{ title: t('setting.subscribe.intervals.min20'), value: 20 },
|
||||||
{ title: '半小时', value: 30 },
|
{ title: t('setting.subscribe.intervals.min30'), value: 30 },
|
||||||
{ title: '1小时', value: 60 },
|
{ title: t('setting.subscribe.intervals.hour1'), value: 60 },
|
||||||
{ title: '12小时', value: 720 },
|
{ title: t('setting.subscribe.intervals.hour12'), value: 720 },
|
||||||
{ title: '1天', value: 1440 },
|
{ title: t('setting.subscribe.intervals.day1'), value: 1440 },
|
||||||
]
|
]
|
||||||
|
|
||||||
// 系统设置项
|
// 系统设置项
|
||||||
@@ -99,8 +100,8 @@ async function saveSelectedRssSites() {
|
|||||||
try {
|
try {
|
||||||
const result1: { [key: string]: any } = await api.post('system/setting/RssSites', selectedRssSites.value)
|
const result1: { [key: string]: any } = await api.post('system/setting/RssSites', selectedRssSites.value)
|
||||||
|
|
||||||
if (result1.success) $toast.success('订阅站点保存成功')
|
if (result1.success) $toast.success(t('setting.subscribe.saveSuccess'))
|
||||||
else $toast.error('订阅站点保存失败!')
|
else $toast.error(t('setting.subscribe.saveFailed'))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
@@ -154,8 +155,8 @@ async function reloadSystem() {
|
|||||||
progressDialog.value = true
|
progressDialog.value = true
|
||||||
try {
|
try {
|
||||||
const result: { [key: string]: any } = await api.get('system/reload')
|
const result: { [key: string]: any } = await api.get('system/reload')
|
||||||
if (result.success) $toast.success('系统配置已生效')
|
if (result.success) $toast.success(t('setting.system.reloadSuccess'))
|
||||||
else $toast.error('重载系统失败!')
|
else $toast.error(t('setting.system.reloadFailed'))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
@@ -178,14 +179,16 @@ async function saveSubscribeSetting() {
|
|||||||
const result3 = await saveSystemSetting(SystemSettings.value.Basic)
|
const result3 = await saveSystemSetting(SystemSettings.value.Basic)
|
||||||
|
|
||||||
if (result1.success && result2.success && result3) {
|
if (result1.success && result2.success && result3) {
|
||||||
$toast.success('订阅基础设置保存成功')
|
$toast.success(t('setting.subscribe.settingsSaveSuccess'))
|
||||||
await reloadSystem()
|
await reloadSystem()
|
||||||
} else $toast.error('订阅基础设置保存失败!')
|
} else $toast.error(t('setting.subscribe.settingsSaveFailed'))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
querySites()
|
querySites()
|
||||||
queryFilterRuleGroups()
|
queryFilterRuleGroups()
|
||||||
@@ -200,8 +203,8 @@ onMounted(() => {
|
|||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VCard>
|
<VCard>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>基础设置</VCardTitle>
|
<VCardTitle>{{ t('setting.subscribe.basicSettings') }}</VCardTitle>
|
||||||
<VCardSubtitle>设定订阅模式、周期等基础设置</VCardSubtitle>
|
<VCardSubtitle>{{ t('setting.subscribe.basicSettingsDesc') }}</VCardSubtitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm>
|
<VForm>
|
||||||
@@ -210,8 +213,8 @@ onMounted(() => {
|
|||||||
<VSelect
|
<VSelect
|
||||||
v-model="SystemSettings.Basic.SUBSCRIBE_MODE"
|
v-model="SystemSettings.Basic.SUBSCRIBE_MODE"
|
||||||
:items="subscribeModeItems"
|
:items="subscribeModeItems"
|
||||||
label="订阅模式"
|
:label="t('setting.subscribe.mode')"
|
||||||
hint="自动:自动爬取站点首页,站点RSS:通过站点RSS链接订阅"
|
:hint="t('setting.subscribe.modeHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
@@ -219,8 +222,8 @@ onMounted(() => {
|
|||||||
<VSelect
|
<VSelect
|
||||||
v-model="SystemSettings.Basic.SUBSCRIBE_RSS_INTERVAL"
|
v-model="SystemSettings.Basic.SUBSCRIBE_RSS_INTERVAL"
|
||||||
:items="rssIntervalItems"
|
:items="rssIntervalItems"
|
||||||
label="站点RSS周期"
|
:label="t('setting.subscribe.rssInterval')"
|
||||||
hint="设置站点RSS运行周期,在订阅模式为`站点RSS`时生效"
|
:hint="t('setting.subscribe.rssIntervalHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
@@ -231,8 +234,8 @@ onMounted(() => {
|
|||||||
chips
|
chips
|
||||||
multiple
|
multiple
|
||||||
clearable
|
clearable
|
||||||
label="订阅优先级规则组"
|
:label="t('setting.subscribe.filterRuleGroup')"
|
||||||
hint="按选定的过滤规则组对订阅进行过滤"
|
:hint="t('setting.subscribe.filterRuleGroupHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
@@ -243,8 +246,8 @@ onMounted(() => {
|
|||||||
chips
|
chips
|
||||||
multiple
|
multiple
|
||||||
clearable
|
clearable
|
||||||
label="洗版优先级规则组"
|
:label="t('setting.subscribe.bestVersionRuleGroup')"
|
||||||
hint="按选定的过滤规则组对洗版订阅进行过滤"
|
:hint="t('setting.subscribe.bestVersionRuleGroupHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
@@ -253,16 +256,16 @@ onMounted(() => {
|
|||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VSwitch
|
<VSwitch
|
||||||
v-model="SystemSettings.Basic.SUBSCRIBE_SEARCH"
|
v-model="SystemSettings.Basic.SUBSCRIBE_SEARCH"
|
||||||
label="订阅定时搜索"
|
:label="t('setting.subscribe.timedSearch')"
|
||||||
hint="每隔24小时全站搜索,以补全订阅可能漏掉的资源"
|
:hint="t('setting.subscribe.timedSearchHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VSwitch
|
<VSwitch
|
||||||
v-model="SystemSettings.Basic.LOCAL_EXISTS_SEARCH"
|
v-model="SystemSettings.Basic.LOCAL_EXISTS_SEARCH"
|
||||||
label="检查本地媒体库资源"
|
:label="t('setting.subscribe.checkLocalMedia')"
|
||||||
hint="检查存储盘是否存在资源,以避免重复下载"
|
:hint="t('setting.subscribe.checkLocalMediaHint')"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
@@ -272,7 +275,7 @@ onMounted(() => {
|
|||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||||
<VBtn type="submit" @click="saveSubscribeSetting"> 保存 </VBtn>
|
<VBtn type="submit" @click="saveSubscribeSetting"> {{ t('common.save') }} </VBtn>
|
||||||
</div>
|
</div>
|
||||||
</VForm>
|
</VForm>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
@@ -283,8 +286,8 @@ onMounted(() => {
|
|||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
<VCard>
|
<VCard>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>订阅站点</VCardTitle>
|
<VCardTitle>{{ t('setting.subscribe.subscribeSites') }}</VCardTitle>
|
||||||
<VCardSubtitle>只有选中的站点才会在订阅中使用。</VCardSubtitle>
|
<VCardSubtitle>{{ t('setting.subscribe.subscribeSitesDesc') }}</VCardSubtitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VChipGroup v-model="selectedRssSites" column multiple>
|
<VChipGroup v-model="selectedRssSites" column multiple>
|
||||||
@@ -303,7 +306,7 @@ onMounted(() => {
|
|||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||||
<VBtn type="submit" @click="saveSelectedRssSites"> 保存 </VBtn>
|
<VBtn type="submit" @click="saveSelectedRssSites"> {{ t('common.save') }} </VBtn>
|
||||||
</div>
|
</div>
|
||||||
</VForm>
|
</VForm>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
@@ -311,5 +314,5 @@ onMounted(() => {
|
|||||||
</VCol>
|
</VCol>
|
||||||
</VRow>
|
</VRow>
|
||||||
<!-- 进度框 -->
|
<!-- 进度框 -->
|
||||||
<ProgressDialog v-if="progressDialog" v-model="progressDialog" text="正在应用配置..." />
|
<ProgressDialog v-if="progressDialog" v-model="progressDialog" :text="t('setting.system.reloading')" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -532,10 +532,10 @@ onDeactivated(() => {
|
|||||||
<VMenu activator="parent" close-on-content-click>
|
<VMenu activator="parent" close-on-content-click>
|
||||||
<VList>
|
<VList>
|
||||||
<VListItem @click="addDownloader('qbittorrent')">
|
<VListItem @click="addDownloader('qbittorrent')">
|
||||||
<VListItemTitle>Qbittorrent</VListItemTitle>
|
<VListItemTitle>{{ t('setting.system.qbittorrent') }}</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
<VListItem @click="addDownloader('transmission')">
|
<VListItem @click="addDownloader('transmission')">
|
||||||
<VListItemTitle>Transmission</VListItemTitle>
|
<VListItemTitle>{{ t('setting.system.transmission') }}</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
</VList>
|
</VList>
|
||||||
</VMenu>
|
</VMenu>
|
||||||
@@ -580,13 +580,13 @@ onDeactivated(() => {
|
|||||||
<VMenu activator="parent" close-on-content-click>
|
<VMenu activator="parent" close-on-content-click>
|
||||||
<VList>
|
<VList>
|
||||||
<VListItem @click="addMediaServer('emby')">
|
<VListItem @click="addMediaServer('emby')">
|
||||||
<VListItemTitle>Emby</VListItemTitle>
|
<VListItemTitle>{{ t('setting.system.emby') }}</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
<VListItem @click="addMediaServer('jellyfin')">
|
<VListItem @click="addMediaServer('jellyfin')">
|
||||||
<VListItemTitle>Jellyfin</VListItemTitle>
|
<VListItemTitle>{{ t('setting.system.jellyfin') }}</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
<VListItem @click="addMediaServer('plex')">
|
<VListItem @click="addMediaServer('plex')">
|
||||||
<VListItemTitle>Plex</VListItemTitle>
|
<VListItemTitle>{{ t('setting.system.plex') }}</VListItemTitle>
|
||||||
</VListItem>
|
</VListItem>
|
||||||
<VListItem @click="addMediaServer('trimemedia')">
|
<VListItem @click="addMediaServer('trimemedia')">
|
||||||
<VListItemTitle>{{ t('setting.system.trimeMedia') }}</VListItemTitle>
|
<VListItemTitle>{{ t('setting.system.trimeMedia') }}</VListItemTitle>
|
||||||
|
|||||||
Reference in New Issue
Block a user