This commit is contained in:
2026-10-21 15:49:35 +08:00
parent e6c864a2a6
commit a4c7f8edd5
38 changed files with 466 additions and 95 deletions
@@ -17,7 +17,7 @@ const Button = defineComponent({ props: ['disabled'], template: '<button :disabl
const Tabs = defineComponent({ props: ['modelValue'], emits: ['update:modelValue'], template: '<div><slot /></div>' })
const Pane = defineComponent({ props: ['name','label'], template: '<article><slot /></article>' })
const Query = defineComponent({ props: ['modelValue','fields'], emits: ['update:modelValue','search'], template: '<div />' })
const Table = defineComponent({ props: ['data','columns','total','page','pageSize'], emits: ['update:page','update:pageSize'], setup(props,{slots}) { return () => h('div', [slots['toolbar-start']?.(), slots.filters?.(), slots.notices?.(), ...(props.data || []).map((row: object) => h('div', Object.entries(slots).filter(([name]) => !['toolbar-start','filters','notices'].includes(name)).map(([,slot]) => slot?.({row}))))]) } })
const Table = defineComponent({ props: ['data','columns','total','page','pageSize'], emits: ['update:page','update:pageSize'], setup(props,{slots}) { return () => h('div', [slots['toolbar-start']?.(), slots.filters?.(), slots.notices?.(), ...(props.data || []).map((row: object) => h('div', Object.entries(slots).filter(([name]) => !['toolbar-start','filters','notices'].includes(name)).map(([name,slot]) => h('section', { 'data-column': name }, slot?.({row})))))]) } })
const OperationsEditor = defineComponent({ name: 'OwnedBusinessOperationsEditorStub', props: ['modelValue','detail'], emits: ['update:modelValue','saved','busy'], template: '<div />' })
const PhotosEditor = defineComponent({ name: 'OwnedBusinessPhotosEditorStub', props: ['modelValue','detail'], emits: ['update:modelValue','saved','busy'], template: '<div />' })
const global = { stubs: { AdminPage: Surface, DetailPageLayout: Surface, DataTable: Table, QueryToolbar: Query, ElTabs: Tabs, ElTabPane: Pane, ElButton: Button, OwnedBusinessOperationsEditor: OperationsEditor, OwnedBusinessPhotosEditor: PhotosEditor, LoadErrorState: { props:['message'], template:'<div>{{message}}<slot name="details" /></div>' }, ApiErrorMeta: true }, directives: { loading: () => {} } }
@@ -30,6 +30,27 @@ beforeEach(() => {
})
describe('owned business views', () => {
it('keeps split prices authoritative and arrival times associated with each destination', async () => {
const detail = ownedBusinessFixture()
detail.row.operations.money = { currency: 'USD', amount: '0.00' }; detail.row.unitPrice = '0.00'
detail.row.destinations[0]!.appointments[0]!.scheduledAt = '2026-10-21T09:00:00Z'
detail.row.destinations.push({ destinationKey: 'destination-2', warehouseCode: 'FBA-2', warehouseName: null, address: null, appointments: [], actualArrivedAt: '2026-10-21T10:00:00Z' })
calls.list.mockResolvedValue({ records: [detail.row], page: 1, size: 20, total: 1, summary: { dispatchCount: 1, afterLoadingCount: 1, deliveringCount: 0, deliveredCount: 0 } })
const wrapper = mount(OwnedBusinessView, { global }); await flushPromises()
const columns = wrapper.findComponent(Table).props('columns') as { key?: string; label: string; slotName?: string }[]
expect(columns.map(column => column.label)).toEqual(expect.arrayContaining(['目的仓', '派送仓库', '总价', '单价(/托)', '最晚装车完成时间', '预约到达时间', '实际到达时间', '状态']))
expect(columns.find(column => column.key === 'deliveryWarehouses')!.slotName).toBe('destinations')
expect(wrapper.get('[data-column="money"]').text()).toBe('USD 0.00')
expect(wrapper.get('[data-column="unitPrice"]').text()).toBe('USD 0.00')
expect(wrapper.get('[data-column="latestLoaded"]').text()).toBe('—')
const scheduled = wrapper.findAll('[data-column="scheduledArrival"] .owned-business-destination')
expect(scheduled.map(cell => cell.text())).toEqual(['FBA-1' + dayjs('2026-10-21T09:00:00Z').format('YYYY-MM-DD HH:mm'), 'FBA-2—'])
const actual = wrapper.findAll('[data-column="actualArrival"] .owned-business-destination')
expect(actual.map(cell => cell.text())).toEqual(['FBA-1—', 'FBA-2' + dayjs('2026-10-21T10:00:00Z').format('YYYY-MM-DD HH:mm')])
expect(calls.detail).not.toHaveBeenCalled()
wrapper.unmount()
})
it('keeps a non-pool external vehicle returned by the server without filtering or requiring a vehicle id', async () => {
const detail = ownedBusinessFixture()
detail.row.vehicle = { vehicleId: null, plate: 'EXTERNAL-NO-POOL', ownership: 'DISPATCHED' }