From 2dd777d74a9dc2ca54134b8d467d30fa0313df89 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Wed, 9 Sep 2026 13:00:45 +0800 Subject: [PATCH] fix(admin): load outbound facts when access becomes ready --- .../components/ContainerCustomsPanel.vue | 4 +-- ...nerDetailView.emptyReturn.behavior.test.ts | 25 +++++++++++++++++++ .../pages/ContainerDetailView.vue | 19 ++++++++++---- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/modules/container-loading/components/ContainerCustomsPanel.vue b/src/modules/container-loading/components/ContainerCustomsPanel.vue index 3bb09b2d..0f290caf 100644 --- a/src/modules/container-loading/components/ContainerCustomsPanel.vue +++ b/src/modules/container-loading/components/ContainerCustomsPanel.vue @@ -23,7 +23,7 @@ const props = defineProps<{ loadingPlanId: string canList: boolean canManage: boolean - departureState: 'DEPARTED' | 'WAITING_OTHER_GATES' + departureState: 'DEPARTED' | 'WAITING_OTHER_GATES' | 'UNKNOWN' }>() const emit = defineEmits<{ refreshed: [] }>() @@ -182,7 +182,7 @@ onMounted(load) -
国内离仓状态:{{ departureState === 'DEPARTED' ? '已自动离仓' : '报关已完成,待其他离仓条件' }}
+
国内离仓状态:{{ departureState === 'DEPARTED' ? '已自动离仓' : departureState === 'UNKNOWN' ? '离仓状态尚未读取' : '报关已完成,待其他离仓条件' }}
diff --git a/src/modules/container-loading/pages/ContainerDetailView.emptyReturn.behavior.test.ts b/src/modules/container-loading/pages/ContainerDetailView.emptyReturn.behavior.test.ts index ece4fed0..f4e555e2 100644 --- a/src/modules/container-loading/pages/ContainerDetailView.emptyReturn.behavior.test.ts +++ b/src/modules/container-loading/pages/ContainerDetailView.emptyReturn.behavior.test.ts @@ -5,6 +5,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import ContainerDetailView from './ContainerDetailView.vue' import { getContainer, getContainerOverview } from '../api/platformContainerLoading' import { recordTerminalDrayageEmptyReturn } from '../api/terminalDrayages' +import { getContainerOutboundDispatch } from '@/modules/outbound-dispatch' +import { ref } from 'vue' const canAccess = vi.hoisted(() => vi.fn<(code: string) => boolean>(() => true)) vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: canAccess }) })) @@ -29,11 +31,34 @@ async function mountDetail(workbench: 'DOMESTIC' | 'OVERSEAS' = 'OVERSEAS') { describe('ContainerDetailView empty return', () => { beforeEach(() => { canAccess.mockReset().mockReturnValue(true) + vi.mocked(getContainerOutboundDispatch).mockReset().mockResolvedValue({ aggregate: { dispatchStatus: 'WAITING_FOR_LOADING', gate: { inbounds: [] } }, timeline: [] } as never) vi.mocked(getContainer).mockReset().mockResolvedValue(base as never) vi.mocked(getContainerOverview).mockReset().mockResolvedValue(overview as never) vi.mocked(recordTerminalDrayageEmptyReturn).mockReset().mockResolvedValue({ ...base.terminalDrayage, status: 'EMPTY_RETURNED', version: 4, actualEmptyReturnAt: '2026-09-09T12:00:00', allowedActions: [] } as never) }) + it('loads departed gates exactly once when read permission arrives after the container detail', async () => { + const granted = ref(false) + canAccess.mockImplementation((code) => code === 'platform:firstleg:outbound-dispatch:view' ? granted.value : true) + const wrapper = await mountDetail('DOMESTIC') + expect(getContainerOutboundDispatch).not.toHaveBeenCalled() + granted.value = true + await flushPromises() + expect(getContainerOutboundDispatch).toHaveBeenCalledTimes(1) + expect(wrapper.text()).toContain('已确认离仓') + expect(wrapper.text()).toContain('整柜已确认离仓;') + expect(wrapper.text()).not.toContain('全部门禁已通过,可确认整柜离仓') + }) + + it('reloads authoritative departure state once on each newly opened domestic detail', async () => { + const first = await mountDetail('DOMESTIC') + expect(first.text()).toContain('已确认离仓') + first.unmount() + const reopened = await mountDetail('DOMESTIC') + expect(reopened.text()).toContain('已确认离仓') + expect(getContainerOutboundDispatch).toHaveBeenCalledTimes(2) + }) + it.each(['DOMESTIC', 'OVERSEAS'] as const)('gates fee tabs by granted permissions in %s', async (workbench) => { for (const [firstLeg, lastLeg] of [[true, false], [false, true], [true, true], [false, false]]) { canAccess.mockImplementation((code) => code === 'firstleg:inbound:fee-detail:view' ? firstLeg! : code === 'platform:finance:customer-arap:list' ? lastLeg! : false) diff --git a/src/modules/container-loading/pages/ContainerDetailView.vue b/src/modules/container-loading/pages/ContainerDetailView.vue index cbd5496b..000752d3 100644 --- a/src/modules/container-loading/pages/ContainerDetailView.vue +++ b/src/modules/container-loading/pages/ContainerDetailView.vue @@ -1,5 +1,5 @@