This commit is contained in:
2026-10-22 11:56:54 +08:00
parent 090431b409
commit 3e77c3976e
40 changed files with 976 additions and 241 deletions
@@ -200,7 +200,7 @@ describe('new dispatch native layout', () => {
expect(calls).toHaveLength(2);expect(calls[1]![0].idempotencyKey).not.toBe(calls[0]![0].idempotencyKey)
expect(api.createDispatchDraft).toHaveBeenCalledOnce();expect(api.lockDispatchDraftPallet).toHaveBeenCalledOnce()
})
it('requires an active cargo group before accepting per-group settings while keeping setup controls available', async () => {
it('keeps publication available before cargo selection without extra planning fields', async () => {
const { dialog } = await render()
expect(view(dialog).find('[aria-label="排车设置"] table').exists()).toBe(false)
expect(view(dialog).find('[aria-label="排车设置"] .density-dialog-note').exists()).toBe(false)
@@ -213,14 +213,16 @@ describe('new dispatch native layout', () => {
expect(field(dialog, '建单方式').getComponent({ name: 'ElRadioGroup' }).props('disabled')).toBe(false)
await restore(dialog)
expect(dialog.findComponent(DispatchResourceFields).exists()).toBe(false)
expect(field(dialog, '备注').get('input').attributes('disabled')).toBeUndefined()
expect(view(dialog).get('.dispatch-candidate-query input[type="checkbox"]').attributes('disabled')).toBeUndefined()
})
it('creates an unassigned empty dispatch while preserving optional dates and remark through fullscreen', async () => {
it('creates an empty dispatch with optional publication preserved through fullscreen', async () => {
const { dialog } = await render(); await emptyMode(dialog); await selectWarehouse(dialog)
expect(dialog.findComponent(DispatchResourceFields).exists()).toBe(false)
field(dialog, '计划发车时间').getComponent({ name: 'ElDatePicker' }).vm.$emit('update:modelValue', '2026-11-02T10:00:00Z')
field(dialog, '预计到达时间').getComponent({ name: 'ElDatePicker' }).vm.$emit('update:modelValue', '2026-11-02T18:00:00Z')
await field(dialog, '备注').get('input').setValue('本趟备注')
expect(view(dialog).find('[aria-label="排车计划时间与备注"]').exists()).toBe(false)
expect(view(dialog).findComponent({ name: 'ElDatePicker' }).exists()).toBe(false)
const publication = view(dialog).get('.dispatch-candidate-query input[type="checkbox"]')
expect(publication.element).toHaveProperty('checked', false)
await publication.setValue(true)
expect(dialog.findComponent({ name: 'ElDialog' }).props('fullscreen')).toBe(true)
await view(dialog).get('button[aria-label="退出全屏"]').trigger('click'); await flushPromises()
expect(dialog.findComponent({ name: 'ElDialog' }).props('fullscreen')).toBe(false)
@@ -229,7 +231,7 @@ describe('new dispatch native layout', () => {
expect(view(dialog).text()).toContain('空单暂不能核平、装车或发车')
expect(view(dialog).find('[aria-label="智能排车三栏选货"]').exists()).toBe(false)
await view(dialog).findAll('button').find(button => button.text() === '保存空排车单')!.trigger('click'); await flushPromises()
expect(api.createDispatch).toHaveBeenCalledExactlyOnceWith({ idempotencyKey: expect.any(String), publishLooseboardDemand: true, warehouseId: '321', cargo: [], batchAllocations: [], plannedDepartureAt: '2026-11-02T10:00:00Z', estimatedArrivalAt: '2026-11-02T18:00:00Z', remark: '本趟备注', vehicle: null, driver: null })
expect(api.createDispatch).toHaveBeenCalledExactlyOnceWith({ idempotencyKey: expect.any(String), publishLooseboardDemand: true, warehouseId: '321', cargo: [], batchAllocations: [], plannedDepartureAt: null, estimatedArrivalAt: null, remark: null, vehicle: null, driver: null })
})
it('creates with only the warehouse and never requests vehicle or driver directories', async () => {
const { dialog } = await render(); await emptyMode(dialog); await selectWarehouse(dialog)
@@ -239,15 +241,14 @@ describe('new dispatch native layout', () => {
expect(listVehicles).not.toHaveBeenCalled()
expect(listDrivers).not.toHaveBeenCalled()
})
it('keeps each group configuration independent and keeps form values editable after conversion read failure', async () => {
it('applies publication to all cars and keeps it editable after conversion read failure', async () => {
vi.mocked(api.getDispatch).mockRejectedValueOnce(new Error('details not ready')).mockImplementation(async no => detail({ dispatchNo: no, recordVersion: 1 }))
const { wrapper, dialog } = await render(); await restore(dialog)
await field(dialog, '备注').get('input').setValue('第一组')
await view(dialog).get('.dispatch-candidate-query input[type="checkbox"]').setValue(true)
const radios = view(dialog).get('[aria-label="车辆装载"]').findAll('input[type="radio"]')
await radios[1]!.setValue(true); await flushPromises()
await field(dialog, '备注').get('input').setValue('第二组')
await radios[0]!.setValue(true); await flushPromises()
expect((field(dialog, '备注').get('input').element as HTMLInputElement).value).toBe('第一组')
expect(view(dialog).get('.dispatch-candidate-query input[type="checkbox"]').element).toHaveProperty('checked', true)
expect(dialog.findComponent({ name: 'ElDialog' }).props('fullscreen')).toBe(true)
await view(dialog).get('button[aria-label="退出全屏"]').trigger('click'); await flushPromises()
expect(dialog.findComponent({ name: 'ElDialog' }).props('fullscreen')).toBe(false)
@@ -256,7 +257,7 @@ describe('new dispatch native layout', () => {
expect(api.convertDispatchDraft).toHaveBeenCalledTimes(1)
const request = vi.mocked(api.convertDispatchDraft).mock.calls[0]![0]
expect(request.recordVersion).toBe(0)
expect(request.groups.map(group => [group.dispatch.vehicle, group.dispatch.driver, group.dispatch.remark])).toEqual([[null, null, '第一组'], [null, null, '第二组']])
expect(request.groups.map(group => [group.dispatch.publishLooseboardDemand, group.dispatch.plannedDepartureAt, group.dispatch.estimatedArrivalAt, group.dispatch.remark])).toEqual([[true, null, null, null], [true, null, null, null]])
expect(wrapper.emitted('created')).toBeUndefined()
expect(view(dialog).text()).toContain('本次排车操作失败,请重试')
dialog.vm.$emit('confirm'); await flushPromises()
@@ -273,12 +274,12 @@ describe('new dispatch native layout', () => {
expect(dialog.props('confirmText')).toBe('生成排车单')
const original = JSON.parse(JSON.stringify(vi.mocked(api.convertDispatchDraft).mock.calls[0]![0])) as ConvertDraft
expect(dialog.findComponent({ name: 'ElDialog' }).props()).toMatchObject({ showClose: false, closeOnPressEscape: false })
expect(field(dialog, '备注').get('input').attributes('disabled')).toBeDefined()
expect(view(dialog).get('.dispatch-candidate-query input[type="checkbox"]').attributes('disabled')).toBeDefined()
reject(new ApiResponseError('转换结果尚未确认', 'A0503', 503, null, 'new-dispatch-request')); await flushPromises()
expect(view(dialog).text()).toContain('new-dispatch-request')
expect(view(dialog).text()).not.toContain('原请求结果尚待核对')
expect(dialog.props('confirmText')).toBe('生成排车单')
expect(field(dialog,'备注').get('input').attributes('disabled')).toBeUndefined()
expect(view(dialog).get('.dispatch-candidate-query input[type="checkbox"]').attributes('disabled')).toBeUndefined()
expect(dialog.findComponent(DispatchResourceFields).exists()).toBe(false)
await wrapper.setProps({ modelValue: false }); await wrapper.setProps({ modelValue: true }); await flushPromises()
dialog.vm.$emit('confirm'); await flushPromises()