fix(fleet): lock destination in readonly inquiry dialog

This commit is contained in:
2026-10-10 18:15:39 +08:00
parent 67bd3e6e53
commit 7f39adf9f5
2 changed files with 34 additions and 1 deletions
@@ -59,3 +59,36 @@ it.each(scenarios)('uses explicit offer quote queries, pagination and negotiated
expect(listOfferQuotes).toHaveBeenCalledTimes(2)
expect(wrapper.emitted('saved')).toHaveLength(1)
})
it('locks the destination in readonly follow-up even without offer detail, while allowing multi-stop editing', async () => {
permissions.values = new Set(['platform:fleet:capacity-offer:manage'])
const multi = { ...offer, destinations: [...offer.destinations, { destinationKey: 'FBA:ACY2', name: 'ACY2', deliveryIndex: 2, remaining: null }] }
const row: CapacityInquiry = {
bookingNo: 'FB-READONLY', offerNo: offer.offerNo, tripNo: offer.tripNo, status: 'DRAFT', recordVersion: 1,
offerRecordVersion: offer.recordVersion, tripRecordVersion: offer.tripRecordVersion, salesOwnerUserId: '17',
customerId: '19', customerCode: 'C-19', customerName: '测试客户', businessType: 'LOCAL_LOOSEBOARD', deliveryMode: 'SELF_DELIVERY',
estimatedArrivalAt: null, expectedPalletCount: null,
cargo: { destinationKey: 'FBA:ACY2', cargoName: null, packageCount: null, palletSpaces: null, weightKg: null, volumeCbm: null, priceBasis: 'PALLET', unitPrice: null, currency: 'USD', contactName: null, contactPhone: null, remark: null },
destinationLabel: 'ACY2', agreedAmount: null, quoteSource: null, businessOrderNo: null, incomingNo: null, dispatchNo: null,
updatedAt: '2026-10-10T00:00:00Z', actions: { canEdit: true, canConfirm: false, canCancel: true, blockReason: null }, appointmentCoverage: null,
progress: { stage: 'NEEDS_DETAILS', label: '待补资料', reservation: '尚未保位', owner: '销售', primaryAction: 'EDIT', message: '待补资料', missingFields: [] },
}
const wrapper = mount(CapacityInquiryDialog, { attachTo: document.body, props: { modelValue: true, offer: null, inquiry: row, readonly: true }, global: { plugins: [createPinia(), ElementPlus] } })
wrappers.push(wrapper); await flushPromises()
const destination = () => formItem(wrapper, '本车卸货站').findComponent({ name: 'ElSelect' })
expect(destination().get('input[role="combobox"]').attributes('disabled')).toBeDefined()
await destination().find('.el-select__wrapper').trigger('click'); await flushPromises()
expect(destination().get('input[role="combobox"]').attributes('aria-expanded')).toBe('false')
expect(destination().props('modelValue')).toBe('FBA:ACY2')
await wrapper.setProps({ offer: multi, readonly: false }); await flushPromises()
expect(destination().get('input[role="combobox"]').attributes('disabled')).toBeUndefined()
await destination().find('.el-select__wrapper').trigger('click'); await flushPromises()
expect(destination().get('input[role="combobox"]').attributes('aria-expanded')).toBe('true')
await select(wrapper, '本车卸货站', 'FBA:ONT8')
expect(destination().props('modelValue')).toBe('FBA:ONT8')
await wrapper.setProps({ inquiry: null }); await flushPromises()
expect(destination().get('input[role="combobox"]').attributes('disabled')).toBeUndefined()
await wrapper.setProps({ offer }); await flushPromises()
expect(destination().get('input[role="combobox"]').attributes('disabled')).toBeDefined()
expect(saveCapacityInquiry).not.toHaveBeenCalled()
})
@@ -119,7 +119,7 @@ onBeforeUnmount(() => { generation++; customerSequence++; quoteSequence++; clear
</section>
<el-form label-position="top" class="density-form capacity-inquiry-form" :disabled="lock">
<el-form-item label="委托客户" required><el-select v-model="form.customerId" filterable remote :remote-method="searchCustomers" :loading="customerLoading" :disabled="!!inquiry" placeholder="按客户编号或名称搜索" @focus="searchCustomers()"><el-option v-if="inquiry" :value="inquiry.customerId" :label="`${inquiry.customerCode} · ${inquiry.customerName}`" /><el-option v-for="customer in customers" :key="customer.id" :value="customer.id" :label="`${customer.code} · ${customer.name}`" /></el-select><span v-if="customerSearched && !customers.length">暂无可选客户</span></el-form-item>
<el-form-item label="本车卸货站" required><el-select v-model="form.cargo.destinationKey" :disabled="offer?.destinations.length === 1" placeholder="选择本车既有卸货站"><el-option v-for="stop in offer?.destinations || []" :key="stop.destinationKey" :value="stop.destinationKey" :label="stop.name" /><el-option v-if="!offer && inquiry" :value="inquiry.cargo.destinationKey" :label="inquiry.destinationLabel" /></el-select></el-form-item>
<el-form-item label="本车卸货站" required><el-select v-model="form.cargo.destinationKey" :disabled="lock || offer?.destinations.length === 1" placeholder="选择本车既有卸货站"><el-option v-for="stop in offer?.destinations || []" :key="stop.destinationKey" :value="stop.destinationKey" :label="stop.name" /><el-option v-if="!offer && inquiry" :value="inquiry.cargo.destinationKey" :label="inquiry.destinationLabel" /></el-select></el-form-item>
<details class="capacity-inquiry-wide" :open="readonly || confirmMode"><summary>已知货量(可先填写,未知可留空)</summary><div class="capacity-inquiry-form">
<el-form-item label="预计箱数"><el-input-number v-model="form.cargo.packageCount" :min="1" :precision="0" placeholder="未知可留空" /></el-form-item>
<el-form-item label="预计实托数"><el-input-number v-model="form.expectedPalletCount" :min="1" :precision="0" placeholder="卡车确认承运前必填" /></el-form-item>