From e124fbcf6858417ff27f70832409bf51ff10203d Mon Sep 17 00:00:00 2001
From: ouyangxq <775153912@qq.com>
Date: Sat, 10 Oct 2026 19:04:09 +0800
Subject: [PATCH] fix(fleet): reflect bound booking in receipt progress
---
.../TripBookingFulfillmentDialog.test.ts | 20 +++++++++++++++++--
.../TripBookingFulfillmentDialog.vue | 7 ++++++-
2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/src/modules/overseas-master-data/components/TripBookingFulfillmentDialog.test.ts b/src/modules/overseas-master-data/components/TripBookingFulfillmentDialog.test.ts
index 141110bc..b61c4399 100644
--- a/src/modules/overseas-master-data/components/TripBookingFulfillmentDialog.test.ts
+++ b/src/modules/overseas-master-data/components/TripBookingFulfillmentDialog.test.ts
@@ -17,9 +17,9 @@ function mount(mode: 'incoming' | 'receipt' | 'bind' | 'view') {
const field = { props: ['modelValue'], emits: ['update:modelValue'], template: '' }
const wrapper = shallowMount(TripBookingFulfillmentDialog, { props: { modelValue: true, trip, booking, mode, arrivalAt: '2026-10-03T08:00:00Z' }, global: { plugins: [createPinia()], directives: { loading: () => undefined }, stubs: {
AppDialog: { name: 'AppDialog', props: ['modelValue', 'confirmDisabled'], emits: ['confirm'], template: '
' },
- DataTable: { props: ['data'], template: '' },
+ DataTable: { name: 'DataTable', props: ['data'], template: '' },
ElForm: { template: '
' }, ElFormItem: { template: '
' }, ElInputNumber: { ...field, name: 'ElInputNumber' }, ElDatePicker: field, ElInput: field,
- LoadErrorState: true, ApiErrorMeta: true,
+ ElButton: { template: '' }, LoadErrorState: true, ApiErrorMeta: true,
} } }); wrappers.push(wrapper); return wrapper
}
beforeEach(() => { vi.clearAllMocks(); vi.mocked(api.getTripIncoming).mockResolvedValue(structuredClone(preview)) })
@@ -56,3 +56,19 @@ it('keeps an uncertain receipt command retryable after closing and reopening wit
expect(api.acceptTripIncoming).toHaveBeenNthCalledWith(2, 'TR-1', 'FB-1', original)
expect(api.getTripIncoming).toHaveBeenCalledOnce()
})
+
+it.each([
+ { bookingStatus: 'BOUND' as const, incomingStatus: 'READY_FOR_DISPATCH', expected: '已确认实收,已排入本车' },
+ { bookingStatus: 'RECEIVED' as const, incomingStatus: 'READY_FOR_DISPATCH', expected: '已确认实收,可安排排车' },
+ { bookingStatus: 'BOUND' as const, incomingStatus: 'OUTBOUNDED', expected: '已出库' },
+])('shows truthful receipt guidance for $bookingStatus / $incomingStatus', async ({ bookingStatus, incomingStatus, expected }) => {
+ vi.mocked(api.getTripIncoming).mockResolvedValue({ ...preview, incoming: { ...preview.incoming!, status: incomingStatus } })
+ const wrapper = mount('view')
+ await wrapper.setProps({ booking: { ...booking, status: bookingStatus, dispatchNo: bookingStatus === 'BOUND' ? 'DS-1' : null } })
+ await flushPromises()
+ expect(wrapper.text()).toContain(expected)
+ if (bookingStatus === 'BOUND') expect(wrapper.text()).not.toContain('可安排排车')
+ expect(wrapper.findComponent({ name: 'DataTable' }).props('data')).toEqual(preview.incoming!.pallets)
+ expect(api.acceptTripIncoming).not.toHaveBeenCalled()
+ expect(api.bindTripBookingDispatch).not.toHaveBeenCalled()
+})
diff --git a/src/modules/overseas-master-data/components/TripBookingFulfillmentDialog.vue b/src/modules/overseas-master-data/components/TripBookingFulfillmentDialog.vue
index 047a061b..e02faafd 100644
--- a/src/modules/overseas-master-data/components/TripBookingFulfillmentDialog.vue
+++ b/src/modules/overseas-master-data/components/TripBookingFulfillmentDialog.vue
@@ -27,6 +27,11 @@ const ready = computed(() => preview.value?.incoming && ['WAIT_CUSTOMER_CONFIRMA
const totalSpaces = computed(() => Object.values(spaces).reduce((a,b) => a + (b || 0), 0))
const amount = computed(() => unitPrice.value == null ? null : Math.round(unitPrice.value * (props.booking?.cargo.priceBasis === 'ORDER' ? 1 : totalSpaces.value) * 100) / 100)
const statuses: Record = { WAIT_PDA_RECEIVING: '等待仓库收货', RECEIVING: '仓库收货中', WAIT_CUSTOMER_CONFIRMATION: '实收完成,待确认', READY_FOR_DISPATCH: '已确认实收,可安排排车', OUTBOUNDED: '已出库' }
+const incomingStatusLabel = computed(() => {
+ const status = preview.value?.incoming?.status
+ if (status === 'READY_FOR_DISPATCH' && props.booking?.status === 'BOUND') return '已确认实收,已排入本车'
+ return statuses[status || ''] || '等待读取'
+})
const columns = computed(() => [{ key: 'palletNo', prop: 'palletNo', label: '实收托盘', minWidth: 180 }, { key: 'packages', prop: 'packages', label: '箱数', width: 95 },
{ key: 'weightKg', prop: 'weightKg', label: '实测重量(kg)', minWidth: 150 }, { key: 'volumeCbm', prop: 'volumeCbm', label: '实测体积(m³)', minWidth: 150 },
...(props.mode === 'receipt' ? [{ key: 'spaces', label: '占用标准托位', slotName: 'spaces', width: 170 }] : [])])
@@ -94,7 +99,7 @@ onBeforeUnmount(() => { generation++ })
- 刷新收货进度来货单:{{ preview?.incoming?.incomingNo || '—' }} · {{ statuses[preview?.incoming?.status || ''] || '等待读取' }}
+ 刷新收货进度来货单:{{ preview?.incoming?.incomingNo || '—' }} · {{ incomingStatusLabel }}
原约定 {{ booking.agreedAmount?.toFixed(2) }} {{ booking.cargo.currency }};本次实收 {{ preview?.incoming?.receivedPackages || 0 }} 箱、{{ totalSpaces }} 托位,确认金额 {{ amount?.toFixed(2) || '—' }} {{ booking.cargo.currency }}。转派送时按本次确认报价登记应收。