This commit is contained in:
2026-08-17 19:57:35 +08:00
parent 0f352bbdf9
commit 771ed6f059
4 changed files with 65 additions and 19 deletions
@@ -137,10 +137,12 @@ test('downloads selected carton labels with one array request', () => {
test('exports every visible order field with normalized dates', () => {
assert.match(source, /function formatExportDateTime\(value: string \| null \| undefined\)/)
assert.match(source, /return `\$\{date\.getFullYear\(\)\}-\$\{pad\(date\.getMonth\(\) \+ 1\)\}-\$\{pad\(date\.getDate\(\)\)\} \$\{pad\(date\.getHours\(\)\)\}:\$\{pad\(date\.getMinutes\(\)\)\}:\$\{pad\(date\.getSeconds\(\)\)\}`/)
for (const label of ['订单号', '入仓码', '渠道', '目的仓', '当前订单状态', '箱数', '快递公司', '快递单号', 'SKUS', '总毛重', '总净重', '总体积', '总数量', '计费单价', '计费体积', '计费重量', '备注', '货件编号', '跟踪编号', '国内仓入库时间', '创建时间']) {
for (const label of ['订单号', '入仓码', '渠道', '运输方式', '交货方式', '预约提货时间', '目的仓', '目的仓类型', '当前订单状态', '箱数', '快递公司', '快递单号', 'SKUS', '总毛重', '总净重', '总体积', '总数量', '计费单价', '计费体积', '计费重量', '备注', '货件编号', '跟踪编号', '国内仓入库时间', '创建时间']) {
assert.match(source, new RegExp(`'${label}'`))
}
assert.match(source, /formatExportDateTime\(order\.inboundedAt\)/)
assert.match(source, /order\.pickupMethod === 'PICKUP' \? formatExportDateTime\(order\.requestedPickupAt\) : '-'/)
assert.match(source, /formatListMetric\(order\.chargeableVolumeCbm, 'm³'\)/)
assert.doesNotMatch(source, /formatExportDateTime\(order\.businessDate\)/)
assert.match(source, /formatExportDateTime\(order\.createdAt\)/)
})
@@ -156,7 +158,7 @@ test('matches the prototype with selectable dense order-list columns', () => {
assert.match(source, />恢复默认<\/el-button>/)
assert.match(source, /const visibleOrderColumns = computed/)
assert.match(source, /:columns="visibleOrderColumns"/)
for (const label of ['入仓码', '渠道', '目的仓', '当前订单状态', '箱数', '快递公司', '快递单号', 'SKUS', '总毛重', '总净重', '总体积', '总数量', '计费单价', '计费体积', '计费重量', '备注', '货件编号', '跟踪编号', '国内仓入库时间']) {
for (const label of ['入仓码', '渠道', '运输方式', '交货方式', '预约提货时间', '目的仓', '目的仓类型', '当前订单状态', '箱数', '快递公司', '快递单号', 'SKUS', '总毛重', '总净重', '总体积', '总数量', '计费单价', '计费体积', '计费重量', '备注', '货件编号', '跟踪编号', '国内仓入库时间']) {
assert.match(source, new RegExp(`label: '${label}'`))
}
assert.match(source, /order\.businessSummary\.totalPackageCount/)
@@ -164,7 +166,8 @@ test('matches the prototype with selectable dense order-list columns', () => {
assert.match(source, /order\.items\.reduce/)
assert.match(source, /<template #chargeableWeight>-<\/template>/)
assert.match(source, /<template #billingUnitPrice>-<\/template>/)
assert.match(source, /<template #chargeableVolume>-<\/template>/)
assert.match(source, /<template #chargeableVolume="\{ row \}">\{\{ formatListMetric\(\(row as FirstLegOrder\)\.chargeableVolumeCbm, 'm³'\) \}\}<\/template>/)
assert.match(source, /pickupMethod === 'PICKUP'[\s\S]{0,160}requestedPickupAt[\s\S]{0,160}: '-'/)
assert.match(source, /inboundedAt/)
assert.doesNotMatch(source, /label: '业务日期'/)
assert.doesNotMatch(source, /<template #businessDate>/)
@@ -94,8 +94,12 @@ const fixedOrderColumns: DataTableColumn[] = [
const selectableOrderColumns: DataTableColumn[] = [
{ key: 'inboundCode', label: '入仓码', width: 176, align: 'left', headerAlign: 'left', showOverflowTooltip: true, slotName: 'inboundCode' },
{ key: 'channel', label: '渠道', width: 150, align: 'left', headerAlign: 'left', showOverflowTooltip: true, slotName: 'channel' },
{ key: 'transportMode', label: '运输方式', width: 104, align: 'center', headerAlign: 'center', slotName: 'transportMode' },
{ key: 'pickupMethod', label: '交货方式', width: 112, align: 'center', headerAlign: 'center', slotName: 'pickupMethod' },
{ key: 'requestedPickupAt', label: '预约提货时间', width: 164, align: 'center', headerAlign: 'center', slotName: 'requestedPickupAt' },
{ key: 'receivingWarehouse', label: '国内收货仓', width: 150, align: 'left', headerAlign: 'left', showOverflowTooltip: true, slotName: 'receivingWarehouse' },
{ key: 'destinationWarehouse', label: '目的仓', width: 120, align: 'left', headerAlign: 'left', showOverflowTooltip: true, slotName: 'destinationWarehouse' },
{ key: 'destinationType', label: '目的仓类型', width: 112, align: 'center', headerAlign: 'center', slotName: 'destinationType' },
{ key: 'status', label: '当前订单状态', width: 126, align: 'center', headerAlign: 'center', slotName: 'status' },
{ key: 'packageCount', label: '箱数', width: 82, align: 'center', headerAlign: 'center', slotName: 'packageCount' },
{ key: 'expressCompany', label: '快递公司', width: 128, align: 'left', headerAlign: 'left', showOverflowTooltip: true, slotName: 'expressCompany' },
@@ -1241,7 +1245,11 @@ function exportOrderInformation() {
displayListValue(order.orderNo),
displayListValue(order.businessSummary.inboundCode),
displayListValue(order.channelName),
order.transportMode ? getFirstLegTransportModeLabel(order.transportMode) : '-',
pickupMethodLabels[order.pickupMethod],
order.pickupMethod === 'PICKUP' ? formatExportDateTime(order.requestedPickupAt) : '-',
displayListValue(order.destinationWarehouseName),
destinationTypeLabels[order.destinationType],
getFirstLegStatusLabel(order.status),
formatListMetric(orderPackageCount(order)),
displayListValue(order.expressCompanyName),
@@ -1252,7 +1260,7 @@ function exportOrderInformation() {
formatListMetric(orderVolume(order), 'm³'),
formatListMetric(orderItemTotal(order, 'pieces')),
'-',
'-',
formatListMetric(order.chargeableVolumeCbm, 'm³'),
'-',
displayListValue(order.customerRemark),
displayListValue(order.shipmentId || uniqueItemValues(order, 'shipmentId')),
@@ -1261,7 +1269,7 @@ function exportOrderInformation() {
formatExportDateTime(order.createdAt),
])
downloadCsv('订单信息.csv', [[
'订单号', '入仓码', '渠道', '目的仓', '当前订单状态', '箱数', '快递公司', '快递单号', 'SKUS',
'订单号', '入仓码', '渠道', '运输方式', '交货方式', '预约提货时间', '目的仓', '目的仓类型', '当前订单状态', '箱数', '快递公司', '快递单号', 'SKUS',
'总毛重', '总净重', '总体积', '总数量', '计费单价', '计费体积', '计费重量', '备注',
'货件编号', '跟踪编号', '国内仓入库时间', '创建时间',
], ...rows])
@@ -1547,8 +1555,12 @@ async function searchOrders(model: QueryModel) {
</template>
<template #inboundCode="{ row }"><span class="table-ellipsis table-code" :title="displayListValue((row as FirstLegOrder).businessSummary.inboundCode)">{{ displayListValue((row as FirstLegOrder).businessSummary.inboundCode) }}</span></template>
<template #channel="{ row }"><span class="table-ellipsis" :title="displayListValue((row as FirstLegOrder).channelName)">{{ displayListValue((row as FirstLegOrder).channelName) }}</span></template>
<template #transportMode="{ row }">{{ (row as FirstLegOrder).transportMode ? getFirstLegTransportModeLabel((row as FirstLegOrder).transportMode) : '-' }}</template>
<template #pickupMethod="{ row }">{{ pickupMethodLabels[(row as FirstLegOrder).pickupMethod] }}</template>
<template #requestedPickupAt="{ row }">{{ (row as FirstLegOrder).pickupMethod === 'PICKUP' && (row as FirstLegOrder).requestedPickupAt ? formatDateTime((row as FirstLegOrder).requestedPickupAt) : '-' }}</template>
<template #receivingWarehouse="{ row }"><span class="table-ellipsis" :title="displayListValue((row as FirstLegOrder).receivingWarehouseName)">{{ displayListValue((row as FirstLegOrder).receivingWarehouseName) }}</span></template>
<template #destinationWarehouse="{ row }"><span class="table-ellipsis" :title="displayListValue((row as FirstLegOrder).destinationWarehouseName)">{{ displayListValue((row as FirstLegOrder).destinationWarehouseName) }}</span></template>
<template #destinationType="{ row }">{{ destinationTypeLabels[(row as FirstLegOrder).destinationType] }}</template>
<template #status="{ row }"><el-tag :type="getFirstLegStatusTone((row as FirstLegOrder).status)" effect="light">{{ getFirstLegStatusLabel((row as FirstLegOrder).status) }}</el-tag></template>
<template #packageCount="{ row }">{{ formatListMetric(orderPackageCount(row as FirstLegOrder)) }}</template>
<template #expressCompany="{ row }"><span class="table-ellipsis" :title="displayListValue((row as FirstLegOrder).expressCompanyName)">{{ displayListValue((row as FirstLegOrder).expressCompanyName) }}</span></template>
@@ -1559,7 +1571,7 @@ async function searchOrders(model: QueryModel) {
<template #volume="{ row }">{{ formatListMetric(orderVolume(row as FirstLegOrder), 'm³') }}</template>
<template #pieces="{ row }">{{ formatListMetric(orderItemTotal(row as FirstLegOrder, 'pieces')) }}</template>
<template #billingUnitPrice>-</template>
<template #chargeableVolume>-</template>
<template #chargeableVolume="{ row }">{{ formatListMetric((row as FirstLegOrder).chargeableVolumeCbm, 'm³') }}</template>
<template #chargeableWeight>-</template>
<template #remark="{ row }"><span class="table-ellipsis" :title="(row as FirstLegOrder).customerRemark">{{ displayListValue((row as FirstLegOrder).customerRemark) }}</span></template>
<template #shipmentId="{ row }"><span class="table-ellipsis table-code" :title="displayListValue((row as FirstLegOrder).shipmentId || uniqueItemValues(row as FirstLegOrder, 'shipmentId'))">{{ displayListValue((row as FirstLegOrder).shipmentId || uniqueItemValues(row as FirstLegOrder, 'shipmentId')) }}</span></template>
@@ -1584,7 +1596,7 @@ async function searchOrders(model: QueryModel) {
<header><button type="button" @click="openDetail(order)">{{ order.orderNo || '未提交草稿' }}</button><el-tag :type="getFirstLegStatusTone(order.status)" effect="light">{{ getFirstLegStatusLabel(order.status) }}</el-tag></header>
<span v-if="order.businessSummary.inboundCode" class="order-reference">入仓码 {{ order.businessSummary.inboundCode }}</span>
<span class="order-reference">{{ order.referenceNo || '无 Reference ID' }}</span>
<dl><div><dt>目的地</dt><dd>{{ order.destination || '待更新' }}</dd></div><div><dt>收货仓</dt><dd>{{ order.receivingWarehouseName || '待更新' }}</dd></div><div><dt>货物摘要</dt><dd>{{ getOrderCargoSummary(order) }}</dd></div><div><dt>运输渠道</dt><dd>{{ order.transportMode ? getFirstLegTransportModeLabel(order.transportMode) : order.channelName || '待更新' }}</dd></div><div v-if="order.businessSummary.cabinetNo || order.businessSummary.containerNo"><dt>柜号 / 柜次</dt><dd>{{ order.businessSummary.cabinetNo || order.businessSummary.containerNo }}</dd></div><div v-if="order.businessSummary.vesselName || order.businessSummary.voyageNo"><dt>船名 / 航次</dt><dd>{{ [order.businessSummary.vesselName, order.businessSummary.voyageNo].filter(Boolean).join(' · ') }}</dd></div><div v-if="order.businessSummary.sailingAt"><dt>预计船期</dt><dd>{{ formatDateTime(order.businessSummary.sailingAt) }}</dd></div></dl>
<dl><div><dt>目的地</dt><dd>{{ order.destination || '待更新' }}</dd></div><div><dt>目的仓类型</dt><dd>{{ destinationTypeLabels[order.destinationType] }}</dd></div><div><dt>收货仓</dt><dd>{{ order.receivingWarehouseName || '待更新' }}</dd></div><div><dt>货物摘要</dt><dd>{{ getOrderCargoSummary(order) }}</dd></div><div><dt>运输方式</dt><dd>{{ order.transportMode ? getFirstLegTransportModeLabel(order.transportMode) : '待更新' }}</dd></div><div><dt>交货方式</dt><dd>{{ pickupMethodLabels[order.pickupMethod] }}</dd></div><div><dt>预约提货时间</dt><dd>{{ order.pickupMethod === 'PICKUP' && order.requestedPickupAt ? formatDateTime(order.requestedPickupAt) : '-' }}</dd></div><div v-if="order.businessSummary.cabinetNo || order.businessSummary.containerNo"><dt>柜号 / 柜次</dt><dd>{{ order.businessSummary.cabinetNo || order.businessSummary.containerNo }}</dd></div><div v-if="order.businessSummary.vesselName || order.businessSummary.voyageNo"><dt>船名 / 航次</dt><dd>{{ [order.businessSummary.vesselName, order.businessSummary.voyageNo].filter(Boolean).join(' · ') }}</dd></div><div v-if="order.businessSummary.sailingAt"><dt>预计船期</dt><dd>{{ formatDateTime(order.businessSummary.sailingAt) }}</dd></div></dl>
<footer><span>更新于 {{ formatDateTime(order.updatedAt) }}</span><div><el-button link type="primary" @click="openDetail(order)"><Eye :size="15" />详情</el-button><el-button v-if="canEditOrder && canClientEditFirstLegOrder(order.status)" link type="primary" :loading="openingEditor" @click="openEdit(order)"><Pencil :size="15" />编辑</el-button></div></footer>
</article>
</div>
@@ -1740,6 +1752,7 @@ async function searchOrders(model: QueryModel) {
<div><dt>运输方式</dt><dd>{{ getFirstLegTransportModeLabel(detailOrder.transportMode) }}</dd></div>
<div><dt>贸易条款</dt><dd>{{ displayValue(detailOrder.tradeTerm) }}</dd></div>
<div><dt>发货方式</dt><dd>{{ pickupMethodLabels[detailOrder.pickupMethod] }}</dd></div>
<div><dt>预约提货时间</dt><dd>{{ detailOrder.pickupMethod === 'PICKUP' && detailOrder.requestedPickupAt ? formatDateTime(detailOrder.requestedPickupAt) : '-' }}</dd></div>
<div><dt>报关方式</dt><dd>{{ taxModeLabels[detailOrder.taxMode] }}</dd></div>
<div><dt>运输渠道</dt><dd>{{ detailOrder.channelName || detailOrder.channelCode || '-' }}<span v-if="detailOrder.channelName && detailOrder.channelCode" class="detail-subline">{{ detailOrder.channelCode }}</span></dd></div>
<div><dt>国内收货仓</dt><dd>{{ detailOrder.receivingWarehouseSnapshot?.name || detailOrder.receivingWarehouseName || '-' }}<span v-if="detailOrder.receivingWarehouseSnapshot" class="detail-subline">{{ detailOrder.receivingWarehouseSnapshot.code || '仓库编码待更新' }} · {{ detailOrder.receivingWarehouseSnapshot.province }}{{ detailOrder.receivingWarehouseSnapshot.city }}{{ detailOrder.receivingWarehouseSnapshot.address }}</span></dd></div>