fix(admin): preserve booking load trace details
This commit is contained in:
@@ -43,6 +43,8 @@ describe('TruckAppointmentForm interaction contract', () => {
|
||||
expect(source).toContain('最终资格仍由服务端校验')
|
||||
expect(source).toContain('所选订舱缺少有效的订舱确认文件或提单文件')
|
||||
expect(source).toContain('bookingContainersError')
|
||||
expect(source).toContain("getApiErrorDetails(cause, '该订舱柜次加载失败,请重试')")
|
||||
expect(source).toContain('<ApiErrorMeta :details="bookingContainersError" />')
|
||||
expect(source).toContain('重新加载选项')
|
||||
expect(source).toContain('重新加载')
|
||||
expect(source).toContain('请选择有效的合作中拖车供应商')
|
||||
|
||||
@@ -5,6 +5,8 @@ import { Eye, Save } from '@lucide/vue'
|
||||
import type { SaveTruckAppointmentRequest, TruckAppointmentResource } from '../types'
|
||||
import { listSuppliers, type Supplier } from '@/modules/suppliers'
|
||||
import { getOceanBooking, listOceanBookings, type OceanBookingAllocatedContainer, type OceanBookingDocument, type OceanBookingResource } from '@/modules/ocean-bookings'
|
||||
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
|
||||
import { getApiErrorDetails, type ApiErrorDetails } from '@/shared/api/http'
|
||||
import { isIso6346ContainerNumber } from '../iso6346'
|
||||
|
||||
const props = defineProps<{ modelValue: SaveTruckAppointmentRequest; resource?: TruckAppointmentResource | null; readonly?: boolean; submitting?: boolean }>()
|
||||
@@ -12,7 +14,7 @@ const emit = defineEmits<{ 'update:modelValue': [SaveTruckAppointmentRequest]; s
|
||||
const formRef = ref<FormInstance>()
|
||||
const relationWarning = ref('')
|
||||
const bookingContainersLoading = ref(false)
|
||||
const bookingContainersError = ref('')
|
||||
const bookingContainersError = ref<ApiErrorDetails | null>(null)
|
||||
const bookingDocuments = ref<OceanBookingDocument[]>([])
|
||||
const defaults: Partial<SaveTruckAppointmentRequest> = { expectedVersion: 0, currency: 'RMB', payableAmount: '0.00', receivableAmount: '0.00', packageCount: 0, palletCount: 0, transitMinutes: 0 }
|
||||
function normalizeDraft(value: SaveTruckAppointmentRequest): SaveTruckAppointmentRequest { return { ...defaults, ...value, currency: value.currency?.trim().toUpperCase() || 'RMB' } }
|
||||
@@ -82,7 +84,7 @@ function selectContainer(containerId: string) {
|
||||
}
|
||||
async function loadBookingContainers(bookingId: string) {
|
||||
bookingContainersLoading.value = true
|
||||
bookingContainersError.value = ''
|
||||
bookingContainersError.value = null
|
||||
try {
|
||||
const booking = await getOceanBooking(bookingId)
|
||||
if (!bookings.value.some((item) => item.id === booking.id)) bookings.value.push(booking)
|
||||
@@ -92,12 +94,12 @@ async function loadBookingContainers(bookingId: string) {
|
||||
draft.containerBookingId = null
|
||||
draft.loadingPlanId = null
|
||||
}
|
||||
} catch {
|
||||
} catch (cause) {
|
||||
containers.value = []
|
||||
bookingDocuments.value = []
|
||||
draft.containerBookingId = null
|
||||
draft.loadingPlanId = null
|
||||
bookingContainersError.value = '该订舱柜次加载失败,请重试'
|
||||
bookingContainersError.value = getApiErrorDetails(cause, '该订舱柜次加载失败,请重试')
|
||||
} finally {
|
||||
bookingContainersLoading.value = false
|
||||
}
|
||||
@@ -151,7 +153,7 @@ watch(() => props.readonly, (readonly) => { if (!readonly && !bookings.value.len
|
||||
<el-row :gutter="16">
|
||||
<el-col :xs="24"><el-divider content-position="left">订舱与柜次(必填)</el-divider></el-col>
|
||||
<el-col :xs="24" :sm="12"><el-form-item label="订舱" prop="oceanBookingId"><el-select :model-value="draft.oceanBookingId" filterable placeholder="请先选择已放舱订舱" :loading="optionsLoading" no-data-text="暂无可用的已放舱订舱" style="width:100%" @update:model-value="selectBooking(String($event || ''))"><el-option v-if="selectedBookingFallback" :key="selectedBookingFallback.id" :label="selectedBookingFallback.label" :value="selectedBookingFallback.id" /><el-option v-for="item in bookings" :key="item.id" :label="`${item.bookingNo || '订舱号缺失'}${item.billOfLadingNo ? ` / 提单号:${item.billOfLadingNo}` : ''}`" :value="item.id" /></el-select></el-form-item></el-col>
|
||||
<el-col :xs="24" :sm="12"><el-form-item label="柜次(真实集装箱号)" prop="containerBookingId"><el-select :model-value="draft.containerBookingId" filterable :disabled="!draft.oceanBookingId || bookingContainersLoading" placeholder="请先选择订舱,再选择真实柜号柜次" :loading="bookingContainersLoading" :no-data-text="draft.oceanBookingId ? '该订舱暂无已录真实集装箱号的柜次' : '请先选择订舱'" style="width:100%" @update:model-value="selectContainer(String($event || ''))"><el-option v-if="selectedContainerFallback" :key="selectedContainerFallback.id" :label="selectedContainerFallback.label" :value="selectedContainerFallback.id" :disabled="!readonly" /><el-option v-for="item in selectableContainers" :key="item.containerBookingId" :label="`柜次号:${item.cabinetNo || '待生成'} / 集装箱号:${item.containerNo}`" :value="item.containerBookingId" /></el-select><div v-if="bookingContainersError" class="field-error"><span>{{ bookingContainersError }}</span><el-button link type="primary" :loading="bookingContainersLoading" @click="draft.oceanBookingId && loadBookingContainers(String(draft.oceanBookingId))">重新加载</el-button></div><div v-else-if="draft.oceanBookingId && !bookingContainersLoading && !selectableContainers.length" class="field-hint">只有已分配至该订舱且已录入真实 ISO 集装箱号的柜次可以预约拖车。</div></el-form-item></el-col>
|
||||
<el-col :xs="24" :sm="12"><el-form-item label="柜次(真实集装箱号)" prop="containerBookingId"><el-select :model-value="draft.containerBookingId" filterable :disabled="!draft.oceanBookingId || bookingContainersLoading" placeholder="请先选择订舱,再选择真实柜号柜次" :loading="bookingContainersLoading" :no-data-text="draft.oceanBookingId ? '该订舱暂无已录真实集装箱号的柜次' : '请先选择订舱'" style="width:100%" @update:model-value="selectContainer(String($event || ''))"><el-option v-if="selectedContainerFallback" :key="selectedContainerFallback.id" :label="selectedContainerFallback.label" :value="selectedContainerFallback.id" :disabled="!readonly" /><el-option v-for="item in selectableContainers" :key="item.containerBookingId" :label="`柜次号:${item.cabinetNo || '待生成'} / 集装箱号:${item.containerNo}`" :value="item.containerBookingId" /></el-select><div v-if="bookingContainersError" class="field-error"><span>{{ bookingContainersError.message }}</span><ApiErrorMeta :details="bookingContainersError" /><el-button link type="primary" :loading="bookingContainersLoading" @click="draft.oceanBookingId && loadBookingContainers(String(draft.oceanBookingId))">重新加载</el-button></div><div v-else-if="draft.oceanBookingId && !bookingContainersLoading && !selectableContainers.length" class="field-hint">只有已分配至该订舱且已录入真实 ISO 集装箱号的柜次可以预约拖车。</div></el-form-item></el-col>
|
||||
<el-col :xs="24"><el-divider content-position="left">基本信息</el-divider></el-col>
|
||||
<el-col v-if="draft.oceanBookingId && !bookingContainersLoading && !bookingContainersError && !bookingDocumentReady" :xs="24"><el-alert title="所选订舱缺少有效的订舱确认文件或提单文件,暂不能创建或保存拖车预约" type="warning" :closable="false" show-icon /></el-col>
|
||||
<el-col :xs="24" :sm="12"><el-form-item label="客户" prop="customerId"><el-input :model-value="draft.customerName || ''" disabled placeholder="选择订舱后自动带入" /></el-form-item></el-col>
|
||||
|
||||
Reference in New Issue
Block a user