From 3a9ec81c51435b5574b73fb3b965d8a435875e32 Mon Sep 17 00:00:00 2001 From: yueli Date: Mon, 31 Aug 2026 13:31:08 +0800 Subject: [PATCH] =?UTF-8?q?fix(purchase):=20=E7=85=A7=E7=89=87=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=8A=A0=E7=A1=AE=E8=AE=A4=20+=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E7=85=A7=E7=89=87=E8=B7=A8=E8=A1=8C=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=AF=BC=E8=87=B4=E5=9B=BE=E7=89=87=E7=BC=BA=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: 同步照片后多行共享同一物理文件 URL,删除某行照片时 deleteFile 删除了物理文件,其他行引用同一 URL 变图片缺失 修复: - 删除前检查照片被几行引用 - 若被多行引用: 弹窗询问【全部删除】(所有行移除+删文件) 或【仅移出此行】(只从当前行移除引用,不删服务器文件) - 若仅当前行引用: 普通确认后删除 - 普通删除也加确认弹窗 --- inventory-web/src/views/purchase/index.vue | 68 ++++++++++++++++++++-- 1 file changed, 63 insertions(+), 5 deletions(-) diff --git a/inventory-web/src/views/purchase/index.vue b/inventory-web/src/views/purchase/index.vue index 8361a9c..bf036bc 100644 --- a/inventory-web/src/views/purchase/index.vue +++ b/inventory-web/src/views/purchase/index.vue @@ -629,14 +629,72 @@ const customUploadRow = async (options: any, row: any) => { } } -// ★ 行内照片删除 +// ★ 统计某张照片被多少行引用(用于判断同步后的跨行删除) +const countImageRefs = (urlToRemove: string): number => { + let count = 0 + formItems.value.forEach(r => { + if ((r.images || []).includes(urlToRemove)) count++ + }) + return count +} + +// ★ 行内照片删除(带确认 + 跨行引用保护) const handleRemoveRowImage = async (uploadFile: any, row: any) => { const urlToRemove = (row.images || []).find(u => getImageUrl(u) === uploadFile.url) || uploadFile.url - row.images = (row.images || []).filter(u => u !== urlToRemove) - row.fileList = (row.fileList || []).filter(f => f.url !== uploadFile.url) const filename = urlToRemove.split('/').pop() - if (filename && !urlToRemove.startsWith('http')) { - await deleteFile(filename).catch(() => {}) + const isInternal = filename && !urlToRemove.startsWith('http') + + // 检查该照片是否也被其他行引用(同步照片场景) + const refCount = countImageRefs(urlToRemove) + const sharedByOthers = refCount > 1 // 包含当前行 + + if (sharedByOthers) { + // ★ 同步照片:询问是否全部删除 + const otherCount = refCount - 1 + try { + const action = await ElMessageBox.confirm( + `此照片当前被 ${refCount} 行使用(含本行)。\n\n` + + `• 【全部删除】将移除所有行中的该照片,并删除服务器文件\n` + + `• 【仅移出此行】只从当前行移除引用,其他行保留(不删服务器文件)`, + '删除照片', + { + confirmButtonText: '全部删除', + cancelButtonText: '仅移出此行', + distinguishCancelAndClose: true, + type: 'warning' + } + ) + // 用户点【全部删除】 + formItems.value.forEach(r => { + r.images = (r.images || []).filter(u => u !== urlToRemove) + r.fileList = (r.fileList || []).filter(f => f.url !== uploadFile.url && f.url !== urlToRemove) + }) + if (isInternal) await deleteFile(filename).catch(() => {}) + ElMessage.success(`已从 ${refCount} 行删除该照片`) + } catch (action) { + if (action === 'cancel') { + // 用户点【仅移出此行】 + row.images = (row.images || []).filter(u => u !== urlToRemove) + row.fileList = (row.fileList || []).filter(f => f.url !== uploadFile.url && f.url !== urlToRemove) + ElMessage.success('已从当前行移除该照片,其他行保留') + } + // close 或直接关闭 → 不操作 + } + } else { + // 普通删除:仅当前行引用,确认后删除 + try { + await ElMessageBox.confirm( + `确定删除这张照片吗?删除后不可恢复。`, + '删除照片', + { confirmButtonText: '删除', cancelButtonText: '取消', type: 'warning' } + ) + row.images = (row.images || []).filter(u => u !== urlToRemove) + row.fileList = (row.fileList || []).filter(f => f.url !== uploadFile.url && f.url !== urlToRemove) + if (isInternal) await deleteFile(filename).catch(() => {}) + ElMessage.success('照片已删除') + } catch (e) { + // 用户取消,不操作 + } } }