fix(admin): validate co-load routes by business code

This commit is contained in:
2026-08-31 15:50:05 +08:00
parent afbee83b51
commit 1a81a5a2b6
5 changed files with 70 additions and 13 deletions
@@ -24,7 +24,7 @@ vi.mock('@/modules/unified-orders/api/coLoadGroups', () => ({
const rows = ['5001', '5002'].map((orderId, index) => ({
orderId, tenantId: `600${index}`, orderNo: `ORD-${index + 1}`, mainStatus: 'WAIT_SPLIT' as const, nextAction: null,
relation: null, internalOrderStatus: 'WAIT_SPLIT', customerId: `600${index}`, customerName: `客户${index + 1}`,
channelName: 'NY-EXX', receivingWarehouseId: '8', receivingWarehouseName: '义乌仓', destinationWarehouseId: '9', destinationWarehouseName: 'ONT8',
channelCode: 'NY_EXX', channelName: '纽约渠道', receivingWarehouseId: '8', receivingWarehouseName: '义乌仓', destinationWarehouseId: '9', destinationWarehouseName: 'ONT8',
inboundId: `700${index}`, inboundVersion: 1, inboundCode: `IN-${index + 1}`, expectedShipDate: null, totalPackageCount: 5,
locationCodes: null, actualGrossWeightKg: 10, actualVolumeCbm: 1, measurement: null, preload: null, loading: null, delivery: null, transport: null,
createdAt: null, updatedAt: null, expectedArrivalAt: null, feeReviewStatus: null, requestedPickupAt: null, totalPalletCount: null,
@@ -68,12 +68,14 @@ describe('UnifiedOrdersView co-load group behavior', () => {
expect(wrapper.text()).toContain('设为同柜不可拆组(2)')
expect(wrapper.text()).toContain('成员路线不一致')
expect(wrapper.text()).toContain('A0409 request-coload trace-coload')
expect(wrapper.text()).not.toContain('5001')
expect(wrapper.text()).not.toContain('5002')
expect(listPlatformUnifiedOrders).toHaveBeenCalledTimes(1)
})
it.each([
['平台收货仓不同', [{ ...rows[0], receivingWarehouseId: '8' }, { ...rows[1], receivingWarehouseId: '9' }], '所选订单的平台收货仓不同,不能设为同柜组'],
['渠道不同', [{ ...rows[0], channelName: 'NY-EXX' }, { ...rows[1], channelName: 'LA-SEA' }], '所选订单的渠道不同,不能设为同柜组'],
['平台收货仓不同', [{ ...rows[0], receivingWarehouseId: '8', receivingWarehouseName: '义乌仓' }, { ...rows[1], receivingWarehouseId: '9', receivingWarehouseName: '东莞仓' }], '所选订单的平台收货仓不同:IN-1(仓库:义乌仓;渠道:纽约渠道)、IN-2(仓库:东莞仓;渠道:纽约渠道),不能设为同柜组'],
['渠道不同', [{ ...rows[0], channelCode: 'NY_EXX', channelName: '纽约渠道' }, { ...rows[1], channelCode: 'LA_SEA', channelName: '洛杉矶渠道' }], '所选订单的渠道不同:IN-1(仓库:义乌仓;渠道:纽约渠道)、IN-2(仓库:义乌仓;渠道:洛杉矶渠道),不能设为同柜组'],
['已有同柜组', [rows[0], { ...rows[1], coLoadGroup: { status: 'ACTIVE', memberCount: 2, memberInboundCodes: ['IN-2', 'IN-3'] } }], '所选订单中已有同柜组,请先解除原同柜组'],
])('blocks create immediately when %s', async (_case, selectedRows, reason) => {
vi.mocked(listPlatformUnifiedOrders).mockResolvedValue({ records: selectedRows, page: 1, size: 20, total: 2, pages: 1 })
@@ -87,6 +89,39 @@ describe('UnifiedOrdersView co-load group behavior', () => {
expect(createPlatformCoLoadGroup).not.toHaveBeenCalled()
})
it.each([
['平台收货仓', [{ ...rows[0], receivingWarehouseId: null, receivingWarehouseName: null }, rows[1]], '以下入仓码缺少平台收货仓:IN-1(仓库:未配置仓库;渠道:纽约渠道),请刷新后重试'],
['渠道', [{ ...rows[0], channelCode: null, channelName: null }, rows[1]], '以下入仓码缺少渠道:IN-1(仓库:义乌仓;渠道:未配置渠道),请刷新后重试'],
])('lists the affected inbound code and display names when %s is missing', async (_case, selectedRows, reason) => {
vi.mocked(listPlatformUnifiedOrders).mockResolvedValue({ records: selectedRows, page: 1, size: 20, total: 2, pages: 1 })
const wrapper = mountView()
await flushPromises()
await wrapper.get('[data-testid="select"]').trigger('click')
expect(wrapper.text()).toContain(reason)
expect(createPlatformCoLoadGroup).not.toHaveBeenCalled()
})
it('allows different display names for the same channel code', async () => {
vi.mocked(listPlatformUnifiedOrders).mockResolvedValue({ records: [rows[0], { ...rows[1], channelName: '纽约渠道(新名称)' }], page: 1, size: 20, total: 2, pages: 1 })
vi.mocked(createPlatformCoLoadGroup).mockResolvedValue({ groupId: '9001', groupNo: 'CLG-1', status: 'ACTIVE', warehouseId: '8', channelCode: 'NY_EXX', lockedPlanId: null, version: 1, members: [], fullPackageCount: 10, createdAt: '', updatedAt: '' })
const wrapper = mountView()
await flushPromises()
await wrapper.get('[data-testid="select"]').trigger('click')
await wrapper.findAll('button').find((button) => button.text().includes('设为同柜不可拆组'))!.trigger('click')
await wrapper.get('[data-testid="dialog-confirm"]').trigger('click')
await flushPromises()
expect(createPlatformCoLoadGroup).toHaveBeenCalledWith(['5001', '5002'])
})
it('blocks identical display names when channel codes differ', async () => {
vi.mocked(listPlatformUnifiedOrders).mockResolvedValue({ records: [rows[0], { ...rows[1], channelCode: 'LA_SEA', channelName: '纽约渠道' }], page: 1, size: 20, total: 2, pages: 1 })
const wrapper = mountView()
await flushPromises()
await wrapper.get('[data-testid="select"]').trigger('click')
expect(wrapper.text()).toContain('所选订单的渠道不同:IN-1(仓库:义乌仓;渠道:纽约渠道)、IN-2(仓库:义乌仓;渠道:纽约渠道),不能设为同柜组')
expect(createPlatformCoLoadGroup).not.toHaveBeenCalled()
})
it('uses inbound codes as the only row identifier and shows an explicit pending state', async () => {
vi.mocked(listPlatformUnifiedOrders).mockResolvedValue({ records: [rows[0], { ...rows[1], inboundCode: null }], page: 1, size: 20, total: 2, pages: 1 })
const wrapper = mountView()