From ef35a1be2e80a8585384049c058c8c1d86783ebc Mon Sep 17 00:00:00 2001 From: liuyihe <2513762445@qq.com> Date: Tue, 11 Aug 2026 14:23:46 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E8=A3=85=E6=9F=9C=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/GlobalSmartLoadingView.test.ts | 22 +++++++++++++++++++ .../pages/GlobalSmartLoadingView.vue | 6 ++--- .../api/platformLoadingLists.test.ts | 4 ++-- .../loading-lists/api/platformLoadingLists.ts | 2 +- .../components/LoadingListDetailDrawer.vue | 2 +- .../components/LoadingListsView.test.ts | 6 ++--- .../components/LoadingListsView.vue | 12 +++++----- 7 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/modules/container-loading/pages/GlobalSmartLoadingView.test.ts b/src/modules/container-loading/pages/GlobalSmartLoadingView.test.ts index ab9af385..1a1c075f 100644 --- a/src/modules/container-loading/pages/GlobalSmartLoadingView.test.ts +++ b/src/modules/container-loading/pages/GlobalSmartLoadingView.test.ts @@ -99,6 +99,28 @@ describe('GlobalSmartLoadingView', () => { expect(wrapper.text()).toContain('CB-1 装柜方案') }) + it('does not overwrite the container status when selecting it', async () => { + const waiting = { ...container, id: '9007199254740995', planId: '9007199254740996', cabinetNo: 'CB-WAIT', planStatus: 'WAIT_LOADING' as const } + vi.mocked(listContainers).mockResolvedValue({ records: [container, waiting], page: 1, size: 100, total: 2, pages: 1 }) + vi.mocked(getSmartLoadingPlanByBooking).mockImplementation(async (bookingId) => ( + bookingId === waiting.id + ? { ...plan, bookingId: waiting.id, status: 'LOADING' as const } + : plan + )) + const wrapper = mount(GlobalSmartLoadingView, { global: { plugins: [ElementPlus] } }) + await flushPromises() + + const waitingOption = wrapper.findAll('.container-option').find((item) => item.text().includes('CB-WAIT'))! + expect(waitingOption.text()).toContain('待装柜') + + await waitingOption.trigger('click') + await flushPromises() + + expect(getSmartLoadingPlanByBooking).toHaveBeenCalledWith(waiting.id) + expect(waitingOption.text()).toContain('待装柜') + expect(waitingOption.text()).not.toContain('拣货中') + }) + it('keeps picking containers editable while hiding the push action', async () => { const pushed = { ...container, id: '9007199254740995', planId: '9007199254740996', cabinetNo: 'CB-2', planStatus: 'LOADING' as const } const pickingPlan = { ...plan, bookingId: pushed.id, status: 'LOADING' as const } diff --git a/src/modules/container-loading/pages/GlobalSmartLoadingView.vue b/src/modules/container-loading/pages/GlobalSmartLoadingView.vue index fbc18ffd..c04cfa2f 100644 --- a/src/modules/container-loading/pages/GlobalSmartLoadingView.vue +++ b/src/modules/container-loading/pages/GlobalSmartLoadingView.vue @@ -142,14 +142,14 @@ function syncDrafts(next: SmartLoadingPlan, preserved: Record = for (const key of Object.keys(quantityDrafts)) delete quantityDrafts[key] for (const item of next.items || []) quantityDrafts[item.id] = preserved[item.id] ?? item.packageCount } -function acceptPlan(next: SmartLoadingPlan, preserved: Record = {}) { +function acceptPlan(next: SmartLoadingPlan, preserved: Record = {}, syncContainerStatus = true) { plan.value = next noDraft.value = false syncDrafts(next, preserved) const container = selectedContainer.value if (container) { container.planId = next.id - container.planStatus = next.status + if (syncContainerStatus) container.planStatus = next.status } } function clearSelectionData() { @@ -178,7 +178,7 @@ async function loadSelectedData(preserved: Record = {}) { ]) if (request !== selectionRequest) return candidates.value = candidateResult - if (planResult.value) acceptPlan(planResult.value, preserved) + if (planResult.value) acceptPlan(planResult.value, preserved, false) else noDraft.value = planResult.missing } catch (error) { if (request === selectionRequest) selectionError.value = getApiErrorDetails(error, '柜次装柜数据加载失败') diff --git a/src/modules/loading-lists/api/platformLoadingLists.test.ts b/src/modules/loading-lists/api/platformLoadingLists.test.ts index ab13132d..8c86a2f1 100644 --- a/src/modules/loading-lists/api/platformLoadingLists.test.ts +++ b/src/modules/loading-lists/api/platformLoadingLists.test.ts @@ -43,11 +43,11 @@ const detail = { describe('platform loading lists API', () => { beforeEach(() => vi.restoreAllMocks()) - it('queries preload plans across all warehouses with fixed LOADING status', async () => { + it('queries preload plans without forcing a status so EDITING and LOADING are returned', async () => { const get = vi.spyOn(http, 'get').mockResolvedValue({ code: '200', message: 'ok', data: { records: [preloadSummary], page: '1', size: '20', total: '1', pages: '1' } }) const result = await listPreloadPlans({ page: 1, size: 20, keyword: 'PL' }) - expect(get).toHaveBeenCalledWith('/platform/v1/first-leg/loading-plans', { params: { page: 1, size: 20, keyword: 'PL', status: 'LOADING' } }) + expect(get).toHaveBeenCalledWith('/platform/v1/first-leg/loading-plans', { params: { page: 1, size: 20, keyword: 'PL' } }) expect(result.total).toBe(1) expect(result.records[0]?.planId).toBe('1900000000000000001') expect(result.records[0]?.customers[0]?.accountId).toBe('1900000000000000002') diff --git a/src/modules/loading-lists/api/platformLoadingLists.ts b/src/modules/loading-lists/api/platformLoadingLists.ts index ab5e7fb1..7a0ad33b 100644 --- a/src/modules/loading-lists/api/platformLoadingLists.ts +++ b/src/modules/loading-lists/api/platformLoadingLists.ts @@ -203,7 +203,7 @@ function idempotencyKey(planId: string) { export async function listPreloadPlans(query: LoadingListQuery) { const response = await http.get>, ApiEnvelope>>( `${basePath}/loading-plans`, - { params: { ...query, status: 'LOADING' } }, + { params: query }, ) return normalizePage(unwrapApiResponse(response), normalizePreloadSummary) } diff --git a/src/modules/loading-lists/components/LoadingListDetailDrawer.vue b/src/modules/loading-lists/components/LoadingListDetailDrawer.vue index 79bd5839..f9e875c4 100644 --- a/src/modules/loading-lists/components/LoadingListDetailDrawer.vue +++ b/src/modules/loading-lists/components/LoadingListDetailDrawer.vue @@ -102,7 +102,7 @@ function formatNumber(value?: number | null, digits = 3) { -
+
编辑运输信息
diff --git a/src/modules/loading-lists/components/LoadingListsView.test.ts b/src/modules/loading-lists/components/LoadingListsView.test.ts index 54b7417f..c578c9a9 100644 --- a/src/modules/loading-lists/components/LoadingListsView.test.ts +++ b/src/modules/loading-lists/components/LoadingListsView.test.ts @@ -34,7 +34,7 @@ describe('LoadingListsView', () => { }) it('only exposes transport editing for LOADING preload details', () => { - expect(detailSource).toContain("mode === 'preload' && canEdit && summary.status === 'LOADING'") + expect(detailSource).toContain("mode === 'preload' && canEdit && ['EDITING', 'LOADING'].includes(summary.status)") expect(detailSource).toContain('装柜完成后清单、明细和运输信息永久只读') expect(source).toContain('expectedVersion: detail.value.summary.version') }) @@ -50,7 +50,7 @@ describe('LoadingListsView', () => { }) it('exposes a row edit action only for loading preload plans', () => { - expect(source).toContain("isPreload && canEdit && row.status === 'LOADING'") + expect(source).toContain("isPreload && canEdit && ['EDITING', 'LOADING'].includes(row.status)") expect(source).toContain('openEditFromRow(row)') expect(source).toContain('await loadDetail()') }) @@ -65,7 +65,7 @@ describe('LoadingListsView', () => { expect(source).toContain('useRoute()') expect(source).toContain('route.query.planId') expect(source).toContain('route.query.warehouseId') - expect(source).toContain("const expectedStatus = isPreload.value ? 'LOADING' : 'COMPLETED'") + expect(source).toContain("const expectedStatuses = isPreload.value ? ['EDITING', 'LOADING'] : ['COMPLETED']") expect(source).toContain('MODE_STATUS_MISMATCH') }) diff --git a/src/modules/loading-lists/components/LoadingListsView.vue b/src/modules/loading-lists/components/LoadingListsView.vue index e858e927..2802aa56 100644 --- a/src/modules/loading-lists/components/LoadingListsView.vue +++ b/src/modules/loading-lists/components/LoadingListsView.vue @@ -159,9 +159,9 @@ async function openDeepLinkedDetail() { detailError.value = null detailOpen.value = true await loadDetail() - const expectedStatus = isPreload.value ? 'LOADING' : 'COMPLETED' + const expectedStatuses = isPreload.value ? ['EDITING', 'LOADING'] : ['COMPLETED'] const loadedDetail = detail.value as LoadingDetail | null - if (loadedDetail && loadedDetail.summary.status !== expectedStatus) { + if (loadedDetail && !expectedStatuses.includes(loadedDetail.summary.status)) { detail.value = null detailError.value = { code: 'MODE_STATUS_MISMATCH', @@ -211,7 +211,7 @@ function openDetail(rowValue: object) { async function openEditFromRow(rowValue: object) { const row = rowValue as LoadingListSummary - if (!isPreload.value || !canEdit.value || row.status !== 'LOADING') return + if (!isPreload.value || !canEdit.value || !['EDITING', 'LOADING'].includes(row.status)) return selectedPlanId.value = String(row.planId) selectedWarehouseId.value = String(row.warehouseId || '') detail.value = null @@ -219,11 +219,11 @@ async function openEditFromRow(rowValue: object) { detailOpen.value = true await loadDetail() const loadedDetail = detail.value as LoadingDetail | null - if (loadedDetail && loadedDetail.summary.status === 'LOADING') openEdit() + if (loadedDetail && ['EDITING', 'LOADING'].includes(loadedDetail.summary.status)) openEdit() } function openEdit() { - if (!detail.value || !('preloadNo' in detail.value.summary) || detail.value.summary.status !== 'LOADING') return + if (!detail.value || !('preloadNo' in detail.value.summary) || !['EDITING', 'LOADING'].includes(detail.value.summary.status)) return editForm.containerNo = detail.value.summary.containerNo || '' editForm.voyageNo = detail.value.summary.voyageNo || '' editForm.operationReason = '' @@ -306,7 +306,7 @@ onMounted(() => { > From acc594655e0bb83d030975ca306e1caa976c005d Mon Sep 17 00:00:00 2001 From: liuyihe <2513762445@qq.com> Date: Tue, 11 Aug 2026 14:36:08 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=99=BA=E8=83=BD=E8=A3=85=E6=9F=9C?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pages/GlobalSmartLoadingView.test.ts | 11 +++-------- .../pages/GlobalSmartLoadingView.vue | 4 ++-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/modules/container-loading/pages/GlobalSmartLoadingView.test.ts b/src/modules/container-loading/pages/GlobalSmartLoadingView.test.ts index 1a1c075f..07fc61fe 100644 --- a/src/modules/container-loading/pages/GlobalSmartLoadingView.test.ts +++ b/src/modules/container-loading/pages/GlobalSmartLoadingView.test.ts @@ -81,7 +81,6 @@ describe('GlobalSmartLoadingView', () => { { label: '待装柜', value: 'WAIT_LOADING' }, { label: '预装柜中', value: 'EDITING' }, { label: '拣货中', value: 'LOADING' }, - { label: '装柜完成', value: 'COMPLETED' }, ]) expect(wrapper.text()).not.toContain('税率') @@ -138,19 +137,15 @@ describe('GlobalSmartLoadingView', () => { expect(wrapper.findAll('button').some((item) => item.text().trim() === '推送预装')).toBe(false) }) - it('routes completed containers to the read-only loading list', async () => { + it('hides completed containers from the smart loading workbench', async () => { const completed = { ...container, id: '9007199254740997', planId: '9007199254740998', cabinetNo: 'CB-3', planStatus: 'COMPLETED' as const } vi.mocked(listContainers).mockResolvedValue({ records: [completed], page: 1, size: 100, total: 1, pages: 1 }) const wrapper = mount(GlobalSmartLoadingView, { global: { plugins: [ElementPlus] } }) await flushPromises() expect(getSmartLoadingPlanByBooking).not.toHaveBeenCalled() - expect(wrapper.text()).toContain('该柜次已完成装柜') - await wrapper.findAll('button').find((item) => item.text().includes('查看装柜清单'))!.trigger('click') - expect(routerPush).toHaveBeenCalledWith({ - name: 'loading-lists', - query: { planId: completed.planId, warehouseId: completed.warehouseId }, - }) + expect(wrapper.text()).not.toContain('CB-3') + expect(wrapper.text()).not.toContain('装柜完成') }) it('refreshes the latest plan after A0409 without losing the selected container', async () => { diff --git a/src/modules/container-loading/pages/GlobalSmartLoadingView.vue b/src/modules/container-loading/pages/GlobalSmartLoadingView.vue index c04cfa2f..c9e05e39 100644 --- a/src/modules/container-loading/pages/GlobalSmartLoadingView.vue +++ b/src/modules/container-loading/pages/GlobalSmartLoadingView.vue @@ -74,7 +74,6 @@ const queryFields = computed(() => [ { label: '待装柜', value: 'WAIT_LOADING' }, { label: '预装柜中', value: 'EDITING' }, { label: '拣货中', value: 'LOADING' }, - { label: '装柜完成', value: 'COMPLETED' }, ] }, ]) @@ -82,6 +81,7 @@ const filteredContainers = computed(() => { const keyword = String(appliedQuery.value.containerKeyword || '').trim().toLowerCase() const status = String(appliedQuery.value.status || '') return containers.value.filter((item) => { + if (item.planStatus === 'COMPLETED') return false if (status && item.planStatus !== status) return false if (!keyword) return true return [item.cabinetNo, item.containerNo, item.bookingNo, item.destinationWarehouseCode, item.destinationWarehouseName] @@ -382,7 +382,7 @@ onMounted(load)