统一后台状态列顺序、详情布局与测量计费展示

This commit is contained in:
2026-10-28 10:32:33 +08:00
parent 8e97fd6a9f
commit e41e9e6d3f
120 changed files with 436 additions and 238 deletions
@@ -1,8 +1,9 @@
import { flushPromises, shallowMount } from '@vue/test-utils'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { ApiResponseError } from '@/shared/api/http'
import { getLoadingAssociationSummary, getOverseasInboundCodeRelationship } from '@/shared/api/inboundCodeRelations'
import { downloadPlatformProductImage, getPlatformUnifiedOrder, listPlatformUnifiedOrders } from '@/modules/unified-orders/api/unifiedOrders'
import { downloadPlatformInboundHoldEvidence, getPlatformInboundHold, holdPlatformInbound, releasePlatformInbound, uploadPlatformInboundHoldEvidence } from '@/modules/inbounds'
import { calculateInboundFee, confirmInboundFee, downloadPlatformInboundHoldEvidence, getLatestInboundFee, getPlatformInboundHold, holdPlatformInbound, releasePlatformInbound, sendInboundFee, uploadPlatformInboundHoldEvidence } from '@/modules/inbounds'
import UnifiedOrdersView from './UnifiedOrdersView.vue'
const { routeQuery, routerPush } = vi.hoisted(() => ({ routeQuery: { tenantId: '6001', from: '' }, routerPush: vi.fn() }))
@@ -17,6 +18,9 @@ vi.mock('@/modules/iam', async importOriginal => ({
vi.mock('@/modules/warehouses', () => ({ listAllPlatformWarehouses: vi.fn().mockResolvedValue([]) }))
vi.mock('@/modules/inbounds', () => ({
downloadWeightImage: vi.fn(), getInboundMeasurement: vi.fn(),
calculateInboundFee: vi.fn(), confirmInboundFee: vi.fn(), sendInboundFee: vi.fn(), getLatestInboundFee: vi.fn(),
createFeeActionIdempotencyKey: vi.fn((action: string) => `fee-${action}`),
createFeeAdjustmentIdempotencyKey: vi.fn(() => 'fee-adjust'),
downloadPlatformInboundHoldEvidence: vi.fn(), getPlatformInboundHold: vi.fn(), holdPlatformInbound: vi.fn(), releasePlatformInbound: vi.fn(), uploadPlatformInboundHoldEvidence: vi.fn(),
InboundFeePanel: { template: '<div />' }, InboundMeasurementDialog: { template: '<div />' }, MeasurementEvidenceThumbnail: { template: '<div />' },
}))
@@ -168,6 +172,58 @@ describe('UnifiedOrdersView downstream fulfillment detail', () => {
wrapper.unmount()
})
it.each([
{ confirmedVolume: 3.894, hasReference: true },
{ confirmedVolume: 4.25, hasReference: true },
{ confirmedVolume: 4.25, hasReference: false },
])('defaults billing to the saved outer volume and sends $confirmedVolume (reference: $hasReference)', async ({ confirmedVolume, hasReference }) => {
const fee = { unitPrice: 13.6, chargeableQuantity: 650.298, chargeUnit: 'KG', roundingScale: 4, rateCode: 'RATE', feeStatus: 'CALCULATED' }
vi.mocked(getLatestInboundFee).mockResolvedValue(fee as never)
if (!hasReference) vi.mocked(getLatestInboundFee).mockRejectedValueOnce(new ApiResponseError('暂无费用快照', 'A0404', 200))
vi.mocked(calculateInboundFee).mockResolvedValue(fee as never)
vi.mocked(confirmInboundFee).mockResolvedValue({ ...fee, feeStatus: 'CONFIRMED' } as never)
vi.mocked(sendInboundFee).mockResolvedValue({ ...fee, feeStatus: 'SENT' } as never)
const wrapper = mountDetail()
await flushPromises()
const vm = wrapper.vm as unknown as {
measurementDetail: Record<string, unknown>
measurementSectionModes: { outer: string; actual: string }
feeConfirmVolume: number
feeConfirmWeight: number
feeConfirmRows: { source: string; volume: number }[]
openFeeConfirmDialog(): Promise<void>
executeConfirmAndSendFee(): Promise<void>
}
vm.measurementDetail = {
actualPackageCount: 22, actualGrossWeightKg: 570.5, actualVolumeCbm: 3.6894,
items: [{ id: '9001', itemNo: 'B1', packageCount: 22, lengthCm: 62, widthCm: 52, heightCm: 52,
outerLengthCm: 63, outerWidthCm: 53, outerHeightCm: 53,
calculatedOuterLengthCm: 63, calculatedOuterWidthCm: 53, calculatedOuterHeightCm: 53,
unitVolumeCbm: 0.177, totalVolumeCbm: 3.894, volumeWeightKg: 650.298,
coefficientMode: 'ACTUAL', calculationRuleVersion: 'WAREHOUSE_OUTER_OVERRIDE_V1' }],
}
vm.measurementSectionModes.outer = 'ACTUAL'
vm.measurementSectionModes.actual = 'ACTUAL'
await vm.openFeeConfirmDialog()
expect(vm.feeConfirmRows.find(row => row.source === '实际测量数据')?.volume).toBeCloseTo(3.6894)
expect(vm.feeConfirmRows.find(row => row.source === '外箱规数据')?.volume).toBeCloseTo(3.894)
expect(vm.feeConfirmVolume).toBeCloseTo(3.894)
expect(vm.feeConfirmWeight).toBeCloseTo(570.5)
if (!hasReference) expect(calculateInboundFee).toHaveBeenCalledWith('6001', '7001', {
selectedWeightKg: 570.5, selectedVolumeCbm: 3.894, weightSource: 'ACTUAL', volumeSource: 'OUTER',
}, 'fee-calculate')
vm.feeConfirmVolume = confirmedVolume
await vm.executeConfirmAndSendFee()
expect(calculateInboundFee).toHaveBeenCalledWith('6001', '7001', {
selectedWeightKg: 570.5, selectedVolumeCbm: confirmedVolume, weightSource: 'ACTUAL', volumeSource: 'OUTER',
}, 'fee-calculate')
expect(confirmInboundFee).toHaveBeenCalledWith('6001', '7001', 'fee-confirm')
expect(sendInboundFee).toHaveBeenCalledWith('6001', '7001', 'fee-send')
wrapper.unmount()
})
it('downloads one preview for cargo rows sharing the same product image', async () => {
vi.mocked(getPlatformUnifiedOrder).mockResolvedValue({
...detail,