diff --git a/src/modules/unified-orders/api/coLoadGroups.test.ts b/src/modules/unified-orders/api/coLoadGroups.test.ts
index 3e0a1039..c50e9f18 100644
--- a/src/modules/unified-orders/api/coLoadGroups.test.ts
+++ b/src/modules/unified-orders/api/coLoadGroups.test.ts
@@ -7,8 +7,8 @@ const group = {
warehouseId: 2093000000000000002n, channelCode: 'NY-EXX', lockedPlanId: null,
version: 0, fullPackageCount: 18, createdAt: '2026-08-29T10:00:00', updatedAt: '2026-08-29T10:00:00',
members: [
- { tenantId: 2093000000000000004n, orderId: 2093000000000000005n, inboundId: 2093000000000000006n, fullPackageCount: 8 },
- { tenantId: 2093000000000000007n, orderId: 2093000000000000008n, inboundId: 2093000000000000009n, fullPackageCount: 10 },
+ { tenantId: 2093000000000000004n, orderId: 2093000000000000005n, inboundId: 2093000000000000006n, inboundCode: 'NYEXX2608310001', fullPackageCount: 8 },
+ { tenantId: 2093000000000000007n, orderId: 2093000000000000008n, inboundId: 2093000000000000009n, inboundCode: 'NYEXX2608310002', fullPackageCount: 10 },
],
}
@@ -23,6 +23,7 @@ describe('co-load group API', () => {
expect(result.groupId).toBe('2093000000000000001')
expect(result.members.map((member) => member.orderId)).toEqual(orderIds)
expect(result.members.map((member) => member.tenantId)).toEqual(['2093000000000000004', '2093000000000000007'])
+ expect(result.members.map((member) => member.inboundCode)).toEqual(['NYEXX2608310001', 'NYEXX2608310002'])
})
it('cancels only the whole group with optimistic version and an optional reason', async () => {
@@ -48,7 +49,7 @@ describe('co-load group API', () => {
})
it('keeps every inbound fragment when one order has multiple current inbounds', async () => {
- const fragment = { ...group.members[0], inboundId: 2093000000000000012n, fullPackageCount: 3 }
+ const fragment = { ...group.members[0], inboundId: 2093000000000000012n, inboundCode: 'NYEXX2608310001-B', fullPackageCount: 3 }
const multiInboundGroup = { ...group, fullPackageCount: 21, members: [group.members[0], fragment, group.members[1]] }
const post = vi.spyOn(http, 'post').mockResolvedValue({ code: '200', message: 'ok', data: [
{ orderId: group.members[0].orderId, group: multiInboundGroup },
@@ -57,9 +58,9 @@ describe('co-load group API', () => {
const result = await batchQueryPlatformCoLoadGroups(['2093000000000000005', '2093000000000000008'])
expect(post).toHaveBeenCalledTimes(1)
expect(result[0].group.members).toEqual([
- expect.objectContaining({ orderId: '2093000000000000005', inboundId: '2093000000000000006', fullPackageCount: 8 }),
- expect.objectContaining({ orderId: '2093000000000000005', inboundId: '2093000000000000012', fullPackageCount: 3 }),
- expect.objectContaining({ orderId: '2093000000000000008', inboundId: '2093000000000000009', fullPackageCount: 10 }),
+ expect.objectContaining({ orderId: '2093000000000000005', inboundId: '2093000000000000006', inboundCode: 'NYEXX2608310001', fullPackageCount: 8 }),
+ expect.objectContaining({ orderId: '2093000000000000005', inboundId: '2093000000000000012', inboundCode: 'NYEXX2608310001-B', fullPackageCount: 3 }),
+ expect.objectContaining({ orderId: '2093000000000000008', inboundId: '2093000000000000009', inboundCode: 'NYEXX2608310002', fullPackageCount: 10 }),
])
})
})
diff --git a/src/modules/unified-orders/api/coLoadGroups.ts b/src/modules/unified-orders/api/coLoadGroups.ts
index 86039995..5f16fee2 100644
--- a/src/modules/unified-orders/api/coLoadGroups.ts
+++ b/src/modules/unified-orders/api/coLoadGroups.ts
@@ -6,6 +6,7 @@ export interface CoLoadGroupMember {
tenantId: string
orderId: string
inboundId: string
+ inboundCode: string
fullPackageCount: number
}
diff --git a/src/modules/unified-orders/pages/UnifiedOrdersView.coLoad.test.ts b/src/modules/unified-orders/pages/UnifiedOrdersView.coLoad.test.ts
index 95bb9409..abf60f4e 100644
--- a/src/modules/unified-orders/pages/UnifiedOrdersView.coLoad.test.ts
+++ b/src/modules/unified-orders/pages/UnifiedOrdersView.coLoad.test.ts
@@ -33,7 +33,7 @@ const rows = ['5001', '5002'].map((orderId, index) => ({
}))
const group = {
groupId: '9001', groupNo: 'CLG-9001', status: 'ACTIVE' as const, warehouseId: '8', channelCode: 'NY-EXX', lockedPlanId: null, version: 0, fullPackageCount: 10,
- members: rows.map((row) => ({ tenantId: String(row.tenantId), orderId: String(row.orderId), inboundId: String(row.inboundId), fullPackageCount: 5 })),
+ members: rows.map((row) => ({ tenantId: String(row.tenantId), orderId: String(row.orderId), inboundId: String(row.inboundId), inboundCode: String(row.inboundCode), fullPackageCount: 5 })),
createdAt: '2026-08-29T10:00:00', updatedAt: '2026-08-29T10:00:00',
}
@@ -43,7 +43,7 @@ function mountView() {
AdminPage: { template: '' },
ListPageLayout: { template: '' },
QueryToolbar: { template: '
' },
- DataTable: { name: 'DataTable', props: ['data'], emits: ['selection-change'], template: '' },
+ DataTable: { name: 'DataTable', props: ['data'], emits: ['selection-change'], template: '' },
AppDialog: { name: 'AppDialog', props: ['modelValue', 'confirmText'], emits: ['confirm', 'update:modelValue'], template: '' },
ApiErrorMeta: { props: ['details'], template: '{{ details.code }} {{ details.requestId }} {{ details.traceId }}
' },
CopyButton: { props: ['value', 'label'], template: '' },
@@ -76,23 +76,39 @@ describe('UnifiedOrdersView co-load group behavior', () => {
expect(listPlatformUnifiedOrders).toHaveBeenCalledTimes(1)
})
- it('shows group number and member count and cancels only the whole ACTIVE group', async () => {
+ 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()
+ await flushPromises()
+ expect(wrapper.text()).toContain('IN-1')
+ expect(wrapper.text()).toContain('待生成入仓码')
+ expect(wrapper.text()).not.toContain('ORD-1')
+ expect(wrapper.text()).not.toContain('ORD-2')
+ expect(wrapper.text()).not.toContain('5001')
+ expect(wrapper.text()).not.toContain('7000')
+ })
+
+ it('shows a business-only group summary and all server-provided inbound codes in the dialog', async () => {
const multiInboundGroup = {
...group,
fullPackageCount: 13,
- members: [group.members[0], { ...group.members[0], inboundId: '7003', fullPackageCount: 3 }, group.members[1]],
+ members: [group.members[0], { ...group.members[0], inboundId: '7003', inboundCode: 'IN-1-B', fullPackageCount: 3 }, group.members[1]],
}
vi.mocked(batchQueryPlatformCoLoadGroups).mockResolvedValue(rows.map((row) => ({ orderId: row.orderId, group: multiInboundGroup })))
vi.mocked(cancelPlatformCoLoadGroup).mockResolvedValue({ ...multiInboundGroup, status: 'CANCELLED', version: 1 })
vi.spyOn(ElMessageBox, 'prompt').mockResolvedValue({ value: '计划调整', action: 'confirm' } as never)
const wrapper = mountView()
await flushPromises()
- expect(wrapper.text()).toContain('CLG-9001')
- expect(wrapper.text()).toContain('CLG-9001 · 2 票 · 未锁定')
- await wrapper.get('[aria-label="查看同柜组 CLG-9001 详情"]').trigger('click')
- expect(wrapper.text()).toContain('2 票 · 3 个入仓片段 · 未锁定')
+ expect(wrapper.text()).toContain('同柜组 · 2 票 · 未锁定')
+ expect(wrapper.text()).not.toContain('CLG-9001')
+ await wrapper.get('[aria-label="查看同柜组 · 2 票 · 未锁定成员"]').trigger('click')
+ expect(wrapper.text()).toContain('3 个入仓码')
expect(wrapper.text()).toContain('13 箱')
- expect(wrapper.text()).toContain('入仓码待补充')
+ expect(wrapper.text()).toContain('IN-1')
+ expect(wrapper.text()).toContain('IN-1-B')
+ expect(wrapper.text()).toContain('IN-2')
+ expect(wrapper.text()).not.toContain('ORD-1')
+ expect(wrapper.text()).not.toContain('ORD-2')
expect(wrapper.text()).not.toContain('7003')
expect(wrapper.text()).not.toContain('5001')
await wrapper.findAll('button').find((button) => button.text().includes('取消同柜组'))!.trigger('click')
diff --git a/src/modules/unified-orders/pages/UnifiedOrdersView.test.ts b/src/modules/unified-orders/pages/UnifiedOrdersView.test.ts
index f40ce574..3fae982f 100644
--- a/src/modules/unified-orders/pages/UnifiedOrdersView.test.ts
+++ b/src/modules/unified-orders/pages/UnifiedOrdersView.test.ts
@@ -95,7 +95,7 @@ describe('UnifiedOrdersView contract', () => {
expect(source).toContain('v-model:page-size="pageSize"')
const columnSource = source.slice(source.indexOf('const columns ='), source.indexOf('function emptyFilters'))
const expectedColumnKeys = [
- 'actions', 'orderNo', 'inboundCode', 'mainStatus', 'customerName', 'receivingWarehouseName',
+ 'actions', 'inboundCode', 'mainStatus', 'customerName', 'receivingWarehouseName',
'destinationWarehouseName', 'channelName', 'totalPackageCount', 'totalPalletCount', 'requestedPickupAt', 'locationCodes', 'measurementReviewStatus', 'actualGrossWeightKg',
'actualVolumeCbm', 'totalNetWeightKg', 'chargeableWeightKg', 'chargeableVolumeCbm', 'expectedShipDate',
'expectedArrivalAt', 'feeReviewStatus', 'skuNos', 'totalQuantity', 'expressCompany', 'expressTrackingNo',
@@ -106,10 +106,10 @@ describe('UnifiedOrdersView contract', () => {
for (const uncontractedKey of [
'internalOrderStatus', 'holdCargo', 'companyName', 'pickupMethod', 'associatedFiles', 'createdBy',
]) expect(columnSource).not.toContain(`key: '${uncontractedKey}'`)
- expect(columnSource.indexOf("key: 'actions'")).toBeLessThan(columnSource.indexOf("key: 'orderNo'"))
- expect(columnSource.indexOf("key: 'orderNo'")).toBeLessThan(columnSource.indexOf("key: 'inboundCode'"))
+ expect(columnSource.indexOf("key: 'actions'")).toBeLessThan(columnSource.indexOf("key: 'inboundCode'"))
expect(columnSource).not.toContain("key: 'coLoadGroup'")
- expect(columnSource).toContain("key: 'orderNo', prop: 'orderNo', label: '订单号', minWidth: 230, slotName: 'orderNo'")
+ expect(columnSource).not.toContain("key: 'orderNo'")
+ expect(columnSource).toContain("key: 'inboundCode', prop: 'inboundCode', label: '入仓码', minWidth: 260, slotName: 'inboundCode'")
expect(columnSource).toContain("{ key: 'mainStatus', prop: 'mainStatus', label: '订单主状态'")
expect(columnSource).not.toContain("key: 'loadingStatus'")
expect(columnSource).not.toContain("key: 'businessDate'")
@@ -176,18 +176,21 @@ describe('UnifiedOrdersView contract', () => {
expect(createSource).toContain('createPlatformCoLoadGroup(selectedOrders.value.map((row) => String(row.orderId)))')
})
- it('embeds a clickable compact group tag under the order code without an empty placeholder column', () => {
+ it('uses inbound code as the only list identifier and opens a business-only group dialog', () => {
expect(source).not.toContain("{ key: 'coLoadGroup', label: '同柜组'")
- expect(source).toContain('')
+ expect(source).not.toContain('')
+ expect(source).toContain("inboundCode || '待生成入仓码'")
expect(source).toContain('class="coload-tag-trigger"')
- expect(source).toContain('coLoadGroupOrderCount(coLoadGroup(row as UnifiedOrderResource)!)')
+ expect(source).toContain('coLoadGroupSummary(coLoadGroup(row as UnifiedOrderResource)!)')
+ expect(source).not.toContain('coLoadDetailGroup.groupNo')
expect(source).not.toContain('—\n 入仓码| 订单编码 | ')
- expect(source).toContain("visibleInboundCode(member.inboundId) || '入仓码待补充'")
- expect(source).toContain("visibleOrderNo(member.orderId) || '订单编码待补充'")
- expect(source).not.toContain('入仓码 / 入仓 ID')
- expect(source).not.toContain('订单编码 / ID')
+ expect(source).toContain('v-for="member in coLoadDetailMembers"')
+ expect(source).toContain('入仓码 | 箱数 | ')
+ expect(source).toContain('{{ member.inboundCode }}')
+ expect(source).not.toContain('visibleInboundCode')
+ expect(source).not.toContain('visibleOrderNo')
+ expect(source).not.toContain('订单编码 | ')
expect(source).not.toContain('客户 ID')
})
diff --git a/src/modules/unified-orders/pages/UnifiedOrdersView.vue b/src/modules/unified-orders/pages/UnifiedOrdersView.vue
index 4f96a6ff..20232edd 100644
--- a/src/modules/unified-orders/pages/UnifiedOrdersView.vue
+++ b/src/modules/unified-orders/pages/UnifiedOrdersView.vue
@@ -260,8 +260,7 @@ const columns = computed(() => [
key: 'selection', type: 'selection', width: 48, fixed: 'left',
selectable: () => !batchApprovalSaving.value && !coLoadSaving.value,
} satisfies DataTableColumn] : []),
- { key: 'orderNo', prop: 'orderNo', label: '订单号', minWidth: 230, slotName: 'orderNo' },
- { key: 'inboundCode', prop: 'inboundCode', label: '入仓码', minWidth: 190, slotName: 'inboundCode' },
+ { key: 'inboundCode', prop: 'inboundCode', label: '入仓码', minWidth: 260, slotName: 'inboundCode' },
{ key: 'mainStatus', prop: 'mainStatus', label: '订单主状态', minWidth: 130, slotName: 'mainStatus' },
{ key: 'customerName', prop: 'customerName', label: '客户', minWidth: 150, slotName: 'field' },
{ key: 'receivingWarehouseName', prop: 'receivingWarehouseName', label: '平台收货仓', minWidth: 150, slotName: 'field' },
@@ -816,18 +815,16 @@ function coLoadGroupStatusLabel(group: CoLoadGroup) {
return group.status === 'ACTIVE' ? '未锁定' : group.status === 'LOCKED' ? '已锁定' : group.status === 'CONSUMED' ? '已消费' : '已取消'
}
+function coLoadGroupSummary(group: CoLoadGroup) {
+ return `同柜组 · ${coLoadGroupOrderCount(group)} 票 · ${coLoadGroupStatusLabel(group)}`
+}
+
+const coLoadDetailMembers = computed(() => coLoadDetailGroup.value?.members.filter((member) => member.inboundCode.trim()) || [])
+
function openCoLoadDetail(group: CoLoadGroup) {
coLoadDetailGroup.value = group
}
-function visibleOrderNo(orderId: string) {
- return records.value.find((row) => String(row.orderId) === orderId)?.orderNo || ''
-}
-
-function visibleInboundCode(inboundId: string) {
- return records.value.find((row) => String(row.inboundId || '') === inboundId)?.inboundCode || ''
-}
-
function openCoLoadCreate() {
if (selectedOrders.value.length < 2) return
coLoadError.value = null
@@ -841,7 +838,7 @@ async function createCoLoadGroup() {
try {
const group = await createPlatformCoLoadGroup(selectedOrders.value.map((row) => String(row.orderId)))
coLoadCreateOpen.value = false
- ElMessage.success(`已创建同柜不可拆组 ${group.groupNo},共 ${coLoadGroupMemberLabel(group)}`)
+ ElMessage.success(`已创建同柜不可拆组,共 ${coLoadGroupMemberLabel(group)}`)
await loadOrders()
} catch (error) {
coLoadError.value = getApiErrorDetails(error, '创建同柜不可拆组失败')
@@ -856,7 +853,7 @@ async function cancelCoLoadGroup(row: UnifiedOrderResource) {
let reason = ''
try {
const result = await ElMessageBox.prompt(
- `将整组取消 ${group.groupNo}(${coLoadGroupMemberLabel(group)})。不支持单独移除成员;如需调整,请取消后重新建组。`,
+ `将整组取消(${coLoadGroupMemberLabel(group)})。不支持单独移除成员;如需调整,请取消后重新建组。`,
'取消同柜不可拆组',
{ confirmButtonText: '确认整组取消', cancelButtonText: '返回', inputPlaceholder: '取消原因(选填)', inputType: 'textarea' },
)
@@ -866,7 +863,7 @@ async function cancelCoLoadGroup(row: UnifiedOrderResource) {
coLoadError.value = null
try {
await cancelPlatformCoLoadGroup(group.groupId, group.version, reason)
- ElMessage.success(`同柜不可拆组 ${group.groupNo} 已整组取消`)
+ ElMessage.success('同柜不可拆组已整组取消')
await loadOrders()
} catch (error) {
coLoadError.value = getApiErrorDetails(error, '取消同柜不可拆组失败')
@@ -1362,8 +1359,9 @@ onBeforeUnmount(() => {
-
-
{{ (row as UnifiedOrderResource).inboundCode || '—' }}
+
+ {{ (row as UnifiedOrderResource).inboundCode || '待生成入仓码' }}
+
关联数据
{
>{{ orderRelationLabel(row as UnifiedOrderResource) }}
-
{{ (row as UnifiedOrderResource).orderNo || '订单编码待补充' }}
{{ displayField(row as UnifiedOrderResource, column.property) }}
@@ -1395,18 +1392,19 @@ onBeforeUnmount(() => {
- {{ row.orderNo || row.inboundCode || '业务编码待补充' }}
+ {{ row.inboundCode || '待生成入仓码' }}
{{ coLoadError.message }}
-
+
- {{ coLoadGroupOrderCount(coLoadDetailGroup) }} 票 · {{ coLoadDetailGroup.members.length }} 个入仓片段 · {{ coLoadGroupStatusLabel(coLoadDetailGroup) }}共 {{ coLoadDetailGroup.fullPackageCount }} 箱
-