From 114def1c11fce0e11f4c1b4b4cc6b557fd4f64f2 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Wed, 9 Sep 2026 18:29:47 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/ContainersView.test.ts | 34 ++++++++++++++++++- .../pages/ContainersView.vue | 34 +++++++++++++++---- 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/src/modules/container-loading/pages/ContainersView.test.ts b/src/modules/container-loading/pages/ContainersView.test.ts index 2433a23c..2f2a1610 100644 --- a/src/modules/container-loading/pages/ContainersView.test.ts +++ b/src/modules/container-loading/pages/ContainersView.test.ts @@ -175,7 +175,7 @@ describe('ContainersView', () => { expect(getTerminalDrayage).not.toHaveBeenCalled() if (missing === 'historical unloaded snapshot') { const fleet = wrapper.findAllComponents({ name: 'ElSelect' }).find((select) => - select.props('placeholder') === '请选择车队' && select.element.closest('.el-table__body'), + select.props('placeholder') === '输入车队名称或联系人搜索' && select.element.closest('.el-table__body'), ) expect(fleet).toBeDefined() expect(fleet!.props('disabled')).toBe(false) @@ -469,6 +469,7 @@ describe('ContainersView', () => { const vm = wrapper.vm as unknown as { rows: Array> + searchTerminalFleets: (keyword?: string) => Promise selectRowFleet: (row: Record, supplierId: string) => Promise openDrayageAction: (row: Record, action: 'RECORD_EMPTY_RETURN') => void drayageActionAt: string @@ -476,6 +477,7 @@ describe('ContainersView', () => { } const beforeFleet = await listContainers({ page: 1, size: 20 }, 'OVERSEAS') vi.mocked(listContainers).mockResolvedValueOnce({ ...beforeFleet, records: beforeFleet.records.map((row) => ({ ...row, terminalDrayage: { ...drayage, version: 4, fleetSupplierId: '502', allowedActions: [...drayage.allowedActions] } })) }) + await vm.searchTerminalFleets('新车队') await vm.selectRowFleet(vm.rows[0], '502') expect(selectTerminalDrayageFleet).toHaveBeenCalledWith('9001', { expectedVersion: 3, fleetSupplierId: '502', fleetSupplierName: '新车队' }) @@ -489,6 +491,33 @@ describe('ContainersView', () => { wrapper.unmount() }) + it('searches active terminal fleets remotely and ignores an older response', async () => { + const router = createTestRouter() + await router.push('/'); await router.isReady() + const wrapper = mount(ContainersView, { props: { workbench: 'OVERSEAS' }, global: { plugins: [ElementPlus, router] } }) + await flushPromises() + let resolveOld!: (value: Awaited>) => void + let resolveLatest!: (value: Awaited>) => void + vi.mocked(listSuppliers).mockReset() + .mockReturnValueOnce(new Promise((resolve) => { resolveOld = resolve })) + .mockReturnValueOnce(new Promise((resolve) => { resolveLatest = resolve })) + const vm = wrapper.vm as unknown as { + terminalFleetOptions: Array<{ id: string; name: string }> + searchTerminalFleets: (keyword?: string) => Promise + } + + const oldSearch = vm.searchTerminalFleets('旧关键词') + const latestSearch = vm.searchTerminalFleets('新车队') + expect(listSuppliers).toHaveBeenNthCalledWith(1, { page: 1, size: 20, category: 'TRUCKING', status: 'ACTIVE', keyword: '旧关键词' }) + expect(listSuppliers).toHaveBeenNthCalledWith(2, { page: 1, size: 20, category: 'TRUCKING', status: 'ACTIVE', keyword: '新车队' }) + resolveLatest({ records: [{ id: '503', name: '新车队', category: 'TRUCKING', status: 'ACTIVE' } as never], page: 1, size: 20, total: 1, pages: 1 }) + await latestSearch + resolveOld({ records: [{ id: '502', name: '旧车队', category: 'TRUCKING', status: 'ACTIVE' } as never], page: 1, size: 20, total: 1, pages: 1 }) + await oldSearch + expect(vm.terminalFleetOptions).toEqual([expect.objectContaining({ id: '503', name: '新车队' })]) + wrapper.unmount() + }) + it('loads terminal drayage detail and history only when requested', async () => { vi.mocked(getTerminalDrayageHistory).mockResolvedValueOnce([{ action: 'SELECT_FLEET', fromStatus: 'ARRIVED', toStatus: 'ARRIVED', fromVersion: 0, toVersion: 1, reason: '到港安排', operatorId: '88', operatorName: '管理员', createdAt: '2026-09-07T08:00:00' }]) const router = createTestRouter() @@ -802,7 +831,10 @@ describe('ContainersView trucking supplier contract', () => { it('uses active TRUCKING suppliers without allowing free-text carrier names', () => { const source = readFileSync(resolve(process.cwd(), 'src/modules/container-loading/pages/ContainersView.vue'), 'utf8') expect(source).toContain("listSuppliers({ page: 1, size: 200, category: 'TRUCKING', status: 'ACTIVE' })") + expect(source).toContain("page: 1, size: 20, category: 'TRUCKING', status: 'ACTIVE', keyword: keyword.trim() || undefined") expect(source).toContain("supplier.category === 'TRUCKING' && supplier.status === 'ACTIVE'") + expect(source).toContain('filterable remote reserve-keyword remote-show-suffix') + expect(source).toContain(':remote-method="searchTerminalFleets"') expect(source).toContain('selectTruckingSupplier') expect(source).toContain('请选择有效的合作中拖车供应商') expect(source).not.toContain('allow-create') diff --git a/src/modules/container-loading/pages/ContainersView.vue b/src/modules/container-loading/pages/ContainersView.vue index 22549aba..25710af1 100644 --- a/src/modules/container-loading/pages/ContainersView.vue +++ b/src/modules/container-loading/pages/ContainersView.vue @@ -52,6 +52,8 @@ const warehouses = ref([]) const destinationWarehouses = ref([]) const partners = ref([]) const truckingSuppliers = ref([]) +const terminalFleetOptions = ref([]) +const terminalFleetLoading = ref(false) const oceanBookings = ref([]) const loading = ref(false) const warehouseLoading = ref(false) @@ -161,6 +163,7 @@ let warehouseOptionsPromise: Promise | null = null let partnersLoaded = false let truckingSuppliersLoaded = false let truckingSuppliersPromise: Promise | null = null +let terminalFleetSearchSequence = 0 let oceanBookingsLoaded = false let businessOptionsPromise: Promise | null = null @@ -473,10 +476,26 @@ async function loadTruckingSuppliers(): Promise { try { return await truckingSuppliersPromise } finally { truckingSuppliersPromise = null } } -async function ensureTruckingSuppliers(open: unknown = true) { - if (!open) return false - try { await loadTruckingSuppliers(); return true } - catch (error) { ElMessage.error(getApiErrorDetails(error, '拖车供应商加载失败').message); return false } +async function searchTerminalFleets(keyword = '') { + const sequence = ++terminalFleetSearchSequence + terminalFleetLoading.value = true + try { + const result = await listSuppliers({ + page: 1, size: 20, category: 'TRUCKING', status: 'ACTIVE', keyword: keyword.trim() || undefined, + }) + if (sequence !== terminalFleetSearchSequence) return + terminalFleetOptions.value = result.records.filter((supplier) => supplier.category === 'TRUCKING' && supplier.status === 'ACTIVE') + } catch (error) { + if (sequence !== terminalFleetSearchSequence) return + terminalFleetOptions.value = [] + ElMessage.error(getApiErrorDetails(error, '码头车队搜索失败').message) + } finally { + if (sequence === terminalFleetSearchSequence) terminalFleetLoading.value = false + } +} +function handleTerminalFleetVisible(open: boolean) { + if (open) void searchTerminalFleets() + else { terminalFleetSearchSequence++; terminalFleetLoading.value = false } } async function loadAllPartners() { const firstPage = await listPlatformPartners({ page: 1, size: 200, status: 'ACTIVE' }) @@ -562,8 +581,9 @@ async function refreshDrayage(containerBookingId: string) { async function selectRowFleet(source: object, supplierIdValue: unknown) { const row = source as ContainerBookingResource const current = drayageFor(row.id) - if (!(await ensureTruckingSuppliers())) return - const supplier = truckingCompanies.value.find((item) => item.id === String(supplierIdValue || '')) + const supplierId = String(supplierIdValue || '') + const supplier = terminalFleetOptions.value.find((item) => item.id === supplierId) + || truckingCompanies.value.find((item) => item.id === supplierId) if (!current || !supplier || !canDrayage(row, 'SELECT_FLEET') || drayageSavingIds.value.includes(row.id)) return drayageSavingIds.value = [...drayageSavingIds.value, row.id] try { @@ -759,7 +779,7 @@ onMounted(async () => { - +