From 4ccad3bc3c132cf583b6d9baa33dfd05844c302e Mon Sep 17 00:00:00 2001
From: ouyangxq <775153912@qq.com>
Date: Wed, 9 Sep 2026 12:15:24 +0800
Subject: [PATCH] fix(admin): consume booking link actions when cached pages
reactivate
---
.../pages/ContainersView.test.ts | 60 ++++++++++++++++---
.../pages/ContainersView.vue | 23 ++++---
2 files changed, 69 insertions(+), 14 deletions(-)
diff --git a/src/modules/container-loading/pages/ContainersView.test.ts b/src/modules/container-loading/pages/ContainersView.test.ts
index 1e2ba78c..c86ff490 100644
--- a/src/modules/container-loading/pages/ContainersView.test.ts
+++ b/src/modules/container-loading/pages/ContainersView.test.ts
@@ -1,6 +1,7 @@
import ElementPlus from 'element-plus'
import { createPinia, setActivePinia } from 'pinia'
import { createMemoryHistory, createRouter } from 'vue-router'
+import { defineComponent } from 'vue'
import { flushPromises, mount } from '@vue/test-utils'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { readFileSync } from 'node:fs'
@@ -34,7 +35,7 @@ const drayage = {
function createTestRouter() {
return createRouter({ history: createMemoryHistory(), routes: [
- { path: '/', component: ContainersView },
+ { path: '/', name: 'domestic-container-workbench', component: ContainersView },
{ path: '/container-loading/domestic/:containerId/smart-loading', name: 'smart-loading-workbench', component: { template: '
' } },
{ path: '/loading-plans', name: 'loading-plans', component: { template: '' } },
{ path: '/container-loading/domestic/:containerId', name: 'domestic-container-detail', component: { template: '' } },
@@ -417,12 +418,57 @@ describe('ContainersView', () => {
wrapper.unmount()
})
- it('opens the existing released-booking workflow when entered from container detail', () => {
- const source = readFileSync(resolve(process.cwd(), 'src/modules/container-loading/pages/ContainersView.vue'), 'utf8')
- expect(source).toContain('route.query.linkContainerId')
- expect(source).toContain("const target = await getContainer(linkContainerId, 'DOMESTIC')")
- expect(source).toContain('await openLink(target)')
- expect(source).toContain("void router.replace({ name: 'domestic-container-workbench' })")
+ it('consumes the booking-link action once when returning to a cached list and preserves other query state', async () => {
+ vi.mocked(getContainer).mockClear()
+ vi.mocked(listContainers).mockClear()
+ vi.mocked(listOceanBookingLinkCandidates).mockClear().mockResolvedValue({ records: [], page: 1, size: 200, total: 0, pages: 0 })
+ const router = createTestRouter()
+ await router.push('/'); await router.isReady()
+ const shell = defineComponent({ template: '' })
+ const wrapper = mount(shell, { global: { plugins: [ElementPlus, router] } })
+ await flushPromises()
+ const initial = wrapper.findComponent(ContainersView).vm.$.uid
+ await router.push('/container-loading/domestic/9001')
+ await flushPromises()
+ await router.push({ name: 'domestic-container-workbench', query: { linkContainerId: '9001', keyword: 'CB-1' }, hash: '#table' })
+ await flushPromises()
+ expect(wrapper.findComponent(ContainersView).vm.$.uid).toBe(initial)
+ expect(getContainer).toHaveBeenCalledTimes(1)
+ expect(listOceanBookingLinkCandidates).toHaveBeenCalledTimes(1)
+ expect(listContainers).toHaveBeenCalledTimes(1)
+ expect(router.currentRoute.value.query).toEqual({ keyword: 'CB-1' })
+ expect(router.currentRoute.value.hash).toBe('#table')
+ const dialog = wrapper.findAllComponents(AppDialog).find((item) => item.props('title') === '关联已放舱订舱')!
+ expect(dialog.props('modelValue')).toBe(true)
+ dialog.vm.$emit('update:modelValue', false)
+ await flushPromises()
+ await router.push('/container-loading/domestic/9001')
+ await router.push({ name: 'domestic-container-workbench' })
+ await flushPromises()
+ expect(dialog.props('modelValue')).toBe(false)
+ expect(getContainer).toHaveBeenCalledTimes(1)
+ expect(listOceanBookingLinkCandidates).toHaveBeenCalledTimes(1)
+ wrapper.unmount()
+ })
+
+ it('ignores a stale linking response after leaving the list', async () => {
+ const target = await vi.mocked(getContainer).getMockImplementation()!('9001', 'DOMESTIC')
+ let finish!: (value: typeof target) => void
+ vi.mocked(getContainer).mockClear().mockImplementationOnce(() => new Promise((resolve) => { finish = resolve }))
+ vi.mocked(listOceanBookingLinkCandidates).mockClear()
+ const router = createTestRouter()
+ await router.push({ name: 'domestic-container-workbench', query: { linkContainerId: '9001' } }); await router.isReady()
+ const wrapper = mount(ContainersView, { global: { plugins: [ElementPlus, router] } })
+ await flushPromises()
+ await router.replace({ query: { linkContainerId: '9001', keyword: 'updated' } })
+ await flushPromises()
+ expect(getContainer).toHaveBeenCalledTimes(1)
+ await router.push('/container-loading/domestic/9001')
+ finish(target)
+ await flushPromises()
+ expect(listOceanBookingLinkCandidates).not.toHaveBeenCalled()
+ expect(router.currentRoute.value.name).toBe('domestic-container-detail')
+ wrapper.unmount()
})
it('normalizes an optional booking-link container number', async () => {
diff --git a/src/modules/container-loading/pages/ContainersView.vue b/src/modules/container-loading/pages/ContainersView.vue
index c8fc56c1..ce8f98dc 100644
--- a/src/modules/container-loading/pages/ContainersView.vue
+++ b/src/modules/container-loading/pages/ContainersView.vue
@@ -1,5 +1,5 @@