From 3d622d2efee0d281800b5596144a1ede6f52977d Mon Sep 17 00:00:00 2001 From: stkevintan Date: Mon, 8 Dec 2025 09:15:51 +0800 Subject: [PATCH] add path mapping --- src/api/types.ts | 2 + src/components/cards/DownloaderCard.vue | 91 ++++++++++++++++++++++++- src/locales/en-US.ts | 5 ++ src/locales/zh-CN.ts | 5 ++ src/locales/zh-TW.ts | 5 ++ 5 files changed, 105 insertions(+), 3 deletions(-) diff --git a/src/api/types.ts b/src/api/types.ts index 9cc072e6..ef52b2e0 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -1084,6 +1084,8 @@ export interface DownloaderConf { config: { [key: string]: any } // 是否启用 enabled: boolean + // 路径映射 + path_mapping?: Array<[src: string, dst: string]> } // 通知配置 diff --git a/src/components/cards/DownloaderCard.vue b/src/components/cards/DownloaderCard.vue index 1b8286e3..df07b83a 100644 --- a/src/components/cards/DownloaderCard.vue +++ b/src/components/cards/DownloaderCard.vue @@ -7,7 +7,7 @@ import type { DownloaderInfo } from '@/api/types' import { getLogoUrl } from '@/utils/imageUtils' import { cloneDeep } from 'lodash-es' import { useI18n } from 'vue-i18n' -import { downloaderDict } from '@/api/constants' +import { downloaderDict, storageAttributes } from '@/api/constants' import { useDisplay } from 'vuetify' import { useBackgroundOptimization } from '@/composables/useBackgroundOptimization' @@ -52,6 +52,24 @@ const download_rate = ref(0) // 下载器详情弹窗 const downloaderInfoDialog = ref(false) +// 表单 +const downloaderForm = ref() + +// 路径校验规则 +const remotePathRules = [ + (v: string) => !!v || t('downloader.pathMappingRequired'), + (v: string) => { + const prefixes = storageAttributes.map(s => (s.type === 'local' ? '/' : `${s.type}:/`)) + const pattern = new RegExp(`^(${prefixes.join('|')})`) + return pattern.test(v) || t('downloader.pathMappingFormatError') + }, +] + +const localPathRules = [ + (v: string) => !!v || t('downloader.pathMappingRequired'), + (v: string) => v.startsWith('/') || t('downloader.pathMappingLocalError'), +] + // 下载器详情 const downloaderInfo = ref({ name: '', @@ -96,7 +114,11 @@ function openDownloaderInfoDialog() { } // 保存详情数据 -function saveDownloaderInfo() { +async function saveDownloaderInfo() { + // 表单校验 + const { valid } = await downloaderForm.value?.validate() + if (!valid) return + // 为空不保存,跳出警告框 if (!downloaderInfo.value.name) { $toast.error(t('downloader.nameRequired')) @@ -134,6 +156,19 @@ const getIcon = computed(() => { } }) +// 添加路径映射 +function addPathMapping() { + if (!downloaderInfo.value.path_mapping) { + downloaderInfo.value.path_mapping = [] + } + downloaderInfo.value.path_mapping.push(['', '']) +} + +// 移除路径映射 +function removePathMapping(index: number) { + downloaderInfo.value.path_mapping?.splice(index, 1) +} + // 按钮点击 function onClose() { emit('close') @@ -152,6 +187,22 @@ onUnmounted(() => { stopRefresh() }) + +