diff --git a/src/shared/components/InboundCodeRelationshipDrawer.test.ts b/src/shared/components/InboundCodeRelationshipDrawer.test.ts
index 949a3117..9926df7b 100644
--- a/src/shared/components/InboundCodeRelationshipDrawer.test.ts
+++ b/src/shared/components/InboundCodeRelationshipDrawer.test.ts
@@ -1,10 +1,114 @@
import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'
-import { describe, expect, it } from 'vitest'
+import { defineComponent } from 'vue'
+import { flushPromises, mount } from '@vue/test-utils'
+import { beforeEach, describe, expect, it, vi } from 'vitest'
+import {
+ getLoadingAssociationSummary,
+ getOverseasInboundCodeRelationship,
+ getPlatformInboundCodeAssociation,
+} from '@/shared/api/inboundCodeRelations'
+import InboundCodeRelationshipDrawer from './InboundCodeRelationshipDrawer.vue'
+
+vi.mock('@/shared/api/inboundCodeRelations', () => ({
+ getLoadingAssociationSummary: vi.fn(),
+ getOverseasInboundCodeRelationship: vi.fn(),
+ getPlatformInboundCodeAssociation: vi.fn(),
+}))
const source = readFileSync(resolve(process.cwd(), 'src/shared/components/InboundCodeRelationshipDrawer.vue'), 'utf8')
+const AppDrawerStub = defineComponent({
+ props: { modelValue: Boolean, title: String, loading: Boolean },
+ emits: ['update:modelValue'],
+ template: '',
+})
+
+function mountDrawer() {
+ return mount(InboundCodeRelationshipDrawer, {
+ props: {
+ modelValue: true,
+ inboundCode: 'NYEXX2608300027',
+ canReadBase: true,
+ canReadLoading: true,
+ canReadOverseas: true,
+ },
+ global: {
+ stubs: {
+ AppDrawer: AppDrawerStub,
+ ApiErrorMeta: true,
+ LoadErrorState: true,
+ StatusBadge: true,
+ 'el-alert': true,
+ 'el-empty': { props: ['description'], template: '
{{ description }}
' },
+ 'el-table': { props: ['data'], template: '{{ data[0]?.skuCode }}
' },
+ 'el-table-column': true,
+ },
+ },
+ })
+}
describe('InboundCodeRelationshipDrawer contract', () => {
+ beforeEach(() => {
+ vi.clearAllMocks()
+ vi.mocked(getPlatformInboundCodeAssociation).mockResolvedValue({
+ inboundCode: 'NYEXX2608300027', orderNo: 'FL2093975748931063810', orderStatus: 'APPROVED',
+ orderId: '90071992547409931', customerId: '90071992547409932', customerName: '纽约客户',
+ destinationType: 'FBA', destinationWarehouseId: '90071992547409933', destinationWarehouseCode: 'ABE3', destinationWarehouseName: '亚马逊 ABE3 仓',
+ })
+ vi.mocked(getLoadingAssociationSummary).mockResolvedValue({
+ inboundId: '90071992547409934', inboundCode: 'NYEXX2608300027', orderNo: 'FL2093975748931063810',
+ loadingPlanId: '90071992547409935', loadingPlanNo: 'LP-260830-0016', containerBookingId: '90071992547409936',
+ cabinetNo: 'CAB-260830-0016', containerNo: null, loadingStatus: 'LOADING', taskId: '90071992547409937',
+ pdaTaskStatus: 'IN_PROGRESS', coLoadGroupId: null, coLoadGroupNo: null, items: [{ itemId: '90071992547409938' }],
+ })
+ vi.mocked(getOverseasInboundCodeRelationship).mockResolvedValue({
+ inboundCode: 'NYEXX2608300027', found: true,
+ customer: { customerId: '90071992547409932', customerName: '纽约客户' },
+ overseasWarehouse: { warehouseId: '90071992547409939', warehouseCode: 'LAX', warehouseName: '洛杉矶海外仓' },
+ overseasReceivingStatus: 'RECEIVING', taillegOrders: [{ orderNo: 'LL-260830-0001', orderStatus: 'PENDING' }],
+ inboundPlans: [{ planNo: 'IP-260830-0001', planStatus: 'READY', receivingStatus: 'WAITING' }],
+ palletCodes: ['PLT-LAX-001'], inventory: [{ skuCode: 'SKU-001', productNameZh: '测试商品', packageCount: 12 }],
+ })
+ })
+
+ it('loads all three sections on an initially open mount and reloads after closing and reopening', async () => {
+ const wrapper = mountDrawer()
+ await flushPromises()
+
+ expect(getPlatformInboundCodeAssociation).toHaveBeenCalledWith('NYEXX2608300027')
+ expect(getLoadingAssociationSummary).toHaveBeenCalledWith('NYEXX2608300027')
+ expect(getOverseasInboundCodeRelationship).toHaveBeenCalledWith('NYEXX2608300027')
+ expect(wrapper.text()).toContain('FL2093975748931063810')
+ expect(wrapper.text()).toContain('LP-260830-0016')
+ expect(wrapper.text()).toContain('CAB-260830-0016')
+ expect(wrapper.text()).toContain('纽约客户')
+ expect(wrapper.text()).toContain('洛杉矶海外仓')
+ expect(wrapper.text()).toContain('LL-260830-0001')
+ expect(wrapper.text()).toContain('IP-260830-0001')
+ expect(wrapper.text()).toContain('PLT-LAX-001')
+ expect(wrapper.text()).toContain('SKU-001')
+ expect(wrapper.text()).not.toMatch(/9007199254740993[1-9]/)
+
+ await wrapper.setProps({ modelValue: false })
+ await wrapper.setProps({ modelValue: true })
+ await flushPromises()
+ expect(getPlatformInboundCodeAssociation).toHaveBeenCalledTimes(2)
+ expect(getLoadingAssociationSummary).toHaveBeenCalledTimes(2)
+ expect(getOverseasInboundCodeRelationship).toHaveBeenCalledTimes(2)
+ })
+
+ it('keeps a server-declared overseas miss as a local empty state', async () => {
+ vi.mocked(getOverseasInboundCodeRelationship).mockResolvedValueOnce({
+ inboundCode: 'NYEXX2608300027', found: false, customer: null, overseasWarehouse: null,
+ overseasReceivingStatus: null, taillegOrders: [], inboundPlans: [], palletCodes: [], inventory: [],
+ })
+ const wrapper = mountDrawer()
+ await flushPromises()
+ expect(wrapper.text()).toContain('服务端未找到该入仓码的海外关联数据')
+ expect(wrapper.text()).toContain('FL2093975748931063810')
+ expect(wrapper.text()).toContain('LP-260830-0016')
+ })
+
it('loads only permission-authorized server read models and keeps failures isolated', () => {
expect(source).toContain('props.canReadBase')
expect(source).toContain('props.canReadLoading')
@@ -13,6 +117,7 @@ describe('InboundCodeRelationshipDrawer contract', () => {
expect(source).toContain('getLoadingAssociationSummary(code)')
expect(source).toContain('getOverseasInboundCodeRelationship(code)')
expect(source).toContain('await Promise.all(tasks)')
+ expect(source).toContain('{ immediate: true }')
expect(source).toContain(' [props.modelValue, props.inboundCode, props.canReadBase, props.canReadLoading, props.canReadOverseas] as const, ([open]) => {
if (open) void load()
else serial += 1
-})
+}, { immediate: true })