fix: align inbound pallet plans with preview

This commit is contained in:
2026-09-10 15:40:55 +08:00
parent a2f1ecc6b9
commit dc1cbfcf4a
3 changed files with 62 additions and 46 deletions
@@ -120,6 +120,16 @@ async function openPending() {
return wrapper
}
async function openHiddenContainerWorkbench(wrapper: Awaited<ReturnType<typeof mountView>>) {
const view = wrapper.vm as unknown as {
statusTab: '全部' | '待分配' | '柜子'
changeStatusTab(): void
}
view.statusTab = '柜子'
view.changeStatusTab()
await flushPromises()
}
async function selectRows(wrapper: Awaited<ReturnType<typeof mountView>>, rows: object[]) {
wrapper.findComponent(DataTable).vm.$emit('selection-change', rows)
await wrapper.vm.$nextTick()
@@ -178,6 +188,7 @@ describe('LastMileOrdersView pending order and container conversion', () => {
expect(wrapper.text()).toContain('按柜批量生成')
expect(wrapper.text()).not.toContain('按订单')
expect(wrapper.text()).not.toContain('待分配整柜')
expect(wrapper.text()).not.toContain('柜子工作台')
expect(listLastMileOrders).toHaveBeenLastCalledWith(expect.objectContaining({ page: 1, size: 10, currentStatus: 'PENDING_ASSIGNMENT' }))
expect(listContainerPlanProgress).not.toHaveBeenCalled()
})
@@ -208,8 +219,7 @@ describe('LastMileOrdersView pending order and container conversion', () => {
await flushPromises()
expect(listLastMileOrders).toHaveBeenLastCalledWith(expect.objectContaining({ currentStatus: 'PENDING_ASSIGNMENT', lxCode: 'LX-SEARCH' }))
await wrapper.findAll('.el-radio-button').find((item) => item.text().startsWith('柜子'))!.trigger('click')
await flushPromises()
await openHiddenContainerWorkbench(wrapper)
expect(listContainerPlanProgress).toHaveBeenLastCalledWith({
page: 1, size: 10, containerNo: 'CONT-SEARCH',
createdFrom: '2026-09-01T00:00:00', createdTo: '2026-09-07T23:59:59',
@@ -265,7 +275,7 @@ describe('LastMileOrdersView pending order and container conversion', () => {
expect(createManualInboundPlan).toHaveBeenCalledWith(expect.objectContaining({
customerId, orderId: '2092873463568596994', expectedOrderVersion: 3,
plannedArrivalDate: '2026-09-08', palletCount: 2,
plannedArrivalDate: '2026-09-08', palletCount: 5, palletType: 'WOOD',
}), expect.stringContaining('manual-inbound-plan-'))
const payload = vi.mocked(createManualInboundPlan).mock.calls[0][0] as unknown as Record<string, unknown>
expect(payload).not.toHaveProperty('inboundCode')
@@ -373,11 +383,9 @@ describe('LastMileOrdersView pending order and container conversion', () => {
const nullArrival = { ...summary, sourceContainerBookingId: '2092873463568597002', containerNo: 'CONT-NULL', plannedArrivalAt: null, planCount: 0, pendingPlanCount: 15 }
vi.mocked(listContainerPlanProgress).mockResolvedValueOnce({ records: [summary, nullArrival], page: 1, size: 10, total: 2, pages: 1 })
const wrapper = await mountView()
const containerTab = wrapper.findAll('.el-radio-button').find((item) => item.text().startsWith('柜子'))
await containerTab!.trigger('click')
await flushPromises()
await openHiddenContainerWorkbench(wrapper)
expect(listContainerPlanProgress).toHaveBeenLastCalledWith({ page: 1, size: 10, containerNo: undefined, createdFrom: undefined, createdTo: undefined })
expect(wrapper.text()).toContain('柜子工作台(2)')
expect(wrapper.text()).not.toContain('柜子工作台(2)')
expect(wrapper.text()).toContain('货柜工作台')
expect(wrapper.text()).toContain('按柜查看和修改海外接柜仓,并为剩余入仓码生成独立入库计划')
expect(wrapper.text()).toContain('5个入仓码待生成计划')
@@ -401,8 +409,7 @@ describe('LastMileOrdersView pending order and container conversion', () => {
}
vi.mocked(listContainerPlanProgress).mockResolvedValueOnce({ records: [ready], page: 1, size: 10, total: 1, pages: 1 })
const wrapper = await mountView()
await wrapper.findAll('.el-radio-button').find((item) => item.text().startsWith('柜子'))!.trigger('click')
await flushPromises()
await openHiddenContainerWorkbench(wrapper)
expect(wrapper.text()).toContain('CONT-15')
expect(wrapper.text()).toContain('0个入仓码待生成计划')
expect((button(wrapper, '生成入库计划')!.element as HTMLButtonElement).disabled).toBe(true)
@@ -412,8 +419,7 @@ describe('LastMileOrdersView pending order and container conversion', () => {
it('renders the all-cabinet empty state and unit', async () => {
vi.mocked(listContainerPlanProgress).mockResolvedValueOnce({ records: [], page: 1, size: 10, total: 0, pages: 0 })
const wrapper = await mountView()
await wrapper.findAll('.el-radio-button').find((item) => item.text().startsWith('柜子'))!.trigger('click')
await flushPromises()
await openHiddenContainerWorkbench(wrapper)
expect(wrapper.text()).toContain('暂无货柜数据')
expect(wrapper.text()).not.toContain('已全部生成计划的柜不再展示')
})
@@ -421,9 +427,7 @@ describe('LastMileOrdersView pending order and container conversion', () => {
it('uses independent cabinet pagination and opens the complete long-id detail in a dialog', async () => {
vi.mocked(listContainerPlanProgress).mockResolvedValue({ records: [summary], page: 1, size: 10, total: 21, pages: 3 })
const wrapper = await mountView()
const containerTab = wrapper.findAll('.el-radio-button').find((item) => item.text().startsWith('柜子'))
await containerTab!.trigger('click')
await flushPromises()
await openHiddenContainerWorkbench(wrapper)
const pagination = wrapper.findComponent({ name: 'ElPagination' })
pagination.vm.$emit('current-change', 2)
await flushPromises()
@@ -445,12 +449,10 @@ describe('LastMileOrdersView pending order and container conversion', () => {
it('starts cabinet plan generation directly from the workbench card', async () => {
const wrapper = await mountView()
const containerTab = wrapper.findAll('.el-radio-button').find((item) => item.text().startsWith('柜子'))
await containerTab!.trigger('click')
await flushPromises()
await openHiddenContainerWorkbench(wrapper)
await button(wrapper, '生成入库计划')!.trigger('click')
await flushPromises()
expect(document.body.textContent).toContain('预览已就绪,本次将新增 5 个计划、5 个托盘码')
expect(document.body.textContent).toContain('预览已就绪,本次将处理 5 票订单、生成或补齐 5 个托盘码')
const confirm = [...document.body.querySelectorAll('button')].find((item) => item.textContent?.includes('确认生成')) as HTMLButtonElement
expect(confirm.disabled).toBe(false)
confirm.click()
@@ -474,8 +476,7 @@ describe('LastMileOrdersView pending order and container conversion', () => {
vi.mocked(listContainerPlanProgress).mockResolvedValueOnce({ records: [invalid], page: 1, size: 10, total: 1, pages: 1 } as never)
vi.mocked(getContainerPlanProgress).mockResolvedValueOnce({ summary: invalid, orders: [] } as never)
const wrapper = await mountView()
await wrapper.findAll('.el-radio-button').find((item) => item.text().startsWith('柜子'))!.trigger('click')
await flushPromises()
await openHiddenContainerWorkbench(wrapper)
expect(wrapper.text()).toContain('柜内接柜仓业务快照不一致')
expect((button(wrapper, '生成入库计划')!.element as HTMLButtonElement).disabled).toBe(true)
@@ -489,8 +490,7 @@ describe('LastMileOrdersView pending order and container conversion', () => {
it('shows the receiving warehouse and changes it from ACTIVE OVERSEAS master data with versioning', async () => {
vi.mocked(listAllPlatformWarehouses).mockResolvedValueOnce([currentReceivingWarehouse, receivingWarehouse] as never)
const wrapper = await mountView()
await wrapper.findAll('.el-radio-button').find((item) => item.text().startsWith('柜子'))!.trigger('click')
await flushPromises()
await openHiddenContainerWorkbench(wrapper)
expect(wrapper.text()).toContain('海外接柜仓')
expect(wrapper.text()).toContain('LAX01 · 洛杉矶接柜仓')
expect(wrapper.get('.container-workbench-card__warehouse strong').attributes('title')).toBe('LAX01 · 洛杉矶接柜仓')
@@ -526,8 +526,7 @@ describe('LastMileOrdersView pending order and container conversion', () => {
let resolveCandidates!: (value: typeof receivingWarehouse[]) => void
vi.mocked(listAllPlatformWarehouses).mockReturnValueOnce(new Promise((resolve) => { resolveCandidates = resolve }) as never)
const wrapper = await mountView()
await wrapper.findAll('.el-radio-button').find((item) => item.text().startsWith('柜子'))!.trigger('click')
await flushPromises()
await openHiddenContainerWorkbench(wrapper)
await button(wrapper, '修改接柜仓')!.trigger('click')
await wrapper.vm.$nextTick()
const confirm = [...document.body.querySelectorAll('button')].find((item) => item.textContent?.includes('确认修改')) as HTMLButtonElement
@@ -544,8 +543,7 @@ describe('LastMileOrdersView pending order and container conversion', () => {
page: 1, size: 10, total: 1, pages: 1,
})
const wrapper = await mountView()
await wrapper.findAll('.el-radio-button').find((item) => item.text().startsWith('柜子'))!.trigger('click')
await flushPromises()
await openHiddenContainerWorkbench(wrapper)
expect(wrapper.text()).toContain('海外仓已开始拆柜收货')
const changeButton = button(wrapper, '修改接柜仓')!
expect(changeButton.exists()).toBe(true)
@@ -557,8 +555,7 @@ describe('LastMileOrdersView pending order and container conversion', () => {
it('keeps a disabled receiving-warehouse action discoverable without edit permission', async () => {
canAccess.mockImplementation((permissionCode: string) => permissionCode !== 'platform:overseas-warehouse:last-mile-order:edit')
const wrapper = await mountView()
await wrapper.findAll('.el-radio-button').find((item) => item.text().startsWith('柜子'))!.trigger('click')
await flushPromises()
await openHiddenContainerWorkbench(wrapper)
const changeButton = button(wrapper, '修改接柜仓')!
expect(changeButton.exists()).toBe(true)
expect((changeButton.element as HTMLButtonElement).disabled).toBe(true)
@@ -574,8 +571,7 @@ describe('LastMileOrdersView pending order and container conversion', () => {
'version conflict', 'A0409', 200, undefined, 'request-receiving', 'trace-receiving',
))
const wrapper = await mountView()
await wrapper.findAll('.el-radio-button').find((item) => item.text().startsWith('柜子'))!.trigger('click')
await flushPromises()
await openHiddenContainerWorkbench(wrapper)
await button(wrapper, '修改接柜仓')!.trigger('click')
await flushPromises()
const warehouseSelect = wrapper.findAllComponents({ name: 'ElSelect' }).find((item) => item.props('placeholder') === '请选择 ACTIVE 海外接柜仓')!
@@ -593,8 +589,7 @@ describe('LastMileOrdersView pending order and container conversion', () => {
it('renders an explicit empty state when there are no ACTIVE OVERSEAS receiving warehouses', async () => {
vi.mocked(listAllPlatformWarehouses).mockResolvedValueOnce([])
const wrapper = await mountView()
await wrapper.findAll('.el-radio-button').find((item) => item.text().startsWith('柜子'))!.trigger('click')
await flushPromises()
await openHiddenContainerWorkbench(wrapper)
await button(wrapper, '修改接柜仓')!.trigger('click')
await flushPromises()
expect(document.body.textContent).toContain('暂无可用的 ACTIVE 海外接柜仓')
@@ -606,8 +601,7 @@ describe('LastMileOrdersView pending order and container conversion', () => {
'receiving warehouse candidate failed', 'A0503', 200, undefined, 'request-receiving-options', 'trace-receiving-options',
))
const wrapper = await mountView()
await wrapper.findAll('.el-radio-button').find((item) => item.text().startsWith('柜子'))!.trigger('click')
await flushPromises()
await openHiddenContainerWorkbench(wrapper)
await button(wrapper, '修改接柜仓')!.trigger('click')
await flushPromises()
expect(document.body.textContent).toContain('request-receiving-options')