优化
This commit is contained in:
@@ -9,8 +9,8 @@ import AppDialog from '@/shared/components/AppDialog.vue'
|
||||
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
|
||||
import { ApiResponseError } from '@/shared/api/http'
|
||||
import * as api from '../api/dispatches'
|
||||
import { command, detail, destination, loadingPreview, page, resources, sharedPalletCandidates } from '../dispatchTestFixtures'
|
||||
import type { ArrangementPreview, CargoLine, DispatchAction, DispatchActions, DispatchCargoItem, DispatchEvidenceFile, PreviewGroup, UpdateDispatch } from '../dispatchContracts'
|
||||
import { command, detail, destination, loadingPreview, resources } from '../dispatchTestFixtures'
|
||||
import type { ArrangementPreview, CargoLine, DispatchAction, DispatchActions, DispatchEvidenceFile, PreviewGroup, UpdateDispatch } from '../dispatchContracts'
|
||||
|
||||
const identity = vi.hoisted(() => ({ id: '' }))
|
||||
const can = vi.hoisted(() => vi.fn((_code: string) => true))
|
||||
@@ -24,7 +24,6 @@ afterEach(() => vi.unstubAllGlobals())
|
||||
const gate = { allowed: true, blockCode: null, blockReason: null }
|
||||
const actions: DispatchActions = { EDIT: gate, ADD_CARGO: gate, REMOVE_CARGO: gate, CANCEL: gate, SUBMIT_REVIEW: gate, DISPATCH_REVIEW: gate, LOADING_REVIEW: gate, RETURN_TO_REVIEW: gate, LOADING_COMPLETE: gate, ARRANGE_DELIVERY: gate, DEPART: gate }
|
||||
const evidence = (fileId = '301'): DispatchEvidenceFile => ({ fileId, fileName: fileId === '301' ? '旧附件.png' : '新附件.png', contentType: 'image/png', sizeBytes: 3 })
|
||||
function item(id: string, picked = 0): DispatchCargoItem { return { dispatchItemId: id, customerId: 'C1', customerName: '客户甲', sourceKey: 'source-1', sourceVersion: 'source-v1', sourceType: 'INBOUND_PLAN', planPalletId: '11', returnReceiptId: null, relabelNo: null, warehousePalletId: '21', palletNo: 'PALLET-1', orderNo: 'ORDER-1', inboundCode: 'IN-1', destination: destination(), scheduledPackages: 2, pickedPackages: picked, remove: picked ? { allowed: false, blockCode: 'PICKED', blockReason: '已经扫码,不可移除' } : gate } }
|
||||
function cargo(key: string, customerId: string): CargoLine { return { dispatchItemId: 'item-' + key, customerId, customerName: '客户' + customerId, orderId: null, orderNo: 'ORDER-' + key, sourceKey: key, sourceStage: 'RECEIVED', sourceRegion: null, sourceInboundId: null, inboundCode: 'IN-' + key, planPalletId: null, warehousePalletId: 'pallet-' + key, palletNo: 'PALLET-' + key, pickId: null, attributionId: null, inventoryPositionId: null, receiptId: null, returnReceiptId: null, returnCartonId: null, cartonMark: 'BOX-' + key, relabelNo: null, destination: destination(), packages: 2, productQuantity: 4, grossWeightKg: 10, volumeCbm: 1, batchAllocations: [], sourceOrigin: null } }
|
||||
function arrangement(): ArrangementPreview {
|
||||
const group = (key: string, customerId: string): PreviewGroup => ({ groupKey: key, customerId, customerName: '客户' + customerId, destination: destination(), groupCargoHash: 'cargo-' + key, cargo: [cargo(key, customerId)], externalFreightHash: 'external-' + key, externalQuotes: [], feeCoverageCargoHash: 'coverage-' + key, feeSources: [], requiredServices: ['DELIVERY_FEE'], blockReasons: [] })
|
||||
@@ -46,15 +45,10 @@ beforeEach(() => {
|
||||
vi.mocked(api.returnDispatchToReview).mockImplementation(async (_, body) => command('RETURN_TO_REVIEW', body.idempotencyKey))
|
||||
vi.mocked(api.submitDispatchReview).mockImplementation(async (_, body) => command('SUBMIT_REVIEW', body.idempotencyKey))
|
||||
vi.mocked(api.departDispatch).mockImplementation(async (_, body) => command('DEPART', body.idempotencyKey))
|
||||
vi.mocked(api.addDispatchCargo).mockImplementation(async (_, body) => command('ADD_CARGO', body.idempotencyKey))
|
||||
vi.mocked(api.removeDispatchItem).mockImplementation(async (_, __, body) => command('REMOVE_CARGO', body.idempotencyKey))
|
||||
vi.mocked(api.reorderDispatchRoute).mockImplementation(async (_, body) => command('EDIT', body.idempotencyKey))
|
||||
vi.mocked(api.completeDispatchLoading).mockImplementation(async (_, body) => command('LOADING_COMPLETE', body.idempotencyKey))
|
||||
vi.mocked(api.getDispatchLoading).mockResolvedValue(loadingPreview())
|
||||
vi.mocked(api.getDispatchRoute).mockResolvedValue({ dispatchNo: 'PC/1', recordVersion: 0, edit: gate, stops: [{ index: 0, name: '起运仓', address: '起点地址', destinationKey: null }, { index: 1, name: '目的仓甲', address: '甲地址', destinationKey: 'A' }, { index: 2, name: '外接卸货点', address: '乙地址', destinationKey: 'B' }] })
|
||||
vi.mocked(api.getDispatchItems).mockResolvedValue({ dispatchNo: 'PC/1', recordVersion: '9007199254740993', status: 'ACTIVE', stage: 'BEFORE_LOADING', items: [item('9223372036854775001'), item('picked', 1)] })
|
||||
vi.mocked(api.listDispatches).mockResolvedValue(page())
|
||||
vi.mocked(api.listDispatchCandidates).mockResolvedValue({ total: 1, page: 1, size: 20, pages: 1, candidates: [sharedPalletCandidates()[0]!], complete: true, snapshotAt: '' })
|
||||
vi.mocked(api.getDispatchArrangement).mockResolvedValue(arrangement())
|
||||
vi.mocked(api.getDispatchEvidence).mockImplementation(async (_, __, id) => evidence(id))
|
||||
vi.mocked(api.getDispatchEvidenceContent).mockResolvedValue(new Blob(['png'], { type: 'image/png' }))
|
||||
@@ -130,25 +124,16 @@ describe('dispatch workflow native layout', () => {
|
||||
dialog.vm.$emit('confirm'); await flushPromises()
|
||||
expect(api.reorderDispatchRoute).toHaveBeenCalledExactlyOnceWith('PC/1', { recordVersion: 0, idempotencyKey: expect.any(String), destinationKeys: ['B', 'A'], reason: '顺序调整' })
|
||||
})
|
||||
it('removes the real item identity while keeping scanned cargo unavailable', async () => {
|
||||
const { dialog } = await render('REMOVE_CARGO')
|
||||
const radios = dialog.get('[aria-label="本车可移除货物"]').findAllComponents({ name: 'ElRadio' })
|
||||
expect(radios[1]!.props('disabled')).toBe(true)
|
||||
radios[0]!.vm.$emit('update:modelValue', '9223372036854775001'); await dialog.get('textarea').setValue(' 计划变更 ')
|
||||
expect(dialog.text()).not.toContain('9223372036854775001')
|
||||
it.each(['ADD_CARGO', 'REMOVE_CARGO'] as const)('replaces the old %s editor with the smart dispatch entry notice', async action => {
|
||||
const { dialog } = await render(action)
|
||||
expect(dialog.text()).toContain('货物安排统一在智能排车中修改')
|
||||
expect(dialog.props('confirmDisabled')).toBe(true)
|
||||
expect(dialog.findComponent({ name: 'ElForm' }).exists()).toBe(false)
|
||||
dialog.vm.$emit('confirm'); await flushPromises()
|
||||
expect(api.removeDispatchItem).toHaveBeenCalledExactlyOnceWith('PC/1', '9223372036854775001', { recordVersion: '9007199254740993', idempotencyKey: expect.any(String), reason: '计划变更' })
|
||||
})
|
||||
it('adds the complete filtered shared-pallet group and keeps every source visible when expanded', async () => {
|
||||
const [first, second] = sharedPalletCandidates()
|
||||
const { dialog } = await render('ADD_CARGO')
|
||||
const source = dialog.get('details')
|
||||
await source.get('summary').trigger('click'); await flushPromises()
|
||||
expect(source.findAll('li')).toHaveLength(2)
|
||||
await dialog.get('input[type="checkbox"]').setValue(true); await flushPromises()
|
||||
dialog.vm.$emit('confirm'); await flushPromises()
|
||||
expect(api.addDispatchCargo).toHaveBeenCalledExactlyOnceWith('PC/1', { recordVersion: 0, idempotencyKey: expect.any(String), cargo: [first!.selection, second!.selection], batchAllocations: [] })
|
||||
expect(dialog.findComponent({ name: 'ElTable' }).props('maxHeight')).toBeUndefined()
|
||||
expect(api.addDispatchCargo).not.toHaveBeenCalled()
|
||||
expect(api.removeDispatchItem).not.toHaveBeenCalled()
|
||||
expect(api.getDispatchItems).not.toHaveBeenCalled()
|
||||
expect(api.listDispatchCandidates).not.toHaveBeenCalled()
|
||||
})
|
||||
it('keeps references separate from real loading measurements and submits the exact manifest', async () => {
|
||||
const { dialog } = await render('LOADING_COMPLETE')
|
||||
|
||||
Reference in New Issue
Block a user