diff --git a/src/modules/overseas-warehouse/api/lastMileOrders.ts b/src/modules/overseas-warehouse/api/lastMileOrders.ts index cd9a2afa..8bdad927 100644 --- a/src/modules/overseas-warehouse/api/lastMileOrders.ts +++ b/src/modules/overseas-warehouse/api/lastMileOrders.ts @@ -99,7 +99,7 @@ export interface LastMileOrderSummaryDto { deliveryOrderNo?: string | null outboundOrderNo?: string | null relabelOrderNo?: string | null - relabelApplications?: Array<{ relabelNo: string; status: string; quantity: number; createdAt: string }> + relabelApplications?: Array<{ relabelNo: string; status: string; quantity: number; quantityUnit?: string; createdAt: string }> relabelStatus?: string | null palletMergeFlag?: string | null /** Optional grouping facts returned by newer last-leg services. */ @@ -359,7 +359,7 @@ export interface LastMileOrderDetailDto { order: { returnNo: string; status?: string; receivedQuantity: number; expectedQuantity: number } items?: Array<{ skuCode: string; productNameZh?: string; expectedQuantity: number; receivedQuantity: number }> receipts: Array<{ receiptNo: string; unitType: string; unitCode?: string; palletCode?: string; receivedQuantity: number; boxCount: number; signedAt: string }> - cartons?: Array<{ receiptNo: string; palletCode?: string; cartonMark: string; countStatus: string; countedAt?: string; items: Array<{ skuCode: string; productNameZh?: string; quantity: number }> }> + cartons?: Array<{ receiptNo: string; palletCode?: string; cartonMark: string; countStatus: string; countedAt?: string; items: Array<{ skuCode: string; productNameZh?: string; quantity: number }>; length?: number | null; width?: number | null; height?: number | null; weight?: number | null }> } | null order: LastMileOrderDto manualNodes?: ManualNodesResponse['nodes'] diff --git a/src/modules/overseas-warehouse/api/relabelOrders.ts b/src/modules/overseas-warehouse/api/relabelOrders.ts index fa450867..6a68a983 100644 --- a/src/modules/overseas-warehouse/api/relabelOrders.ts +++ b/src/modules/overseas-warehouse/api/relabelOrders.ts @@ -66,6 +66,8 @@ export interface RelabelSummaryDto { totalPackageCount?: number | null notifiedPackageCount?: number | null skuCodes?: string | null + productNameZh?: string | null + labelRequirement?: string | null totalFileId?: string | null totalFileName?: string | null totalFileUrl?: string | null @@ -87,6 +89,8 @@ export interface RelabelSummaryDto { export interface RelabelItemDto { id: string + operationType?: 'CARTON_LABEL' | 'SKU_LABEL' | 'CARTON_AND_SKU' + skuItems?: Array<{ skuCode: string; newSkuCode: string; quantity: number; remark?: string }> skuCode?: string | null productNameZh?: string | null totalPackageCount?: number | null diff --git a/src/modules/overseas-warehouse/pages/LastMileOrderDetailView.vue b/src/modules/overseas-warehouse/pages/LastMileOrderDetailView.vue index 3d4d34ee..64bb2bd1 100644 --- a/src/modules/overseas-warehouse/pages/LastMileOrderDetailView.vue +++ b/src/modules/overseas-warehouse/pages/LastMileOrderDetailView.vue @@ -57,6 +57,7 @@ function isSingleLineBusinessField(field: DetailField) { return field.label === const referenceValue = computed(() => lastMileOrderReference(detail.value?.order.orderNo, '订单编码待补充')) const isReturnOrder = computed(() => detail.value?.order.orderType === 'RETURN_RELABEL') +const returnReceiptUnitLabel = computed(() => detail.value?.returnReceipt?.receipts.some(receipt => receipt.unitType === 'PARCEL') ? '包裹' : '箱') const showReturnForecast = computed(() => isReturnOrder.value && (detail.value?.returnReceipt?.order.status ? detail.value.returnReceipt.order.status !== 'COMPLETED' : ['PENDING_REVIEW', 'PENDING_RECEIPT', 'PARTIALLY_RECEIVED', 'REJECTED', 'CANCELLED'].includes(detail.value?.order.currentStatus || ''))) @@ -168,7 +169,7 @@ const cargoColumns = computed(() => isReturnOrder.value ? [ { key: 'volume', prop: 'volume', label: '体积(m³)', width: 120, align: 'right' }, ]) const documentColumns: DataTableColumn[] = [ - { key: 'status', prop: 'status', label: '状态', minWidth: 130 }, { key: 'quantity', prop: 'quantity', label: '换标数量(件)', minWidth: 130 }, + { key: 'status', prop: 'status', label: '状态', minWidth: 130 }, { key: 'quantity', prop: 'quantity', label: '换标数量(箱/件)', minWidth: 150, formatter: (row: { quantity?: number; quantityUnit?: string }) => `${row.quantity ?? '—'}${row.quantityUnit || '件'}` }, { key: 'type', prop: 'type', label: '单据类型', minWidth: 150 }, { key: 'number', prop: 'number', label: '单据编号', minWidth: 200 }, { key: 'createdAt', prop: 'createdAt', label: '生成时间', minWidth: 170 }, { key: 'quote', prop: 'quote', label: '报价', minWidth: 150 }, ] @@ -249,11 +250,12 @@ onMounted(load) -

签收箱号明细({{ detail.returnReceipt.cartons?.length || 0 }} 箱)

+

签收{{ returnReceiptUnitLabel }}明细({{ detail.returnReceipt.cartons?.length || 0 }} {{ returnReceiptUnitLabel }})

签收单 {{ box.receiptNo }}

+

测量:{{ box.length ?? '—' }} × {{ box.width ?? '—' }} × {{ box.height ?? '—' }} cm · 重量 {{ box.weight ?? '—' }} kg

diff --git a/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.refresh.test.ts b/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.refresh.test.ts new file mode 100644 index 00000000..5c5be51e --- /dev/null +++ b/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.refresh.test.ts @@ -0,0 +1,27 @@ +import { KeepAlive, defineComponent, h, ref } from 'vue' +import { flushPromises, mount } from '@vue/test-utils' +import { expect, it, vi } from 'vitest' +import { getRelabelOrder } from '../api/relabelOrders' +import RelabelOrderDetailView from './RelabelOrderDetailView.vue' + +vi.mock('vue-router', () => ({ useRoute: () => ({ params: { orderId: 'RL-1' } }), useRouter: () => ({ push: vi.fn() }) })) +vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: () => false }) })) +vi.mock('../api/relabelOrders', () => ({ getRelabelOrder: vi.fn(), confirmRelabelCompletion: vi.fn(), getRelabelReviewTask: vi.fn(), returnRelabelForRework: vi.fn(), downloadRelabelCompletionPhoto: vi.fn(), downloadRelabelPdf: vi.fn(), uploadRelabelPdf: vi.fn() })) + +it('reloads authoritative status when a cached detail tab is reopened without double loading initially', async () => { + vi.mocked(getRelabelOrder).mockResolvedValueOnce({ application: { id: '1', relabelNo: 'RL-1', status: 'PENDING_REVIEW' }, items: [], history: [] }) + .mockResolvedValueOnce({ application: { id: '1', relabelNo: 'RL-1', status: 'PENDING_PROCESSING' }, items: [], history: [] }) + const active = ref(true) + const Host = defineComponent({ setup: () => () => h(KeepAlive, null, { default: () => active.value ? h(RelabelOrderDetailView) : h('div') }) }) + const wrapper = mount(Host, { global: { stubs: { OverseasReadOnlyDetail: true, AppDialog: true } } }) + await flushPromises() + expect(getRelabelOrder).toHaveBeenCalledTimes(1) + expect(wrapper.findComponent({ name: 'OverseasReadOnlyDetail' }).props('statusText')).toBe('待审核') + active.value = false + await flushPromises() + active.value = true + await flushPromises() + expect(getRelabelOrder).toHaveBeenCalledTimes(2) + expect(wrapper.findComponent({ name: 'OverseasReadOnlyDetail' }).props('statusText')).toBe('待处理') + wrapper.unmount() +}) diff --git a/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.test.ts b/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.test.ts index b4d8dd92..e85e7e64 100644 --- a/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.test.ts +++ b/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.test.ts @@ -18,6 +18,9 @@ describe('RelabelOrderDetailView', () => { expect(source).toContain("PENDING_REVIEW: '待审核'") expect(source).toContain('value?.application.customerOrderNo || value?.application.lastlegOrderNo') expect(source).toContain('item.destinationFbaWarehouseCode || item.destinationWarehouseId') + expect(source).toContain('items.flatMap(relabelSkuCodes)') + expect(source).toContain('v-for="(sku, index) in item.skuItems"') + expect(source).toContain('{{ sku.skuCode }} → {{ sku.newSkuCode }} × {{ sku.quantity }} 件') }) it('lets platform operators confirm completion or return PDA work for rework', () => { diff --git a/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.vue b/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.vue index 1cbd6500..32437077 100644 --- a/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.vue +++ b/src/modules/overseas-warehouse/pages/RelabelOrderDetailView.vue @@ -1,6 +1,6 @@ @@ -241,7 +242,7 @@ watch(dialogOpen, (open) => { if (!open) createIdempotencyKey.value = '' }) - + @@ -251,7 +252,7 @@ watch(dialogOpen, (open) => { if (!open) createIdempotencyKey.value = '' })

作业要求

- + diff --git a/src/modules/overseas-warehouse/pages/ReturnInventoryManagementView.vue b/src/modules/overseas-warehouse/pages/ReturnInventoryManagementView.vue index cf15f872..89476278 100644 --- a/src/modules/overseas-warehouse/pages/ReturnInventoryManagementView.vue +++ b/src/modules/overseas-warehouse/pages/ReturnInventoryManagementView.vue @@ -668,11 +668,10 @@ const tableColumns = computed(() => warehouseName(row.overseasWarehouseId) }}