fix(fleet): keep capacity fields readable in publish dialog
This commit is contained in:
@@ -19,7 +19,7 @@ function mount(realPlanner = false) {
|
||||
const wrapper = shallowMount(Dialog, { props: { modelValue: true, trip }, global: { plugins: [createPinia()], stubs: {
|
||||
AppDialog: { name: 'AppDialog', props: ['confirmText'], emits: ['confirm'], template: '<div><slot/><button @click="$emit(\'confirm\')">{{confirmText}}</button></div>' },
|
||||
TripLoadingPanel: realPlanner ? false : defineComponent({ name: 'TripLoadingPanel', setup(_, { expose }) { expose({ save: state.plan }); return {} }, template: '<div/>' }),
|
||||
DataTable: { name: 'DataTable', props: ['data'], template: '<div><div v-for="row in data" :key="row.warehousePalletId"><slot name="weight" :row="row"/><slot name="volume" :row="row"/></div></div>' },
|
||||
DataTable: { name: 'DataTable', props: ['data', 'columns'], template: '<div><div v-for="row in data" :key="row.warehousePalletId"><slot name="palletNo" :row="row"/><slot name="weight" :row="row"/><slot name="volume" :row="row"/></div></div>' },
|
||||
ElInputNumber: { name: 'ElInputNumber', props: ['modelValue'], emits: ['update:modelValue'], template: '<input/>' },
|
||||
ElForm: { template: '<div><slot/></div>' }, ElFormItem: { template: '<div><slot/></div>' },
|
||||
ElButton: { template: '<button><slot/></button>' }, ElDatePicker: true, ElInput: true, LoadErrorState: true, ApiErrorMeta: true,
|
||||
@@ -61,10 +61,14 @@ it('retries only the uncertain publish command with the original key', async ()
|
||||
})
|
||||
|
||||
it('submits measurements from the embedded panel before saving and publishing', async () => {
|
||||
const basis = { tripNo: 'TR-1', recordVersion: 5, cargo: [{ dispatchNo: 'DP-1', customerId: '1', dispatchItemId: '2', warehousePalletId: '3', palletNo: 'PLT-1', packages: 1, destinationKey: 'FBA:ACY2', destinationLabel: 'ACY2' }], manifestHash: 'hash', capacityPlan: null, planValid: false, blockReason: null, availableSegments: [] }
|
||||
const basis = { tripNo: 'TR-1', recordVersion: 5, cargo: [{ dispatchNo: 'DP-1', customerId: '1', dispatchItemId: '2', warehousePalletId: '3', palletNo: 'PLT-USLAX01-261010-G0RD3LYHGD8H', packages: 1, destinationKey: 'FBA:ACY2', destinationLabel: 'ACY2' }], manifestHash: 'hash', capacityPlan: null, planValid: false, blockReason: null, availableSegments: [] }
|
||||
vi.mocked(trips.getTripCapacityPlan).mockResolvedValue(basis)
|
||||
vi.mocked(trips.confirmTripCapacityPlan).mockResolvedValue({ ...basis, recordVersion: 6, planValid: true })
|
||||
const wrapper = mount(true); await flushPromises()
|
||||
expect(wrapper.text()).toContain('PLT-USLAX01-261010-G0RD3LYHGD8H')
|
||||
const columns = wrapper.findComponent({ name: 'DataTable' }).props('columns') as { key: string; singleLine?: boolean; width?: number; minWidth?: number }[]
|
||||
expect(columns.filter(column => ['palletNo', 'spaces', 'weight', 'volume', 'stop'].includes(column.key)).every(column => column.singleLine === false)).toBe(true)
|
||||
expect(columns.reduce((sum, column) => sum + (column.width || column.minWidth || 0), 0)).toBeLessThanOrEqual(1048)
|
||||
const fields = wrapper.findAllComponents({ name: 'ElInputNumber' })
|
||||
fields[0]!.vm.$emit('update:modelValue', 100); fields[1]!.vm.$emit('update:modelValue', 2); await flushPromises()
|
||||
wrapper.findComponent({ name: 'AppDialog' }).vm.$emit('confirm'); await flushPromises()
|
||||
|
||||
@@ -15,10 +15,14 @@ const info = ref<TripLoading | TripCapacityPlanning | null>(null), rows = ref<Pa
|
||||
let sequence = 0
|
||||
const baseline = ref('')
|
||||
watch(rows, value => emit('changed', JSON.stringify(value)), { deep: true })
|
||||
const columns = computed<DataTableColumn[]>(() => [{ key: 'palletNo', prop: 'palletNo', label: '实物托盘', minWidth: 150 },
|
||||
{ key: 'destinations', prop: 'destinations', label: '货物目的地', minWidth: 160 }, { key: 'spaces', label: '占用标准托位', slotName: 'spaces', width: 175 },
|
||||
{ key: 'weight', label: props.planning ? '预计重量(kg)' : '实测重量(kg)', slotName: 'weight', width: 190 }, { key: 'volume', label: props.planning ? '预计体积(m³)' : '实测体积(m³)', slotName: 'volume', width: 190 },
|
||||
{ key: 'stop', label: '卸货站', slotName: 'stop', minWidth: 200 }])
|
||||
const columns = computed<DataTableColumn[]>(() => [
|
||||
{ key: 'palletNo', label: '实物托盘', slotName: 'palletNo', minWidth: 210, singleLine: false },
|
||||
{ key: 'destinations', prop: 'destinations', label: '货物目的地', minWidth: 140, singleLine: false },
|
||||
{ key: 'spaces', label: '占用标准托位', slotName: 'spaces', width: 160, singleLine: false },
|
||||
{ key: 'weight', label: props.planning ? '预计重量(kg)' : '实测重量(kg)', slotName: 'weight', width: 180, singleLine: false },
|
||||
{ key: 'volume', label: props.planning ? '预计体积(m³)' : '实测体积(m³)', slotName: 'volume', width: 180, singleLine: false },
|
||||
{ key: 'stop', label: '卸货站', slotName: 'stop', minWidth: 160, singleLine: false },
|
||||
])
|
||||
const savedLoad = computed(() => info.value && ('capacityPlan' in info.value ? info.value.capacityPlan : info.value.confirmedLoad))
|
||||
const segments = computed(() => info.value && 'availableSegments' in info.value ? info.value.availableSegments : savedLoad.value?.segments || [])
|
||||
const stalePlan = computed(() => info.value && 'planValid' in info.value && !!info.value.capacityPlan && !info.value.planValid)
|
||||
@@ -91,7 +95,8 @@ onBeforeUnmount(() => { sequence++ })
|
||||
<p v-if="info?.blockReason" role="status">{{ info.blockReason }}</p>
|
||||
<p v-else-if="!planning && savedLoad">已确认实际装载;车辆、司机或计划调整后需要重新确认。</p>
|
||||
<p v-else-if="!planning">按实物托盘核对,同一托盘中的多客户货物只计一次。发车仍由海外 PDA 完成。</p>
|
||||
<DataTable :data="rows" :columns="columns" row-key="warehousePalletId" empty-text="关联排车单后显示实物托盘">
|
||||
<DataTable class="trip-loading-table" :data="rows" :columns="columns" row-key="warehousePalletId" empty-text="关联排车单后显示实物托盘">
|
||||
<template #palletNo="{ row }"><span class="trip-pallet-code">{{ row.palletNo }}</span></template>
|
||||
<template #spaces="{ row }"><el-input-number v-model="row.palletSpaces" :min="1" :precision="0" :disabled="!editable || busy" placeholder="占用托位" /></template>
|
||||
<template #weight="{ row }"><el-input-number v-model="row.weightKg" :min="0.001" :precision="3" :disabled="!editable || busy" :placeholder="planning ? '预计重量' : '实际重量'" /></template>
|
||||
<template #volume="{ row }"><el-input-number v-model="row.volumeCbm" :min="0.001" :precision="3" :disabled="!editable || busy" :placeholder="planning ? '预计体积' : '实际体积'" /></template>
|
||||
@@ -101,3 +106,8 @@ onBeforeUnmount(() => { sequence++ })
|
||||
<table v-if="savedLoad && !stalePlan" class="density-table"><thead><tr><th>行驶区间</th><th>占用托位</th><th>重量(kg)</th><th>体积(m³)</th><th v-if="planning">剩余托位 / kg / m³</th></tr></thead><tbody><tr v-for="segment in segments" :key="segment.fromIndex"><td>{{ trip.stops[segment.fromIndex]?.name }} → {{ trip.stops[segment.toIndex]?.name }}</td><td>{{ segment.occupied.palletSpaces }} / {{ trip.maxPalletSpaces }}</td><td>{{ segment.occupied.weightKg }} / {{ trip.maxLoadKg }}</td><td>{{ segment.occupied.volumeCbm }} / {{ trip.maxVolumeCbm }}</td><td v-if="planning">{{ segment.remaining.palletSpaces }} / {{ segment.remaining.weightKg }} / {{ segment.remaining.volumeCbm }}</td></tr></tbody></table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.trip-pallet-code{white-space:normal;overflow-wrap:anywhere}
|
||||
.trip-loading-table :deep(.el-input-number),.trip-loading-table :deep(.el-select){width:100%;min-width:0;max-width:100%}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user