diff --git a/src/modules/overseas-warehouse/components/RelabelDocumentsPanel.test.ts b/src/modules/overseas-warehouse/components/RelabelDocumentsPanel.test.ts index 4ed31d13..c37fc4fa 100644 --- a/src/modules/overseas-warehouse/components/RelabelDocumentsPanel.test.ts +++ b/src/modules/overseas-warehouse/components/RelabelDocumentsPanel.test.ts @@ -12,12 +12,13 @@ describe('贴标附件回显', () => { const wrapper = mountPanel(); await flushPromises() const rows = wrapper.findAll('.el-table__body tbody tr') expect(rows).toHaveLength(4) - expect(wrapper.text()).toContain('箱唛.pdf'); expect(wrapper.text()).toContain('SKU.pdf') - expect(wrapper.text()).toContain('面单.pdf'); expect(wrapper.text()).toContain('明细.pdf') - expect(wrapper.text()).toContain('BX-1 / SKU-A') + expect(wrapper.text()).toContain('箱唛贴标文件'); expect(wrapper.text()).toContain('SKU 贴标文件') + expect(wrapper.text()).toContain('面单文件'); expect(wrapper.text()).toContain('明细文件') + expect(wrapper.text()).not.toContain('BX-1 / SKU-A'); expect(wrapper.text()).not.toContain('文件名称'); expect(wrapper.text()).not.toContain('查看'); expect(wrapper.text()).not.toContain('箱唛.pdf') + expect(wrapper.findAll('thead th')).toHaveLength(2) expect(getRelabelOrder).not.toHaveBeenCalled() }) - it('预览请求使用申请号、文件分类及明细编号,并可重试失败请求', async () => { + it('下载请求使用申请号、文件分类及明细编号,并可重试失败请求', async () => { vi.mocked(downloadRelabelDocument).mockRejectedValue(new Error('文件暂不可用')) const wrapper = mountPanel(); await flushPromises() const rows = wrapper.findAll('.el-table__body tbody tr') @@ -32,6 +33,6 @@ describe('贴标附件回显', () => { const wrapper = mount(RelabelDocumentsPanel, { props: { relabelNo: 'RL-1' }, global: { plugins: [ElementPlus] } }); await flushPromises() expect(wrapper.get('[role="alert"]').text()).toContain('资料加载失败') await wrapper.get('[role="alert"] button').trigger('click'); await flushPromises() - expect(wrapper.text()).toContain('箱唛.pdf') + expect(wrapper.text()).toContain('箱唛贴标文件') }) }) diff --git a/src/modules/overseas-warehouse/components/RelabelDocumentsPanel.vue b/src/modules/overseas-warehouse/components/RelabelDocumentsPanel.vue index 609ce0e8..56e7d6d9 100644 --- a/src/modules/overseas-warehouse/components/RelabelDocumentsPanel.vue +++ b/src/modules/overseas-warehouse/components/RelabelDocumentsPanel.vue @@ -7,9 +7,6 @@ const loaded = ref(null) const loading = ref(false) const error = ref('') const busy = ref(false) -const previewUrl = ref('') -const previewOpen = ref(false) -const previewTitle = ref('') let generation = 0 const current = computed(() => props.detail || loaded.value) /** 各申请分别加载,失败只影响资料区,不阻断订单详情。 */ @@ -22,28 +19,26 @@ async function load() { catch (cause) { if (ticket === generation) error.value = cause instanceof Error ? cause.message : '贴标资料加载失败' } finally { if (ticket === generation) loading.value = false } } -watch(() => [props.relabelNo, props.detail], () => { clearPreview(); void load() }, { immediate: true }) -interface DocumentRow { key: string; kind: string; fileId: string; fileName: string; scope: string; itemId?: string; context?: string } +watch(() => [props.relabelNo, props.detail], () => { void load() }, { immediate: true }) +interface DocumentRow { key: string; kind: string; fileId: string; fileName: string; scope: string; itemId?: string } const documents = computed(() => { const result: DocumentRow[] = [] const application = current.value?.application if (!application) return result // 旧总文件仅作为兼容回显,避免与已分类型的总文件重复展示。 - const add = (kind: string, id: string | null | undefined, name: string | null | undefined, scope: string, itemId?: string, context?: string) => { - if (id) result.push({ key: scope + ':' + (itemId || '') + ':' + id, kind, fileId: id, fileName: name || '未命名文件', scope, itemId, context }) + const add = (kind: string, id: string | null | undefined, name: string | null | undefined, scope: string, itemId?: string) => { + if (id) result.push({ key: scope + ':' + (itemId || '') + ':' + id, kind, fileId: id, fileName: name || '未命名文件', scope, itemId }) } - add('箱唛总文件', application.cartonTotalFileId, application.cartonTotalFileName, 'CARTON_TOTAL') - add('SKU 标签总文件', application.skuTotalFileId, application.skuTotalFileName, 'SKU_TOTAL') + add('箱唛贴标文件', application.cartonTotalFileId, application.cartonTotalFileName, 'CARTON_TOTAL') + add('SKU 贴标文件', application.skuTotalFileId, application.skuTotalFileName, 'SKU_TOTAL') if (application.totalFileId !== application.cartonTotalFileId && application.totalFileId !== application.skuTotalFileId) add('贴标总文件', application.totalFileId, application.totalFileName, 'TOTAL') add('面单文件', application.shippingLabelFileId, application.shippingLabelFileName, 'SHIPPING') - for (const item of current.value?.items || []) add('明细文件', item.relabelFileId, item.relabelFileName, 'ITEM', String(item.id), [item.cartonMark, item.skuCode].filter(Boolean).join(' / ')) + for (const item of current.value?.items || []) add('明细文件', item.relabelFileId, item.relabelFileName, 'ITEM', String(item.id)) return result }) -/** 切换申请及关闭预览时释放文件对象。 */ -function clearPreview() { if (previewUrl.value) URL.revokeObjectURL(previewUrl.value); previewUrl.value = ''; previewOpen.value = false } -/** 使用带身份认证的下载接口,预览和保存共享同一归属校验。 */ -async function openFile(key: string, download = false) { +/** 使用带身份认证的下载接口,保留文件归属校验和原始文件名。 */ +async function downloadFile(key: string) { const row = documents.value.find(document => document.key === key) if (!row || busy.value) return busy.value = true @@ -51,32 +46,25 @@ async function openFile(key: string, download = false) { try { const blob = await downloadRelabelDocument(props.relabelNo, row.fileId, row.scope, row.itemId) if (ticket !== generation) return - if (download) { - const url = URL.createObjectURL(blob); const link = document.createElement('a') - link.href = url; link.download = row.fileName; link.click(); window.setTimeout(() => URL.revokeObjectURL(url), 1000) - } else { clearPreview(); previewUrl.value = URL.createObjectURL(blob); previewTitle.value = row.fileName; previewOpen.value = true } + const url = URL.createObjectURL(blob); const link = document.createElement('a') + link.href = url; link.download = row.fileName; link.click(); window.setTimeout(() => URL.revokeObjectURL(url), 1000) } catch (cause) { ElMessage.error(cause instanceof Error ? cause.message : '文件读取失败,请重试') } finally { busy.value = false } } -onBeforeUnmount(() => { ++generation; clearPreview() }) +onBeforeUnmount(() => { ++generation })