diff --git a/src/app/router/index.test.ts b/src/app/router/index.test.ts index ece2e605..31f06b36 100644 --- a/src/app/router/index.test.ts +++ b/src/app/router/index.test.ts @@ -81,12 +81,10 @@ describe('admin router access metadata', () => { it('registers the confirmed phase-four routes with stable list permissions', () => { const expected = [ - ['overseas-last-mile-orders', '/overseas-warehouse/last-mile-orders', 'platform:overseas-warehouse:last-mile-order:list'], + ['overseas-last-mile-orders', '/overseas-warehouse/last-mile-orders', 'platform:lastleg:order:list'], ['overseas-inbound-orders', '/overseas-warehouse/inbound-orders', 'platform:lastleg:inbound-plan:list'], - ['overseas-relabel-orders', '/overseas-warehouse/relabel-orders', 'platform:overseas-warehouse:relabel-order:list'], + ['overseas-relabel-orders', '/overseas-warehouse/relabel-orders', 'platform:lastleg:relabel:list'], ['overseas-pallets', '/overseas-warehouse/pallets', 'platform:pallet:list'], - ['overseas-cartons', '/overseas-warehouse/cartons', 'platform:overseas-warehouse:carton:list'], - ['overseas-products', '/overseas-warehouse/products', 'platform:overseas-warehouse:product:list'], ['overseas-inventory', '/overseas-warehouse/inventory', 'platform:lastleg:inventory:list'], ['overseas-business-purchases', '/overseas-business/purchases', 'platform:overseas-business:purchase:list'], ['overseas-business-trucks', '/overseas-business/trucks', 'platform:overseas-business:truck:list'], diff --git a/src/core/navigation/adminNavigation.test.ts b/src/core/navigation/adminNavigation.test.ts index 42ac5a27..871f046d 100644 --- a/src/core/navigation/adminNavigation.test.ts +++ b/src/core/navigation/adminNavigation.test.ts @@ -52,8 +52,6 @@ describe('adminNavigation', () => { '入库单', '换标单', '托盘管理', - '箱号管理', - '产品库', '库存管理', ]) expect(adminNavigation.find((item) => item.key === 'general')?.children?.map((item) => item.title)).toEqual([ @@ -139,12 +137,10 @@ describe('adminNavigation', () => { it('shows only the confirmed phase-four pages with their list permissions', () => { const filtered = filterAdminNavigation(adminNavigation, new Set([ - 'platform:overseas-warehouse:last-mile-order:list', + 'platform:lastleg:order:list', 'platform:lastleg:inbound-plan:list', - 'platform:overseas-warehouse:relabel-order:list', + 'platform:lastleg:relabel:list', 'platform:pallet:list', - 'platform:overseas-warehouse:carton:list', - 'platform:overseas-warehouse:product:list', 'platform:lastleg:inventory:list', 'platform:overseas-business:purchase:list', 'platform:overseas-business:truck:list', @@ -160,8 +156,6 @@ describe('adminNavigation', () => { '/overseas-warehouse/inbound-orders', '/overseas-warehouse/relabel-orders', '/overseas-warehouse/pallets', - '/overseas-warehouse/cartons', - '/overseas-warehouse/products', '/overseas-warehouse/inventory', '/overseas-business/purchases', '/overseas-business/trucks', @@ -170,6 +164,8 @@ describe('adminNavigation', () => { '/overseas-master-data/quotes', '/overseas-master-data/vehicles', ])) + expect(paths).not.toContain('/overseas-warehouse/cartons') + expect(paths).not.toContain('/overseas-warehouse/products') expect(paths.some((path) => path.includes('outbound') || path.includes('delivery'))).toBe(false) }) diff --git a/src/core/navigation/adminNavigation.ts b/src/core/navigation/adminNavigation.ts index 0834b632..fe6cd796 100644 --- a/src/core/navigation/adminNavigation.ts +++ b/src/core/navigation/adminNavigation.ts @@ -120,12 +120,10 @@ export const adminNavigation: AdminNavigationNode[] = [ title: '海外仓', icon: PrototypeOverseasWarehouseIcon, children: [ - { key: 'last-mile-orders', title: '尾程订单', icon: ClipboardList, path: '/overseas-warehouse/last-mile-orders', permission: 'platform:overseas-warehouse:last-mile-order:list' }, + { key: 'last-mile-orders', title: '尾程订单', icon: ClipboardList, path: '/overseas-warehouse/last-mile-orders', permission: 'platform:lastleg:order:list' }, { key: 'fba-inbound-order', title: '入库单', icon: ClipboardList, path: '/overseas-warehouse/inbound-orders', permission: 'platform:lastleg:inbound-plan:list' }, - { key: 'fba-relabel-order', title: '换标单', icon: ClipboardList, path: '/overseas-warehouse/relabel-orders', permission: 'platform:overseas-warehouse:relabel-order:list' }, + { key: 'fba-relabel-order', title: '换标单', icon: ClipboardList, path: '/overseas-warehouse/relabel-orders', permission: 'platform:lastleg:relabel:list' }, { key: 'fba-pallet', title: '托盘管理', icon: WarehouseIcon, path: '/overseas-warehouse/pallets', permission: 'platform:pallet:list' }, - { key: 'fba-carton', title: '箱号管理', icon: ClipboardList, path: '/overseas-warehouse/cartons', permission: 'platform:overseas-warehouse:carton:list' }, - { key: 'fba-product', title: '产品库', icon: Database, path: '/overseas-warehouse/products', permission: 'platform:overseas-warehouse:product:list' }, { key: 'overseas-inventory-list', title: '库存管理', icon: WarehouseIcon, path: '/overseas-warehouse/inventory', permission: 'platform:lastleg:inventory:list' }, ], }, diff --git a/src/modules/container-loading/api/platformContainerLoading.test.ts b/src/modules/container-loading/api/platformContainerLoading.test.ts index 64597b7c..0bab530f 100644 --- a/src/modules/container-loading/api/platformContainerLoading.test.ts +++ b/src/modules/container-loading/api/platformContainerLoading.test.ts @@ -15,7 +15,7 @@ vi.mock('@/shared/api/http', () => ({ unwrapApiResponse: (response: { data: T }) => response.data, })) -const container = { id: 9007199254740993, planId: 9007199254740994, planNo: 'LP-001', warehouseId: 9007199254740995, shippingCompanyId: 9007199254740996, sourceType: 'SIMULATION', recordStatus: 'ACTIVE', mergedIntoContainerBookingId: null, channelCode: 'NY_EXX', channelName: '纽约EXX海铁', exceptionActive: true, destinationClearanceDocumentStatus: 'COMPLETED', customsDeclarationDocumentStatus: 'UPLOADED', deliveryOrderDocumentStatus: 'UPLOADED', pickupOrderDocumentStatus: 'MISSING', version: '2', capacityCbm: '76', maxWeightKg: '28000' } +const container = { id: 9007199254740993, planId: 9007199254740994, planNo: 'LP-001', warehouseId: 9007199254740995, shippingCompanyId: 9007199254740996, sourceType: 'SIMULATION', recordStatus: 'ACTIVE', mergedIntoContainerBookingId: null, channelCode: 'NY_EXX', channelName: '纽约EXX海铁', exceptionActive: true, destinationClearanceDocumentStatus: 'COMPLETED', customsDeclarationDocumentStatus: 'UPLOADED', deliveryOrderDocumentStatus: 'UPLOADED', pickupOrderDocumentStatus: 'MISSING', unloadingCompletedAt: '2026-08-20T10:00:00', unloadingPhotoUploadedAt: '2026-08-20T10:15:00', estimatedEmptyReportedAt: '2026-08-21T09:00:00', actualEmptyReportedAt: null, emptyReportSourceVersion: '9007199254740997', version: '2', capacityCbm: '76', maxWeightKg: '28000' } const plan = { id: 9007199254740993, bookingId: 9007199254740994, version: '3', status: 'LOADING', canAssign: true, canEdit: true, blockedReason: null, finalCompletionStatus: 'NOT_STARTED', @@ -38,7 +38,7 @@ describe('platform container loading API', () => { it('normalizes paged container ids and numeric metadata', async () => { vi.mocked(http.get).mockResolvedValueOnce({ code: '200', data: { records: [container], page: '1', size: '20', total: '1', pages: '1' } }) const result = await listContainers({ page: 1, size: 20 }) - expect(result.records[0]).toMatchObject({ id: String(container.id), planId: String(container.planId), planNo: 'LP-001', warehouseId: String(container.warehouseId), channelCode: 'NY_EXX', channelName: '纽约EXX海铁', exceptionActive: true, destinationClearanceDocumentStatus: 'COMPLETED', customsDeclarationDocumentStatus: 'UPLOADED', deliveryOrderDocumentStatus: 'UPLOADED', pickupOrderDocumentStatus: 'MISSING', version: 2, capacityCbm: 76 }) + expect(result.records[0]).toMatchObject({ id: String(container.id), planId: String(container.planId), planNo: 'LP-001', warehouseId: String(container.warehouseId), channelCode: 'NY_EXX', channelName: '纽约EXX海铁', exceptionActive: true, destinationClearanceDocumentStatus: 'COMPLETED', customsDeclarationDocumentStatus: 'UPLOADED', deliveryOrderDocumentStatus: 'UPLOADED', pickupOrderDocumentStatus: 'MISSING', unloadingCompletedAt: '2026-08-20T10:00:00', unloadingPhotoUploadedAt: '2026-08-20T10:15:00', estimatedEmptyReportedAt: '2026-08-21T09:00:00', actualEmptyReportedAt: null, emptyReportSourceVersion: '9007199254740997', version: 2, capacityCbm: 76 }) expect(http.get).toHaveBeenCalledWith('/platform/v1/containers', { params: { page: 1, size: 20 } }) }) diff --git a/src/modules/container-loading/api/platformContainerLoading.ts b/src/modules/container-loading/api/platformContainerLoading.ts index c9f08f86..06e7fa10 100644 --- a/src/modules/container-loading/api/platformContainerLoading.ts +++ b/src/modules/container-loading/api/platformContainerLoading.ts @@ -76,6 +76,7 @@ function container(raw: ContainerBookingResource): ContainerBookingResource { oceanBookingRequirementId: optionalId(raw.oceanBookingRequirementId), customerId: optionalId(raw.customerId), shippingCompanyId: optionalId(raw.shippingCompanyId), + emptyReportSourceVersion: optionalId(raw.emptyReportSourceVersion), version: numberValue(raw.version), capacityCbm: raw.capacityCbm == null ? null : numberValue(raw.capacityCbm), maxWeightKg: raw.maxWeightKg == null ? null : numberValue(raw.maxWeightKg), diff --git a/src/modules/container-loading/pages/ContainerDetailView.test.ts b/src/modules/container-loading/pages/ContainerDetailView.test.ts index b98ac56b..9172914b 100644 --- a/src/modules/container-loading/pages/ContainerDetailView.test.ts +++ b/src/modules/container-loading/pages/ContainerDetailView.test.ts @@ -28,4 +28,13 @@ describe('ContainerDetailView', () => { expect(source).toContain(':ocean-booking-id="detail.oceanBookingId"') expect(source).toContain(':container-booking-id="detail.id"') }) + + it('shows overseas unloading and empty-report facts without adding upload or PDA actions', () => { + expect(source).toContain('detail.unloadingCompletedAt') + expect(source).toContain('detail.unloadingPhotoUploadedAt') + expect(source).toContain('detail.estimatedEmptyReportedAt') + expect(source).toContain('detail.actualEmptyReportedAt') + expect(source).not.toContain('uploadUnloadingPhoto') + expect(source).not.toContain('submitEmptyReport') + }) }) diff --git a/src/modules/container-loading/pages/ContainerDetailView.vue b/src/modules/container-loading/pages/ContainerDetailView.vue index 8a2f600d..16af6b11 100644 --- a/src/modules/container-loading/pages/ContainerDetailView.vue +++ b/src/modules/container-loading/pages/ContainerDetailView.vue @@ -153,7 +153,7 @@ onMounted(async () => { await load(); if (route.query.action === 'documents') op