This commit is contained in:
2026-08-18 16:09:43 +08:00
parent f9ae2d94cb
commit 21249d1dde
52 changed files with 980 additions and 698 deletions
@@ -23,6 +23,15 @@ vi.mock('../weight/components/WeightOcrPanel.vue', () => ({
},
}))
vi.mock('../measurement/components/MeasurementEvidenceThumbnail.vue', () => ({
default: {
name: 'MeasurementEvidenceThumbnail',
props: { customerId: String, inboundId: String, fileId: String, alt: String, emptyText: String },
emits: ['open'],
template: '<button class="mock-measurement-image" @click="$emit(\'open\')">测量图片</button>',
},
}))
const detail: MeasurementReviewDetail = {
inboundId: '90001', inboundCode: 'RK90001', companyName: '柏悦客户', channelCode: 'SEA', channelName: '海运',
processStatus: 'MEASURE_PENDING', measureReviewStatus: 'PENDING', recommendedPalletType: 'STANDARD', reviewReason: null, reviewerId: null, reviewerName: null,
@@ -71,6 +80,8 @@ describe('MeasurementReviewPanel', () => {
expect(wrapper.text()).not.toContain('入仓码')
expect(wrapper.text()).not.toContain('驳回')
expect(wrapper.text()).not.toContain('异常放行')
expect(wrapper.text()).not.toContain('审核历史')
expect(listMeasurementReviewHistory).not.toHaveBeenCalled()
const source = await import('./MeasurementReviewPanel.vue?raw').then((module) => module.default)
expect(source).not.toContain('position: sticky')
expect(source).toContain('review-toolbar__context')
@@ -78,6 +89,7 @@ describe('MeasurementReviewPanel', () => {
expect(source).not.toContain('reasonDialog')
expect(source).not.toContain('saveInboundMeasurementDraft')
expect(source).not.toContain('submitInboundMeasurement')
expect(source).not.toContain('listMeasurementReviewHistory')
})
it('uses the list customer context when the review detail has no customer name', async () => {
@@ -91,6 +103,73 @@ 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 () => {
vi.mocked(getMeasurementReviewDetail).mockResolvedValue({
...detail,
originalPackageCount: 9,
originalGrossWeightKg: 118,
originalVolumeCbm: 2,
actualPackageCount: 10,
actualGrossWeightKg: 120,
actualNetWeightKg: 110,
actualVolumeCbm: 2.2,
volumeWeightKg: 367.4,
items: [{
id: 'item-1', boxCode: 'BOX-001', itemNo: '1', boxSpecification: null, packageCount: 10,
lengthCm: 60, widthCm: 40, heightCm: 30, girthCm: 200, unitWeightKg: 12,
unitVolumeCbm: 0.072, totalWeightKg: 120, totalVolumeCbm: 0.72, volumeWeightKg: 120.2,
intelligentImageFileId: '88001', machineNo: 'DEVICE-01', deviceMeasuredAt: '2026-08-18T10:30:00',
overLimitWarning: null, outerLengthCm: null, outerWidthCm: null, outerHeightCm: null, remark: null,
}],
})
const wrapper = mount(MeasurementReviewPanel, { props: { customerId: '10001', inboundId: '90001' }, global: { plugins: [ElementPlus] } })
await flushPromises()
const summary = wrapper.get('.review-data').text()
expect(summary).toContain('审核数据总览')
const comparisonRows = wrapper.findAll('.review-comparison__row')
expect(comparisonRows).toHaveLength(2)
expect(comparisonRows[0].text()).toContain('客户申报')
expect(comparisonRows[0].text()).toContain('箱数9')
expect(comparisonRows[0].text()).toContain('毛重118 kg')
expect(comparisonRows[0].text()).not.toContain('实际品名')
expect(comparisonRows[0].text()).not.toContain('原单据号码')
expect(comparisonRows[1].text()).toContain('平台实测')
expect(comparisonRows[1].text()).toContain('箱数10 差异 +1')
expect(comparisonRows[1].text()).toContain('毛重120 kg · 差异 +2 kg')
expect(comparisonRows[1].text()).toContain('货物净重110 kg')
expect(comparisonRows[1].text()).toContain('体积2.2 m³ · 差异 +0.2 m³')
expect(comparisonRows[1].text()).toContain('体积重367.4 kg')
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).toContain('2026-08-18 10:30:00')
expect(items).not.toContain('每箱毛重(kg)')
expect(items).not.toContain('总重量(kg)')
const image = wrapper.getComponent({ name: 'MeasurementEvidenceThumbnail' })
expect(image.props('customerId')).toBe('10001')
expect(image.props('inboundId')).toBe('90001')
expect(image.props('fileId')).toBe('88001')
const source = await import('./MeasurementReviewPanel.vue?raw').then((module) => module.default)
expect(source).toContain(':file-id="row.intelligentImageFileId"')
expect(source).toContain('openImagePreview(row.intelligentImageFileId')
expect(source).toContain('downloadInboundMeasurementImage')
expect(source).toContain('.review-table :deep(.el-table__header .cell) { white-space: nowrap; }')
expect(source).toContain('.review-table :deep(.review-time-cell .cell) { white-space: nowrap; }')
})
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] } })
await flushPromises()
expect(wrapper.get('.review-comparison').text()).not.toContain('差异')
})
it('reuses WeightOcrPanel and enables only its review correction mode', async () => {
const wrapper = mount(MeasurementReviewPanel, { props: { customerId: '10001', inboundId: '90001' }, global: { plugins: [ElementPlus] } })
await flushPromises()