优化
This commit is contained in:
@@ -95,21 +95,21 @@ 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', 'inboundCode', 'mainStatus', 'customerName', 'receivingWarehouseName',
|
||||
'destinationWarehouseName', 'totalPackageCount', 'measurementReviewStatus', 'actualGrossWeightKg',
|
||||
'actions', 'orderNo', 'inboundCode', 'mainStatus', 'customerName', 'receivingWarehouseName',
|
||||
'destinationWarehouseName', 'channelName', 'totalPackageCount', 'recommendedPalletType', 'locationCodes', 'measurementReviewStatus', 'actualGrossWeightKg',
|
||||
'actualVolumeCbm', 'chargeableWeightKg', 'expectedShipDate', 'loadingStatus', 'containerNo', 'cabinetNo',
|
||||
'sailingAt', 'portArrivalAt', 'customerRemark', 'latestInternalNote', 'createdAt', 'updatedAt',
|
||||
]
|
||||
for (const key of expectedColumnKeys) expect(columnSource).toContain(`key: '${key}'`)
|
||||
for (const uncontractedKey of [
|
||||
'internalOrderStatus', 'expectedArrivalAt', 'feeReviewStatus', 'holdCargo', 'companyName',
|
||||
'pickupMethod', 'chargeableVolumeCbm', 'recommendedPalletType', 'locationCodes', 'associatedFiles', 'createdBy',
|
||||
'pickupMethod', 'chargeableVolumeCbm', 'associatedFiles', 'createdBy',
|
||||
]) expect(columnSource).not.toContain(`key: '${uncontractedKey}'`)
|
||||
expect(columnSource).not.toContain("key: 'orderNo'")
|
||||
expect(columnSource.indexOf("key: 'actions'")).toBeLessThan(columnSource.indexOf("key: 'inboundCode'"))
|
||||
expect(columnSource.indexOf("key: 'actions'")).toBeLessThan(columnSource.indexOf("key: 'orderNo'"))
|
||||
expect(columnSource.indexOf("key: 'orderNo'")).toBeLessThan(columnSource.indexOf("key: 'inboundCode'"))
|
||||
expect(columnSource).toContain("{ key: 'mainStatus', prop: 'mainStatus', label: '订单主状态'")
|
||||
expect(columnSource).toContain("{ key: 'loadingStatus', prop: 'loadingStatus', label: '配载状态', minWidth: 130, slotName: 'field', defaultVisible: false }")
|
||||
expect(columnSource.match(/defaultVisible: false/g)).toHaveLength(8)
|
||||
expect(columnSource.match(/defaultVisible: false/g)).toHaveLength(10)
|
||||
expect(source).toContain('.table-card { overflow: hidden; }')
|
||||
expect(source).toContain('slotName: \'measurementReviewStatus\'')
|
||||
expect(source).toContain('unifiedOrderReviewStatusLabel(value, \'未录入\')')
|
||||
@@ -288,6 +288,7 @@ describe('UnifiedOrdersView contract', () => {
|
||||
expect(source).toContain('InboundFeePanel')
|
||||
expect(source).toContain('InboundFeeDetailManager')
|
||||
expect(source).toContain(':customer-id="String(detail.summary.tenantId)"')
|
||||
expect(source).toContain('compact')
|
||||
expect(source).toContain('头程自动初算')
|
||||
expect(source).toContain('其他费用明细')
|
||||
expect(source).toContain('@changed="loadDetail(true)"')
|
||||
|
||||
@@ -103,6 +103,18 @@ const detail = ref<UnifiedOrderDetailResource | null>(null)
|
||||
const detailLoading = ref(false)
|
||||
const detailError = ref<ApiErrorDetails | null>(null)
|
||||
const activeDetailTab = ref('basic')
|
||||
const automaticFee = ref<AutomaticFeeSummary | null>(null)
|
||||
const otherFeeSummary = ref<OtherFeeSummary>({ currency: 'CNY', approvedReceivable: 0, approvedPayable: 0 })
|
||||
const customerFeeTotal = computed(() => (
|
||||
(automaticFee.value?.feeStatus === 'SENT' ? Number(automaticFee.value.totalAmount || 0) : 0)
|
||||
+ otherFeeSummary.value.approvedReceivable
|
||||
))
|
||||
function feeMoney(value: number) {
|
||||
return new Intl.NumberFormat('zh-CN', { style: 'currency', currency: otherFeeSummary.value.currency || 'CNY' }).format(value)
|
||||
}
|
||||
|
||||
type OtherFeeSummary = { currency: string; approvedReceivable: number; approvedPayable: number }
|
||||
type AutomaticFeeSummary = { feeStatus: string; totalAmount: number }
|
||||
const approvalOpen = ref(false)
|
||||
const approvalLoadingId = ref('')
|
||||
const approvalSaving = ref(false)
|
||||
@@ -226,12 +238,16 @@ const columns = computed<DataTableColumn[]>(() => [
|
||||
key: 'selection', type: 'selection', width: 48, fixed: 'left',
|
||||
selectable: (row: UnifiedOrderResource) => canApprove(row) && !batchApprovalSaving.value,
|
||||
} satisfies DataTableColumn] : []),
|
||||
{ key: 'orderNo', prop: 'orderNo', label: '订单号', minWidth: 180, slotName: 'field' },
|
||||
{ key: 'inboundCode', prop: 'inboundCode', label: '入仓码', minWidth: 190, 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' },
|
||||
{ key: 'destinationWarehouseName', prop: 'destinationWarehouseName', label: '目的仓', minWidth: 150, slotName: 'field' },
|
||||
{ key: 'channelName', prop: 'channelName', label: '渠道', minWidth: 140, slotName: 'field' },
|
||||
{ key: 'totalPackageCount', prop: 'totalPackageCount', label: '总箱数', minWidth: 100, slotName: 'field' },
|
||||
{ key: 'recommendedPalletType', prop: 'recommendedPalletType', label: '推荐托盘类型', minWidth: 140, slotName: 'field', defaultVisible: false },
|
||||
{ key: 'locationCodes', prop: 'locationCodes', label: '库位位置', minWidth: 160, slotName: 'field', defaultVisible: false },
|
||||
{ key: 'measurementReviewStatus', prop: 'measurementReviewStatus', label: '测量数据审核状态', minWidth: 170, slotName: 'measurementReviewStatus' },
|
||||
{ key: 'actualGrossWeightKg', prop: 'actualGrossWeightKg', label: '实测毛重(kg)', minWidth: 130, slotName: 'field' },
|
||||
{ key: 'actualVolumeCbm', prop: 'actualVolumeCbm', label: '实测体积(m³)', minWidth: 130, slotName: 'field' },
|
||||
@@ -351,7 +367,6 @@ function displayField(row: UnifiedOrderResource, property: string | undefined) {
|
||||
measurementReviewStatus: 'measurement.reviewStatus', expectedArrivalAt: 'expectedArrivalAt',
|
||||
loadingStatus: 'transport.loadingStatus', containerNo: 'transport.containerNo', cabinetNo: 'transport.cabinetNo',
|
||||
sailingAt: 'transport.sailingAt', portArrivalAt: 'transport.portArrivalAt',
|
||||
actualGrossWeightKg: 'measurement.actualGrossWeightKg', actualVolumeCbm: 'measurement.actualVolumeCbm',
|
||||
chargeableWeightKg: 'measurement.chargeableWeightKg', measurementCompletedAt: 'measurement.completedAt',
|
||||
expressTrackingNo: 'delivery.trackingNo',
|
||||
}
|
||||
@@ -978,16 +993,23 @@ onBeforeUnmount(() => {
|
||||
|
||||
<template v-else-if="activeDetailTab === 'fees'">
|
||||
<div class="panel-title"><div><h2>费用信息</h2><p>头程自动初算与其他人工费用在同一页维护</p></div><WalletCards :size="19" /></div>
|
||||
<dl class="fee-overview" aria-label="费用汇总">
|
||||
<div><dt>对客费用合计</dt><dd>{{ feeMoney(customerFeeTotal) }}</dd><small>已发布头程费用 + 已审核其他应收</small></div>
|
||||
<div><dt>已审核其他应付</dt><dd>{{ feeMoney(otherFeeSummary.approvedPayable) }}</dd><small>单列展示,不计入对客费用</small></div>
|
||||
</dl>
|
||||
<h3 class="fee-section-title">头程自动初算</h3>
|
||||
<InboundFeePanel
|
||||
:customer-id="String(detail.summary.tenantId)"
|
||||
:inbound-id="String(detail.summary.inboundId)"
|
||||
compact
|
||||
@loaded="automaticFee = $event"
|
||||
@changed="loadDetail(true)"
|
||||
/>
|
||||
<h3 class="fee-section-title fee-section-title--secondary">其他费用明细</h3>
|
||||
<InboundFeeDetailManager
|
||||
:account-id="String(detail.summary.tenantId)"
|
||||
:inbound-id="String(detail.summary.inboundId)"
|
||||
@summary="otherFeeSummary = $event"
|
||||
@changed="loadDetail(true)"
|
||||
/>
|
||||
</template>
|
||||
@@ -1295,6 +1317,12 @@ onBeforeUnmount(() => {
|
||||
.panel-title p { margin: 5px 0 0; color: var(--cc-muted); font-size: 11px; }
|
||||
.panel-title > svg { color: var(--cc-primary); }
|
||||
.fee-section-title { margin: 14px 0 8px; color: #344054; font-size: 13px; line-height: 1.4; }
|
||||
.fee-overview { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 8px 0 0; border: 1px solid var(--cc-border); }
|
||||
.fee-overview > div { display: grid; grid-template-columns: auto 1fr; align-items: baseline; gap: 4px 12px; padding: 10px 12px; }
|
||||
.fee-overview > div + div { border-left: 1px solid var(--cc-border); }
|
||||
.fee-overview dt, .fee-overview small { color: var(--cc-muted); font-size: 11px; }
|
||||
.fee-overview dd { margin: 0; font-size: 18px; font-weight: 700; text-align: right; }
|
||||
.fee-overview small { grid-column: 1 / -1; }
|
||||
.fee-section-title--secondary { margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--cc-border); }
|
||||
.order-info-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0; margin: 0; overflow: hidden; border: 1px solid #edf0f4; background: #fff; }
|
||||
.order-info-grid > div, .measurement-grid > div { display: flex; min-width: 0; min-height: 38px; align-items: baseline; gap: 8px; padding: 8px 12px; border-right: 1px solid #edf0f4; border-bottom: 1px solid #edf0f4; background: #fff; }
|
||||
@@ -1346,5 +1374,6 @@ onBeforeUnmount(() => {
|
||||
@media (max-width: 960px) { .detail-overview { grid-template-columns: repeat(2, minmax(0, 1fr)); } .detail-overview article:nth-child(2) { border-right: 0; } .detail-overview article:nth-child(-n+2) { border-bottom: 1px solid var(--cc-border); } .order-info-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .measurement-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
|
||||
@media (max-width: 720px) { .page-intro { align-items: stretch; flex-direction: column; } .page-intro :deep(.el-button) { width: 100%; min-height: 44px; } .status-tab { min-height: 46px; padding: 0 14px; } .table-actions :deep(.el-button) { width: 100%; min-height: 40px; } .row-actions { flex-wrap: wrap; } .order-detail-header { align-items: stretch; flex-direction: column; } .order-detail-heading { display: grid; grid-template-columns: auto 36px minmax(0, 1fr) auto; } .detail-header-actions { display: grid; grid-template-columns: 1fr; } .detail-header-actions :deep(.el-button) { min-height: 40px; } .detail-overview, .order-info-grid, .measurement-grid { grid-template-columns: 1fr; } .detail-overview article { border-right: 0; border-bottom: 1px solid var(--cc-border); } .detail-overview article:last-child { border-bottom: 0; } .order-info-grid > div.wide { grid-column: auto; } .detail-tabs button { padding: 0 18px; } .detail-panel { padding: 16px; } .measurement-section-title { align-items: flex-start; flex-wrap: wrap; padding: 12px; } .measurement-section-summary { width: 100%; flex-basis: calc(100% - 34px); flex-wrap: wrap; justify-content: flex-start; gap: 6px 16px; white-space: normal; } .measurement-section-title > svg { margin-left: auto; } .measurement-total { flex-wrap: wrap; justify-content: flex-start; gap: 6px 16px; } .measurement-total strong { width: 100%; } }
|
||||
@media (max-width: 720px) { .weight-evidence__heading { flex-direction: column; } .weight-evidence__heading dl { text-align: left; } }
|
||||
@media (max-width: 720px) { .fee-overview { grid-template-columns: 1fr; } .fee-overview > div + div { border-top: 1px solid var(--cc-border); border-left: 0; } }
|
||||
@media (max-width: 420px) { .order-detail-heading { grid-template-columns: auto minmax(0, 1fr) auto; } .order-mark { display: none; } .weight-evidence { padding: 10px; } .weight-evidence-grid { grid-template-columns: 1fr; } }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user