diff --git a/src/modules/overseas-warehouse/api/relabelOrders.ts b/src/modules/overseas-warehouse/api/relabelOrders.ts index b604f431..59a14a2c 100644 --- a/src/modules/overseas-warehouse/api/relabelOrders.ts +++ b/src/modules/overseas-warehouse/api/relabelOrders.ts @@ -70,6 +70,10 @@ export interface RelabelSummaryDto { labelRequirement?: string | null totalFileId?: string | null totalFileName?: string | null + cartonTotalFileId?: string | null + cartonTotalFileName?: string | null + skuTotalFileId?: string | null + skuTotalFileName?: string | null totalFileUrl?: string | null chargeAmount?: number | string | null chargeCurrency?: string | null @@ -270,3 +274,9 @@ export async function downloadRelabelCompletionPhoto(relabelNo: string, fileId: { responseType: 'blob' }, ) } + +/** 通过平台授权入口读取贴标资料或面单。 */ +export async function downloadRelabelDocument(relabelNo: string, fileId: string, scope: string, itemId?: string) { + const base = '/platform/v1/last-leg/relabel-applications/' + encodeURIComponent(relabelNo) + return http.get(scope === 'SHIPPING' ? base + '/shipping-label/' + encodeURIComponent(fileId) + '/download' : base + '/files/' + encodeURIComponent(fileId) + '/download', { params: scope === 'SHIPPING' ? undefined : { scope, itemId }, responseType: 'blob' }) +} diff --git a/src/modules/overseas-warehouse/api/warehouseTransfers.ts b/src/modules/overseas-warehouse/api/warehouseTransfers.ts index 03793bfa..2e2e868a 100644 --- a/src/modules/overseas-warehouse/api/warehouseTransfers.ts +++ b/src/modules/overseas-warehouse/api/warehouseTransfers.ts @@ -227,3 +227,11 @@ export async function reviewWarehouseTransfer( ) return normalizeTransferDetail(unwrapApiResponse(response)) } + +/** 平台在指定客户范围内追加整单预报箱数。 */ +export async function increaseWarehouseTransferForecast(customerId: string, transferNo: string, payload: { expectedPackageCount: number; packageCount: number }) { + const response = await http.post, ApiEnvelope>( + '/platform/v1/last-leg/warehouse-transfers/' + encodeURIComponent(transferNo) + '/increase-forecast-cartons', payload, { params: { customerId } }, + ) + return unwrapApiResponse(response) +} diff --git a/src/modules/overseas-warehouse/components/RelabelDocumentsPanel.test.ts b/src/modules/overseas-warehouse/components/RelabelDocumentsPanel.test.ts new file mode 100644 index 00000000..4ed31d13 --- /dev/null +++ b/src/modules/overseas-warehouse/components/RelabelDocumentsPanel.test.ts @@ -0,0 +1,37 @@ +import { mount, flushPromises, enableAutoUnmount } from '@vue/test-utils' +import ElementPlus from 'element-plus' +import { afterEach, describe, expect, it, vi } from 'vitest' +import RelabelDocumentsPanel from './RelabelDocumentsPanel.vue' +import { getRelabelOrder, downloadRelabelDocument, type RelabelDetailDto } from '../api/relabelOrders' +vi.mock('../api/relabelOrders', () => ({ getRelabelOrder: vi.fn(), downloadRelabelDocument: vi.fn() })) +enableAutoUnmount(afterEach) +const detail = { application: { id: '1', relabelNo: 'RL-1', cartonTotalFileId: '11', cartonTotalFileName: '箱唛.pdf', skuTotalFileId: '12', skuTotalFileName: 'SKU.pdf', totalFileId: '12', totalFileName: 'SKU.pdf', shippingLabelFileId: '13', shippingLabelFileName: '面单.pdf' }, items: [{ id: '22', cartonMark: 'BX-1', skuCode: 'SKU-A', relabelFileId: '14', relabelFileName: '明细.pdf' }], history: [] } as RelabelDetailDto +const mountPanel = (value = detail) => mount(RelabelDocumentsPanel, { props: { relabelNo: 'RL-1', detail: value }, global: { plugins: [ElementPlus] } }) +describe('贴标附件回显', () => { + it('分别显示两类总文件、面单与箱明细,兼容总文件不重复', async () => { + 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(getRelabelOrder).not.toHaveBeenCalled() + }) + it('预览请求使用申请号、文件分类及明细编号,并可重试失败请求', async () => { + vi.mocked(downloadRelabelDocument).mockRejectedValue(new Error('文件暂不可用')) + const wrapper = mountPanel(); await flushPromises() + const rows = wrapper.findAll('.el-table__body tbody tr') + await rows[3]!.findAll('button')[0]!.trigger('click'); await flushPromises() + expect(downloadRelabelDocument).toHaveBeenLastCalledWith('RL-1', '14', 'ITEM', '22') + expect(rows[3]!.find('button').attributes('disabled')).toBeUndefined() + await rows[2]!.findAll('button')[0]!.trigger('click'); await flushPromises() + expect(downloadRelabelDocument).toHaveBeenLastCalledWith('RL-1', '13', 'SHIPPING', undefined) + }) + it('资料加载失败可单独重试,不冒充空附件', async () => { + vi.mocked(getRelabelOrder).mockRejectedValueOnce(new Error('资料加载失败')).mockResolvedValueOnce(detail) + 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') + }) +}) diff --git a/src/modules/overseas-warehouse/components/RelabelDocumentsPanel.vue b/src/modules/overseas-warehouse/components/RelabelDocumentsPanel.vue new file mode 100644 index 00000000..609ce0e8 --- /dev/null +++ b/src/modules/overseas-warehouse/components/RelabelDocumentsPanel.vue @@ -0,0 +1,82 @@ + +