完善预约确认与排车表单并统一计费和筛选展示

This commit is contained in:
2026-10-28 12:01:43 +08:00
parent 0c3f4ece2a
commit 39b9a6a1a0
27 changed files with 277 additions and 77 deletions
@@ -13,7 +13,7 @@ import {
submitInboundMeasurement,
updateConfirmedPackageCount,
} from './api'
import type { InboundMeasurementDetail } from './types'
import type { InboundMeasurementDetail, SaveInboundMeasurementItemRequest } from './types'
import InboundMeasurementPanel from './InboundMeasurementPanel.vue'
vi.mock('./api', () => ({
@@ -152,6 +152,10 @@ async function mountPanel(permissions = [
return wrapper
}
function measurementDraft(wrapper: Awaited<ReturnType<typeof mountPanel>>) {
return (wrapper.vm.$ as unknown as { setupState: { form: { items: SaveInboundMeasurementItemRequest[] } } }).setupState.form
}
enableAutoUnmount(afterEach)
afterAll(() => vi.unstubAllGlobals())
@@ -317,6 +321,50 @@ describe('InboundMeasurementPanel', () => {
expect(wrapper.find('.measurement-declaration').element.parentElement).toBe(wrapper.find('.measurement-summary-section').element.parentElement)
})
it('shows raw measured volume rather than customer weighted billing volume in the rows and comparison', async () => {
const value = measurement({ originalVolumeCbm: 3.3, originalPackageCount: 22, actualPackageCount: 22, actualVolumeCbm: 7.205, volumeWeightKg: 1203.235 })
Object.assign(value.items[0]!, {
lengthCm: 62, widthCm: 52, heightCm: 52, packageCount: 22,
coefficientMode: 'MULTIPLY', chargeRuleId: '6001',
calculatedOuterLengthCm: 77.5, calculatedOuterWidthCm: 65, calculatedOuterHeightCm: 65,
unitVolumeCbm: 0.3275, totalVolumeCbm: 7.205,
})
vi.mocked(getInboundMeasurement).mockResolvedValueOnce(value)
const wrapper = await mountPanel()
const comparisonVolume = () => wrapper.get('.measurement-comparison tbody tr:last-child').findAll('td').map(cell => cell.text())
expect(comparisonVolume()).toEqual(['3.300', '3.688', '差异 +0.388 m³'])
expect(wrapper.get('.measurement-table').text()).toContain('3.688')
expect(wrapper.get('.measurement-table').text()).not.toContain('7.205')
expect(wrapper.get('.measurement-extra-facts').text()).toContain('计费材积重')
await wrapper.get('input[aria-label="仓库修改外箱长"]').setValue('80')
expect(comparisonVolume()[1]).toBe('3.688')
await wrapper.get('.measurement-count-editor input').setValue('11')
expect(comparisonVolume()).toEqual(['3.300', '1.844', '差异 -1.456 m³'])
expect(wrapper.get('.measurement-table').text()).toContain('1.844')
expect(value.actualVolumeCbm).toBe(7.205)
expect(saveInboundMeasurementDraft).not.toHaveBeenCalled()
expect(updateConfirmedPackageCount).not.toHaveBeenCalled()
})
it('sums measured volumes across rows and does not substitute billing totals for incomplete dimensions', async () => {
const value = measurement({ actualVolumeCbm: 9.999 })
value.items.push({ ...value.items[0]!, id: '9102', itemNo: '002', boxCode: 'RK202608040001#10-2', lengthCm: 10, widthCm: 20, heightCm: 30, packageCount: 2, totalVolumeCbm: 8.888 })
vi.mocked(getInboundMeasurement).mockResolvedValueOnce(value)
const wrapper = await mountPanel()
expect(wrapper.get('.measurement-comparison tbody tr:last-child').findAll('td')[1]!.text()).toBe('0.612')
value.items[1]!.lengthCm = 0
vi.mocked(getInboundMeasurement).mockResolvedValueOnce(value)
await wrapper.setProps({ inboundId: '7002' })
await flushPromises()
const cells = wrapper.get('.measurement-comparison tbody tr:last-child').findAll('td')
expect(cells[1]!.text()).toBe('未测量')
expect(cells[2]!.text()).toBe('待测量')
expect(wrapper.get('.measurement-table').text()).not.toContain('8.888')
})
it('shows pending comparison rather than a negative count when no boxes have been measured', async () => {
vi.mocked(getInboundMeasurement).mockResolvedValueOnce(measurement({
items: [], actualPackageCount: null, actualGrossWeightKg: null, actualVolumeCbm: null,
@@ -424,7 +472,7 @@ describe('InboundMeasurementPanel', () => {
it('retains server-calculated facts in the draft without the removed expandable row', async () => {
const wrapper = await mountPanel()
expect(wrapper.find('.el-table__expand-icon').exists()).toBe(false)
expect(wrapper.vm.form.items[0]).toMatchObject({
expect(measurementDraft(wrapper).items[0]).toMatchObject({
boxSpecification: '50×40×30cm', coefficientMode: 'ACTUAL',
calculatedOuterLengthCm: 50, calculatedOuterWidthCm: 40, calculatedOuterHeightCm: 30,
calculationRuleVersion: 'DIMENSION_ACTUAL_V1',
@@ -621,7 +669,7 @@ describe('InboundMeasurementPanel', () => {
it('retains the formal deviceMeasuredAt response field in the measurement draft', async () => {
const wrapper = await mountPanel()
expect(wrapper.vm.form.items[0].measuredAt).toBe('2026-08-04T10:30:00+08:00')
expect(measurementDraft(wrapper).items[0]!.measuredAt).toBe('2026-08-04T10:30:00+08:00')
const source = await import('./InboundMeasurementPanel.vue?raw').then((module) => module.default)
expect(source).toContain('measuredAt: item.deviceMeasuredAt')
expect(source).not.toContain('measuredAt: item.measuredAt')