修复采购审核竞态并整理管理页面展示
This commit is contained in:
@@ -19,6 +19,7 @@ vi.mock('../weight/components/WeightOcrPanel.vue', () => ({
|
||||
name: 'WeightOcrPanel',
|
||||
props: { customerId: String, inboundId: String, reviewMode: Boolean, correctionMode: Boolean, tableMode: Boolean },
|
||||
emits: ['changed'],
|
||||
methods: { reload: async () => {} },
|
||||
template: '<button class="mock-weight-change" @click="$emit(\'changed\')">重量证据</button>',
|
||||
},
|
||||
}))
|
||||
@@ -42,6 +43,14 @@ const detail: MeasurementReviewDetail = {
|
||||
weightResults: [],
|
||||
}
|
||||
|
||||
const measuredItem: MeasurementReviewDetail['items'][number] = {
|
||||
id: 'item-raw', boxCode: 'BOX-RAW-001', itemNo: '1', boxSpecification: null, packageCount: 22,
|
||||
lengthCm: 62, widthCm: 52, heightCm: 52, girthCm: 270, unitWeightKg: 25.9318,
|
||||
unitVolumeCbm: 0.3275, totalWeightKg: 570.5, totalVolumeCbm: 7.205, volumeWeightKg: 1203.235,
|
||||
intelligentImageFileId: null, machineNo: null, deviceMeasuredAt: null, overLimitWarning: null,
|
||||
outerLengthCm: 75, outerWidthCm: 66, outerHeightCm: 66, remark: null,
|
||||
}
|
||||
|
||||
enableAutoUnmount(afterEach)
|
||||
|
||||
describe('MeasurementReviewPanel', () => {
|
||||
@@ -98,18 +107,23 @@ describe('MeasurementReviewPanel', () => {
|
||||
expect(source).not.toContain('listMeasurementReviewHistory')
|
||||
})
|
||||
|
||||
it.each([true, false])('describes dropship palletizing and uses the server result when pricing succeeds=%s', async (initialPricingSucceeded) => {
|
||||
vi.mocked(approveMeasurement).mockResolvedValue({ inboundId: '90001', measurementId: '70001', processStatus: 'WAIT_PALLETIZE', feeStatus: initialPricingSucceeded ? 'CALCULATED' : 'UNPRICED', initialPricingSucceeded, initialPricingMessage: null, initialFee: null })
|
||||
it.each([
|
||||
{ fulfillmentType: 'ONE_CLICK_DROPSHIP', processStatus: 'WAIT_PALLETIZE', targetLabel: '待一件代发组托', initialPricingSucceeded: true },
|
||||
{ fulfillmentType: 'ONE_CLICK_DROPSHIP', processStatus: 'WAIT_PALLETIZE', targetLabel: '待一件代发组托', initialPricingSucceeded: false },
|
||||
{ fulfillmentType: 'FBA', processStatus: 'WAIT_SPLIT', targetLabel: '待分柜', initialPricingSucceeded: true },
|
||||
{ fulfillmentType: 'FBA', processStatus: 'WAIT_SPLIT', targetLabel: '待分柜', initialPricingSucceeded: false },
|
||||
])('describes $fulfillmentType approval target and uses the server result when pricing succeeds=$initialPricingSucceeded', async ({ fulfillmentType, processStatus, targetLabel, initialPricingSucceeded }) => {
|
||||
vi.mocked(approveMeasurement).mockResolvedValue({ inboundId: '90001', measurementId: '70001', processStatus, feeStatus: initialPricingSucceeded ? 'CALCULATED' : 'UNPRICED', initialPricingSucceeded, initialPricingMessage: null, initialFee: null })
|
||||
const confirmation = vi.spyOn(ElMessageBox, 'confirm').mockResolvedValue(undefined as never)
|
||||
const success = vi.spyOn(ElMessage, 'success')
|
||||
const warning = vi.spyOn(ElMessage, 'warning')
|
||||
const wrapper = mount(MeasurementReviewPanel, { props: { customerId: '10001', inboundId: '90001', fulfillmentType: 'ONE_CLICK_DROPSHIP' }, global: { plugins: [ElementPlus] } })
|
||||
const wrapper = mount(MeasurementReviewPanel, { props: { customerId: '10001', inboundId: '90001', fulfillmentType }, global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
expect(wrapper.text()).not.toContain('通过并进入')
|
||||
await wrapper.findAll('button').find((button) => button.text() === '通过')!.trigger('click')
|
||||
await flushPromises()
|
||||
expect(confirmation).toHaveBeenCalledWith('审核通过后,入库单将进入待分柜', '确认测量', expect.objectContaining({ confirmButtonText: '通过' }))
|
||||
expect(initialPricingSucceeded ? success : warning).toHaveBeenCalledWith(expect.stringContaining('入库单已进入待一件代发组托'))
|
||||
expect(confirmation).toHaveBeenCalledWith(`审核通过后,入库单将进入${targetLabel}`, '确认测量', expect.objectContaining({ confirmButtonText: '通过' }))
|
||||
expect(initialPricingSucceeded ? success : warning).toHaveBeenCalledWith(expect.stringContaining(`入库单已进入${targetLabel}`))
|
||||
expect(approveMeasurement).toHaveBeenCalledTimes(1)
|
||||
expect(wrapper.emitted('changed')).toHaveLength(1)
|
||||
})
|
||||
@@ -125,7 +139,7 @@ describe('MeasurementReviewPanel', () => {
|
||||
expect(wrapper.get('.review-toolbar__context').text()).toBe('客户:欧阳的公司 · 渠道:海运')
|
||||
})
|
||||
|
||||
it('shows declared facts, authoritative measurement totals, and box-detail evidence for manual review', async () => {
|
||||
it('shows declared facts, raw measured volume, weight totals and box-detail evidence for manual review', async () => {
|
||||
vi.mocked(getMeasurementReviewDetail).mockResolvedValue({
|
||||
...detail,
|
||||
originalPackageCount: 9,
|
||||
@@ -153,19 +167,19 @@ describe('MeasurementReviewPanel', () => {
|
||||
expect(comparisonRows.map(row => row.findAll('th, td').map(cell => cell.text()))).toEqual([
|
||||
['箱数', '9', '10', '差异 +1'],
|
||||
['毛重(kg)', '118', '120', '差异 +2 kg'],
|
||||
['体积(m³)', '2', '2.2', '差异 +0.2 m³'],
|
||||
['体积(m³)', '2', '0.72', '差异 -1.28 m³'],
|
||||
])
|
||||
expect(wrapper.get('.review-comparison').text()).not.toContain('实际品名')
|
||||
expect(wrapper.get('.review-comparison').text()).not.toContain('原单据号码')
|
||||
const extraFacts = wrapper.get('.review-extra-facts').text().replace(/\s/g, '')
|
||||
expect(extraFacts).toContain('货物净重110kg')
|
||||
expect(extraFacts).toContain('体积重367.4kg')
|
||||
expect(extraFacts).toContain('计费体积重367.4kg')
|
||||
|
||||
const items = wrapper.get('.review-items').text()
|
||||
expect(items).toContain('箱规测量明细')
|
||||
expect(items).toContain('BOX-001')
|
||||
expect(items).toContain('60 × 40 × 30')
|
||||
expect(items).toContain('120.2')
|
||||
expect(items).not.toContain('120.2')
|
||||
expect(items).toContain('2026-08-18 10:30:00')
|
||||
expect(items).not.toContain('每箱毛重(kg)')
|
||||
expect(items).not.toContain('总重量(kg)')
|
||||
@@ -182,6 +196,103 @@ describe('MeasurementReviewPanel', () => {
|
||||
expect(source).toContain('.review-table :deep(.review-time-cell .cell) { white-space: nowrap; }')
|
||||
})
|
||||
|
||||
it('uses original measured dimensions for unit volume, row volume and summary without replacing billing snapshots', async () => {
|
||||
const value = { ...detail, originalVolumeCbm: 3.3, actualVolumeCbm: 7.205, items: [{ ...measuredItem }] }
|
||||
vi.mocked(getMeasurementReviewDetail).mockResolvedValue(value)
|
||||
const wrapper = mount(MeasurementReviewPanel, { props: { customerId: '10001', inboundId: '90001' }, global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
const volumeRow = wrapper.get('.review-comparison tbody tr:last-child')
|
||||
expect(volumeRow.findAll('td').map(cell => cell.text())).toEqual(['3.3', '3.688', '差异 +0.388 m³'])
|
||||
const cells = wrapper.get('.review-items .el-table__body tbody tr').findAll('td')
|
||||
expect(cells.slice(5, 7).map(cell => cell.text())).toEqual(['0.168', '3.688'])
|
||||
expect(wrapper.get('.review-items').text()).not.toContain('1,203.235')
|
||||
expect(value.actualVolumeCbm).toBe(7.205)
|
||||
expect(value.items[0]).toMatchObject({ unitVolumeCbm: 0.3275, totalVolumeCbm: 7.205, outerLengthCm: 75 })
|
||||
})
|
||||
|
||||
it('sums all unrounded measured row volumes before formatting the review comparison', async () => {
|
||||
vi.mocked(getMeasurementReviewDetail).mockResolvedValue({ ...detail, originalVolumeCbm: 3.3, actualVolumeCbm: 9.999,
|
||||
items: [{ ...measuredItem }, { ...measuredItem, id: 'item-2', boxCode: 'BOX-RAW-002', lengthCm: 50, widthCm: 40, heightCm: 30, packageCount: 2 }] })
|
||||
const wrapper = mount(MeasurementReviewPanel, { props: { customerId: '10001', inboundId: '90001' }, global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
expect(wrapper.get('.review-comparison tbody tr:last-child').findAll('td').map(cell => cell.text())).toEqual(['3.3', '3.808', '差异 +0.508 m³'])
|
||||
})
|
||||
|
||||
it('separates warehouse overrides and their saved volume from original measured data', async () => {
|
||||
const corrected = { ...measuredItem, outerLengthCm: 63, outerWidthCm: 53, outerHeightCm: 53,
|
||||
unitVolumeCbm: 0.177, totalVolumeCbm: 3.894, volumeWeightKg: 650.298 }
|
||||
const unmodified = { ...measuredItem, id: 'item-unmodified', boxCode: 'BOX-RAW-002',
|
||||
lengthCm: 10, widthCm: 20, heightCm: 30, packageCount: 2,
|
||||
outerLengthCm: null, outerWidthCm: null, outerHeightCm: null,
|
||||
unitVolumeCbm: 0.006, totalVolumeCbm: 0.012, volumeWeightKg: 2.004 }
|
||||
const value = { ...detail, originalVolumeCbm: 3.3, actualPackageCount: 24,
|
||||
actualVolumeCbm: 3.906, items: [corrected, unmodified] }
|
||||
vi.mocked(getMeasurementReviewDetail).mockResolvedValue(value)
|
||||
const wrapper = mount(MeasurementReviewPanel, { props: { customerId: '10001', inboundId: '90001' }, global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
|
||||
expect(wrapper.get('.review-comparison tbody tr:last-child').findAll('td').map(cell => cell.text())).toEqual(['3.3', '3.7', '差异 +0.4 m³'])
|
||||
const measuredCells = wrapper.get('.review-items .el-table__body tbody tr').findAll('td')
|
||||
expect(measuredCells[3]!.text()).toBe('62 × 52 × 52')
|
||||
expect(measuredCells.slice(5, 7).map(cell => cell.text())).toEqual(['0.168', '3.688'])
|
||||
const outer = wrapper.get('.review-outer-items')
|
||||
expect(outer.get('h3').text()).toBe('仓库修改外箱')
|
||||
expect(outer.findAll('.el-table__body tbody tr')).toHaveLength(1)
|
||||
expect(outer.get('.el-table__body tbody tr').findAll('td').map(cell => cell.text())).toEqual([
|
||||
'1', 'BOX-RAW-001', '63', '53', '53', '22', '0.177', '3.894', '650.298',
|
||||
])
|
||||
expect(outer.get('.el-table__footer').findAll('td').map(cell => cell.text())).toEqual([
|
||||
'合计', '', '', '', '', '22', '—', '3.894', '650.298',
|
||||
])
|
||||
expect(value.items[0]).toBe(corrected)
|
||||
expect(corrected).toMatchObject({ lengthCm: 62, unitVolumeCbm: 0.177, totalVolumeCbm: 3.894 })
|
||||
})
|
||||
|
||||
it('hides the warehouse outer section when no manual dimension was entered', async () => {
|
||||
vi.mocked(getMeasurementReviewDetail).mockResolvedValue({ ...detail, items: [{ ...measuredItem,
|
||||
outerLengthCm: null, outerWidthCm: null, outerHeightCm: null }] })
|
||||
const wrapper = mount(MeasurementReviewPanel, { props: { customerId: '10001', inboundId: '90001' }, global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
expect(wrapper.find('.review-outer-items').exists()).toBe(false)
|
||||
expect(wrapper.get('.review-items').text()).toContain('3.688')
|
||||
})
|
||||
|
||||
it('keeps partial outer edits and missing saved volumes explicit, then removes the section after clearing', async () => {
|
||||
const item = { ...measuredItem, outerLengthCm: 63, outerWidthCm: null, outerHeightCm: null,
|
||||
unitVolumeCbm: null, totalVolumeCbm: null, volumeWeightKg: null }
|
||||
vi.mocked(getMeasurementReviewDetail).mockResolvedValue({ ...detail, items: [item] })
|
||||
const wrapper = mount(MeasurementReviewPanel, { props: { customerId: '10001', inboundId: '90001' }, global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
const outer = wrapper.get('.review-outer-items')
|
||||
expect(outer.get('.el-table__body tbody tr').findAll('td').slice(2).map(cell => cell.text())).toEqual([
|
||||
'63', '—', '—', '22', '—', '—', '—',
|
||||
])
|
||||
expect(outer.get('.el-table__footer').findAll('td').slice(7).map(cell => cell.text())).toEqual(['—', '—'])
|
||||
vi.mocked(getMeasurementReviewDetail).mockResolvedValue({ ...detail, version: 5, items: [{ ...item, outerLengthCm: null }] })
|
||||
await wrapper.get('.review-refresh').trigger('click')
|
||||
await flushPromises()
|
||||
expect(wrapper.find('.review-outer-items').exists()).toBe(false)
|
||||
expect(wrapper.get('.review-items').text()).toContain('3.688')
|
||||
})
|
||||
|
||||
it('totals only the saved correction rows before formatting', async () => {
|
||||
vi.mocked(getMeasurementReviewDetail).mockResolvedValue({ ...detail, items: [
|
||||
{ ...measuredItem, totalVolumeCbm: 1.2344 },
|
||||
{ ...measuredItem, id: 'item-2', boxCode: 'BOX-RAW-002', totalVolumeCbm: 1.2344 },
|
||||
] })
|
||||
const wrapper = mount(MeasurementReviewPanel, { props: { customerId: '10001', inboundId: '90001' }, global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
expect(wrapper.get('.review-outer-items .el-table__footer').findAll('td')[7]!.text()).toBe('2.469')
|
||||
})
|
||||
|
||||
it.each([{ lengthCm: null }, { widthCm: 0 }, { heightCm: Number.NaN }, { packageCount: null }, { packageCount: 1.5 }])('keeps incomplete or invalid measured volume unknown instead of using billing totals: %o', async (invalid) => {
|
||||
vi.mocked(getMeasurementReviewDetail).mockResolvedValue({ ...detail, items: [{ ...measuredItem }, { ...measuredItem, ...invalid, id: 'item-invalid' }] })
|
||||
const wrapper = mount(MeasurementReviewPanel, { props: { customerId: '10001', inboundId: '90001' }, global: { plugins: [ElementPlus] } })
|
||||
await flushPromises()
|
||||
expect(wrapper.get('.review-comparison tbody tr:last-child').findAll('td').map(cell => cell.text())).toEqual(['2', '—', '—'])
|
||||
expect(wrapper.findAll('.review-items .el-table__body tbody tr')[1]!.findAll('td')[6]!.text()).toBe('—')
|
||||
})
|
||||
|
||||
it('keeps difference labels absent when declared values are unavailable', async () => {
|
||||
vi.mocked(getMeasurementReviewDetail).mockResolvedValue({ ...detail, originalGrossWeightKg: null, originalVolumeCbm: null })
|
||||
const wrapper = mount(MeasurementReviewPanel, { props: { customerId: '10001', inboundId: '90001' }, global: { plugins: [ElementPlus] } })
|
||||
@@ -190,7 +301,7 @@ describe('MeasurementReviewPanel', () => {
|
||||
const rows = wrapper.findAll('.review-comparison tbody tr')
|
||||
expect(rows[0].findAll('td').at(-1)?.text()).toBe('一致')
|
||||
expect(rows[1].findAll('td').map(cell => cell.text())).toEqual(['—', '120', '—'])
|
||||
expect(rows[2].findAll('td').map(cell => cell.text())).toEqual(['—', '2.2', '—'])
|
||||
expect(rows[2].findAll('td').map(cell => cell.text())).toEqual(['—', '—', '—'])
|
||||
})
|
||||
|
||||
it('reuses WeightOcrPanel and enables only its review correction mode', async () => {
|
||||
|
||||
@@ -15,7 +15,7 @@ import { inboundProcessStatusLabels, inboundReviewStatusLabels, inboundStatusLab
|
||||
import WeightOcrPanel from '../weight/components/WeightOcrPanel.vue'
|
||||
import type { WeightResultResource } from '../weight/types'
|
||||
import { approveMeasurement, getMeasurementReviewDetail } from './api'
|
||||
import type { MeasurementReviewDetail } from './types'
|
||||
import type { MeasurementReviewDetail, MeasurementReviewItem } from './types'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
customerId?: string
|
||||
@@ -60,6 +60,52 @@ const displayChannelName = computed(() => detail.value?.channelName?.trim() || d
|
||||
const measurementCount = computed(() => detail.value?.items.length || 0)
|
||||
const weightCount = computed(() => detail.value?.weightResults.length || 0)
|
||||
|
||||
// 实测展示只采用原始尺寸与确认箱数,规则计算后的体积仍留在服务端计费快照中。
|
||||
function measuredUnitVolumeCbm(item: MeasurementReviewItem) {
|
||||
const { lengthCm, widthCm, heightCm } = item
|
||||
if (lengthCm == null || widthCm == null || heightCm == null
|
||||
|| ![lengthCm, widthCm, heightCm].every(value => Number.isFinite(value) && value > 0)) return null
|
||||
const volume = lengthCm * widthCm * heightCm / 1_000_000
|
||||
return Number.isFinite(volume) ? volume : null
|
||||
}
|
||||
|
||||
function measuredVolumeCbm(item: MeasurementReviewItem) {
|
||||
const unitVolume = measuredUnitVolumeCbm(item)
|
||||
if (unitVolume == null || item.packageCount == null || !Number.isInteger(item.packageCount) || item.packageCount < 1) return null
|
||||
const volume = unitVolume * item.packageCount
|
||||
return Number.isFinite(volume) ? volume : null
|
||||
}
|
||||
|
||||
const measuredTotalVolumeCbm = computed(() => {
|
||||
if (!detail.value?.items.length) return null
|
||||
let total = 0
|
||||
for (const item of detail.value.items) {
|
||||
const volume = measuredVolumeCbm(item)
|
||||
if (volume == null) return null
|
||||
total += volume
|
||||
}
|
||||
return Number.isFinite(total) ? total : null
|
||||
})
|
||||
|
||||
const warehouseOuterItems = computed(() => (detail.value?.items || []).filter(item =>
|
||||
item.outerLengthCm != null || item.outerWidthCm != null || item.outerHeightCm != null))
|
||||
|
||||
function warehouseOuterTotal(key: 'packageCount' | 'totalVolumeCbm' | 'volumeWeightKg') {
|
||||
if (!warehouseOuterItems.value.length) return null
|
||||
let total = 0
|
||||
for (const item of warehouseOuterItems.value) {
|
||||
const value = item[key]
|
||||
if (value == null || !Number.isFinite(value) || value < 0) return null
|
||||
total += value
|
||||
}
|
||||
return Number.isFinite(total) ? total : null
|
||||
}
|
||||
|
||||
function warehouseOuterSummary() {
|
||||
return ['合计', '', '', '', '', formatNumber(warehouseOuterTotal('packageCount'), 0), '—',
|
||||
formatNumber(warehouseOuterTotal('totalVolumeCbm')), formatNumber(warehouseOuterTotal('volumeWeightKg'))]
|
||||
}
|
||||
|
||||
function formatNumber(value: number | null | undefined, maximumFractionDigits = 3) {
|
||||
if (value === null || value === undefined || !Number.isFinite(value)) return '—'
|
||||
return new Intl.NumberFormat('zh-CN', { maximumFractionDigits, minimumFractionDigits: 0 }).format(value)
|
||||
@@ -142,7 +188,7 @@ async function confirmApprove() {
|
||||
if (!detail.value || !isPending.value || !canReview.value || actionLoading.value || props.postApproveLoading || props.approvalCompleted) return
|
||||
try {
|
||||
await ElMessageBox.confirm(
|
||||
'审核通过后,入库单将进入待分柜',
|
||||
`审核通过后,入库单将进入${approvalTargetLabel.value}`,
|
||||
'确认测量',
|
||||
{ customClass: 'admin-density-confirm', confirmButtonText: approvalButtonLabel.value, cancelButtonText: '返回', type: 'warning' },
|
||||
)
|
||||
@@ -213,10 +259,10 @@ defineExpose({ confirmApprove, approvalButtonLabel, isPending, canReview, action
|
||||
<tbody>
|
||||
<tr><th scope="row">箱数</th><td>{{ formatNumber(detail.originalPackageCount, 0) }}</td><td>{{ formatNumber(detail.actualPackageCount, 0) }}</td><td>{{ formatDifference(detail.actualPackageCount, detail.originalPackageCount, 0) }}</td></tr>
|
||||
<tr><th scope="row">毛重(kg)</th><td>{{ formatNumber(detail.originalGrossWeightKg) }}</td><td>{{ formatNumber(detail.actualGrossWeightKg) }}</td><td>{{ formatDifference(detail.actualGrossWeightKg, detail.originalGrossWeightKg, 3, ' kg') }}</td></tr>
|
||||
<tr><th scope="row">体积(m³)</th><td>{{ formatNumber(detail.originalVolumeCbm, 3) }}</td><td>{{ formatNumber(detail.actualVolumeCbm, 3) }}</td><td>{{ formatDifference(detail.actualVolumeCbm, detail.originalVolumeCbm, 3, ' m³') }}</td></tr>
|
||||
<tr><th scope="row">体积(m³)</th><td>{{ formatNumber(detail.originalVolumeCbm, 3) }}</td><td>{{ formatNumber(measuredTotalVolumeCbm, 3) }}</td><td>{{ formatDifference(measuredTotalVolumeCbm, detail.originalVolumeCbm, 3, ' m³') }}</td></tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
<div class="review-extra-facts"><span>货物净重 <strong>{{ formatNumber(detail.actualNetWeightKg) }}</strong> kg</span><span>体积重 <strong>{{ formatNumber(detail.volumeWeightKg) }}</strong> kg</span></div>
|
||||
<div class="review-extra-facts"><span>货物净重 <strong>{{ formatNumber(detail.actualNetWeightKg) }}</strong> kg</span><span>计费体积重 <strong>{{ formatNumber(detail.volumeWeightKg) }}</strong> kg</span></div>
|
||||
</section>
|
||||
|
||||
<section class="review-items density-dialog-section" data-tone="source" aria-labelledby="review-items-title">
|
||||
@@ -249,13 +295,10 @@ defineExpose({ confirmApprove, approvalButtonLabel, isPending, canReview, action
|
||||
<template #default="{ row }">{{ formatNumber(row.packageCount, 0) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单箱体积(m³)" width="106" align="right">
|
||||
<template #default="{ row }">{{ formatNumber(row.unitVolumeCbm, 3) }}</template>
|
||||
<template #default="{ row }">{{ formatNumber(measuredUnitVolumeCbm(row as MeasurementReviewItem), 3) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总体积(m³)" width="96" align="right">
|
||||
<template #default="{ row }">{{ formatNumber(row.totalVolumeCbm, 3) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="体积重(kg)" width="96" align="right">
|
||||
<template #default="{ row }">{{ formatNumber(row.volumeWeightKg) }}</template>
|
||||
<template #default="{ row }">{{ formatNumber(measuredVolumeCbm(row as MeasurementReviewItem), 3) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="测量时间" width="220" class-name="review-time-cell">
|
||||
<template #default="{ row }">{{ formatDate(row.deviceMeasuredAt) }}</template>
|
||||
@@ -265,6 +308,42 @@ defineExpose({ confirmApprove, approvalButtonLabel, isPending, canReview, action
|
||||
<el-empty v-else description="暂无箱规测量明细" :image-size="48" />
|
||||
</section>
|
||||
|
||||
<section v-if="warehouseOuterItems.length" class="review-items review-outer-items density-dialog-section" aria-labelledby="review-outer-title">
|
||||
<header class="review-section-heading density-dialog-section__title">
|
||||
<h3 id="review-outer-title" class="review-detail-heading"><Ruler :size="18" aria-hidden="true" />仓库修改外箱</h3>
|
||||
<span>{{ warehouseOuterItems.length }} 条</span>
|
||||
</header>
|
||||
<div class="review-table-scroll">
|
||||
<el-table :data="warehouseOuterItems" border stripe table-layout="fixed" class="review-table" show-summary :summary-method="warehouseOuterSummary">
|
||||
<el-table-column type="index" label="#" width="54" align="center" />
|
||||
<el-table-column label="箱号" min-width="160" show-overflow-tooltip>
|
||||
<template #default="{ row }">{{ row.boxCode || row.itemNo || '—' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="仓库修改外箱(长)cm" min-width="150" align="right">
|
||||
<template #default="{ row }">{{ formatNumber(row.outerLengthCm) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="仓库修改外箱(宽)cm" min-width="150" align="right">
|
||||
<template #default="{ row }">{{ formatNumber(row.outerWidthCm) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="仓库修改外箱(高)cm" min-width="150" align="right">
|
||||
<template #default="{ row }">{{ formatNumber(row.outerHeightCm) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="箱数" width="66" align="right">
|
||||
<template #default="{ row }">{{ formatNumber(row.packageCount, 0) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计算后单箱体积(m³)" min-width="138" align="right">
|
||||
<template #default="{ row }">{{ formatNumber(row.unitVolumeCbm, 3) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计算后总体积(m³)" min-width="138" align="right">
|
||||
<template #default="{ row }">{{ formatNumber(row.totalVolumeCbm, 3) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计费体积重(kg)" min-width="120" align="right">
|
||||
<template #default="{ row }">{{ formatNumber(row.volumeWeightKg) }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="review-items review-weight-items density-dialog-section" data-tone="source" aria-labelledby="review-weight-title">
|
||||
<header class="review-section-heading density-dialog-section__title">
|
||||
<h3 id="review-weight-title" class="review-detail-heading"><Scale :size="18" aria-hidden="true" />称重明细</h3>
|
||||
|
||||
Reference in New Issue
Block a user