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(() => { >