From 8aba3cbe009283593b5ea59e12c699d69cd15421 Mon Sep 17 00:00:00 2001 From: stkevintan Date: Mon, 8 Dec 2025 17:43:49 +0800 Subject: [PATCH] fix key index issue --- src/components/cards/DownloaderCard.vue | 68 ++++++++++++++++--------- 1 file changed, 44 insertions(+), 24 deletions(-) diff --git a/src/components/cards/DownloaderCard.vue b/src/components/cards/DownloaderCard.vue index 076db08f..b6db10a1 100644 --- a/src/components/cards/DownloaderCard.vue +++ b/src/components/cards/DownloaderCard.vue @@ -85,22 +85,16 @@ function parseStoragePath(path: string): [prefix: string, suffix: string] { } // 更新存储路径前缀 -function updateStoragePrefix(index: number, storage: string) { - if (!downloaderInfo.value.path_mapping) return - const currentMapping = downloaderInfo.value.path_mapping[index] - const currentPath = currentMapping[0] || '' - const [, currentSuffix] = parseStoragePath(currentPath) +function updateStoragePrefix(row: PathMappingRow, storage: string) { + const [, currentSuffix] = parseStoragePath(row.storage) const prefix = storage2Prefix(storage) - currentMapping[0] = prefix + currentSuffix + row.storage = prefix + currentSuffix } // 更新存储路径后缀 -function updateStorageSuffix(index: number, suffix: string) { - if (!downloaderInfo.value.path_mapping) return - const currentMapping = downloaderInfo.value.path_mapping[index] - const currentPath = currentMapping[0] || '' - const [currentPrefix] = parseStoragePath(currentPath) - currentMapping[0] = currentPrefix + suffix +function updateStorageSuffix(row: PathMappingRow, suffix: string) { + const [currentPrefix] = parseStoragePath(row.storage) + row.storage = currentPrefix + suffix } const pathValidationRules = [ @@ -115,8 +109,24 @@ const downloaderInfo = ref({ default: false, enabled: false, config: {}, + path_mapping: [], }) +// 路径映射行定义 +interface PathMappingRow { + id: string + storage: string + download: string +} + +// 路径映射行数据 +const pathMappingRows = ref([]) + +// 生成随机ID +function generateId() { + return Math.random().toString(36).substring(2, 9) +} + // 下载器是否应该刷新数据的计算属性 const shouldRefresh = computed(() => props.allowRefresh && props.downloader.enabled) @@ -148,6 +158,12 @@ async function loadDownloaderInfo() { function openDownloaderInfoDialog() { // 深复制 downloaderInfo.value = cloneDeep(props.downloader) + // 初始化路径映射行数据 + pathMappingRows.value = (downloaderInfo.value.path_mapping || []).map(item => ({ + id: generateId(), + storage: item[0], + download: item[1], + })) downloaderInfoDialog.value = true } @@ -157,6 +173,9 @@ async function saveDownloaderInfo() { const { valid } = await downloaderForm.value?.validate() if (!valid) return + // 同步路径映射数据 + downloaderInfo.value.path_mapping = pathMappingRows.value.map(row => [row.storage, row.download]) + // 为空不保存,跳出警告框 if (!downloaderInfo.value.name) { $toast.error(t('downloader.nameRequired')) @@ -196,15 +215,16 @@ const getIcon = computed(() => { // 添加路径映射 function addPathMapping() { - if (!downloaderInfo.value.path_mapping) { - downloaderInfo.value.path_mapping = [] - } - downloaderInfo.value.path_mapping.push(['', '']) + pathMappingRows.value.push({ + id: generateId(), + storage: '', + download: '' + }) } // 移除路径映射 function removePathMapping(index: number) { - downloaderInfo.value.path_mapping?.splice(index, 1) + pathMappingRows.value.splice(index, 1) } // 按钮点击 @@ -482,30 +502,30 @@ onUnmounted(() => { {{ t('downloader.pathMapping') }}
@@ -513,7 +533,7 @@ onUnmounted(() => {