feat(admin): bind booking documents and truck containers
This commit is contained in:
@@ -5,85 +5,52 @@ import { resolve } from 'node:path'
|
||||
const source = readFileSync(resolve(process.cwd(), 'src/modules/trucking/components/TruckAppointmentForm.vue'), 'utf8')
|
||||
|
||||
describe('TruckAppointmentForm interaction contract', () => {
|
||||
it('uses searchable business selectors for shared resources', () => {
|
||||
expect(source).toContain('listPlatformTenants')
|
||||
expect(source).toContain('listSuppliers')
|
||||
expect(source).toContain('listContainers')
|
||||
expect(source).toContain('listOceanBookings')
|
||||
expect(source).toContain('listAllPlatformWarehouses')
|
||||
expect(source).not.toContain('label="承运商 ID"')
|
||||
expect(source).not.toContain('label="客户关联 ID"')
|
||||
expect(source).toContain("listPlatformTenants({ page: 1, size: 200, status: 'ACTIVE' })")
|
||||
expect(source).toContain("listSuppliers({ page: 1, size: 200, category: 'TRUCKING', status: 'ACTIVE' })")
|
||||
expect(source).toContain('function customerLabel(customer: PlatformTenantResource) { return customer.tenantName }')
|
||||
expect(source).not.toContain('customer.tenantCode')
|
||||
it('requires a released booking before a real-numbered allocated container', () => {
|
||||
expect(source).toContain("listOceanBookings({ page: 1, size: 200, status: 'RELEASED' })")
|
||||
expect(source).toContain("oceanBookingId: [{ required: true, message: '请选择已放舱订舱'")
|
||||
expect(source).toContain("containerBookingId: [{ required: true, message: '请选择该订舱下已录真实集装箱号的柜次'")
|
||||
expect(source.indexOf('label="订舱"')).toBeLessThan(source.indexOf('label="柜次(真实集装箱号)"'))
|
||||
expect(source).toContain(':disabled="!draft.oceanBookingId || bookingContainersLoading"')
|
||||
expect(source).not.toContain('关联订舱(可选)')
|
||||
expect(source).not.toContain('关联柜次(可选)')
|
||||
})
|
||||
|
||||
it('synchronizes ids and names and recovers failed option loading', () => {
|
||||
expect(source).toContain('selectCarrier')
|
||||
expect(source).toContain("item.category === 'TRUCKING' && item.status === 'ACTIVE'")
|
||||
expect(source).toContain('请选择有效的合作中拖车供应商')
|
||||
expect(source).toContain('draft.carrierName')
|
||||
expect(source).toContain('selectCustomer')
|
||||
expect(source).toContain('draft.customerName')
|
||||
expect(source).toContain('selectContainer')
|
||||
expect(source).toContain('draft.loadingPlanId = item.planId || null')
|
||||
expect(source).toContain('draft.loadingPlanId = null; draft.warehouseId = null')
|
||||
expect(source).toContain("derivedCustomerSource.value === 'container'")
|
||||
expect(source).toContain("derivedCustomerSource.value === 'booking'")
|
||||
it('loads only containers allocated to the selected booking and filters missing or malformed physical numbers', () => {
|
||||
expect(source).toContain('getOceanBooking(bookingId)')
|
||||
expect(source).toContain('containers.value = booking.containers || []')
|
||||
expect(source).toContain('bookingDocuments.value = booking.documents || []')
|
||||
expect(source).toContain('isIso6346ContainerNumber(item.containerNo)')
|
||||
expect(source).toContain('该订舱暂无已录真实集装箱号的柜次')
|
||||
expect(source).not.toContain('listContainers')
|
||||
})
|
||||
|
||||
it('clears an incompatible container whenever the booking changes', () => {
|
||||
expect(source).toContain('draft.containerBookingId = null')
|
||||
expect(source).toContain('draft.loadingPlanId = null')
|
||||
expect(source).toContain('if (!selectableContainers.value.some((item) => item.containerBookingId === draft.containerBookingId))')
|
||||
})
|
||||
|
||||
it('freezes customer, warehouse and bill of lading snapshots from the booking', () => {
|
||||
expect(source).toContain('draft.customerId = item.customerId')
|
||||
expect(source).toContain('draft.customerName = item.customerName')
|
||||
expect(source).toContain('draft.warehouseId = item.warehouseId')
|
||||
expect(source).toContain('draft.billOfLadingNo = item.billOfLadingNo')
|
||||
expect(source).toContain('已从放舱订舱冻结资料带入')
|
||||
expect(source).toContain(':model-value="draft.billOfLadingNo || \'\'" disabled')
|
||||
})
|
||||
|
||||
it('keeps server-side validation authoritative and preserves recoverable option errors', () => {
|
||||
expect(source).toContain('最终资格仍由服务端校验')
|
||||
expect(source).toContain('所选订舱缺少有效的订舱确认文件或提单文件')
|
||||
expect(source).toContain('bookingContainersError')
|
||||
expect(source).toContain('重新加载选项')
|
||||
})
|
||||
|
||||
it('keeps historical snapshots visible but requires active customer and carrier choices', () => {
|
||||
expect(source).toContain("item.status === 'ACTIVE'")
|
||||
expect(source).toContain("item.status === 'ACTIVE' || String(item.id) === String(draft.warehouseId)")
|
||||
expect(source).toContain('v-for="item in selectableCustomers"')
|
||||
expect(source).toContain('v-for="item in selectableWarehouses"')
|
||||
expect(source).toContain("customerId: [{ required: true, message: '请选择客户'")
|
||||
expect(source).toContain("carrierId: [{ required: true, message: '请选择承运商'")
|
||||
expect(source).toContain("plannedLoadingAt: [{ required: true, message: '请选择预计装箱时间'")
|
||||
expect(source).toContain("draft.customerName || '历史客户(需重新选择)'")
|
||||
expect(source).toContain(':value="String(draft.customerId)" disabled')
|
||||
expect(source).not.toContain('const relationText = computed')
|
||||
})
|
||||
|
||||
it('loads readonly detail options and preserves relation snapshots outside the first page', () => {
|
||||
expect(source).toContain('onMounted(() => { void loadOptions() })')
|
||||
expect(source).toContain('const selectedContainerFallback = computed')
|
||||
expect(source).toContain('const selectedBookingFallback = computed')
|
||||
expect(source).toContain('const selectedWarehouseFallback = computed')
|
||||
expect(source).toContain('v-if="selectedContainerFallback"')
|
||||
expect(source).toContain('v-if="selectedBookingFallback"')
|
||||
expect(source).toContain('v-if="selectedWarehouseFallback"')
|
||||
})
|
||||
|
||||
it('keeps booking, cabinet and loading plan optional and only uses them for completion hints', () => {
|
||||
expect(source).toContain('订舱、柜次和装柜计划均为可选关联,不影响独立开立拖车预约')
|
||||
expect(source).toContain('class="relation-note"')
|
||||
expect(source).toContain('<slot name="relation-note-actions" />')
|
||||
expect(source).toContain('justify-content:space-between')
|
||||
expect(source).not.toContain('class="relation-alert">历史关联快照')
|
||||
expect(source).toContain('<el-divider content-position="left">可选关联</el-divider>')
|
||||
expect(source).toContain('label="关联柜次(可选)"')
|
||||
expect(source).toContain('label="关联订舱(可选)"')
|
||||
expect(source).toContain("relationWarning.value = '所选关联资源与当前客户不一致")
|
||||
expect(source).toContain("item.status === 'RELEASED'")
|
||||
expect(source).toContain('已从放舱订舱回填并锁定')
|
||||
expect(source).toContain(':disabled="Boolean(selectedReleasedBooking)"')
|
||||
expect(source).toContain('草稿可暂不填写,派车前必填')
|
||||
expect(source).not.toContain('尚未建立装柜计划')
|
||||
})
|
||||
|
||||
it('gives editable fields clear placeholders', () => {
|
||||
expect(source).toContain('placeholder="请输入司机姓名"')
|
||||
expect(source).toContain('placeholder="请选择预计装箱时间"')
|
||||
expect(source).toContain('placeholder="请输入目的门店地址"')
|
||||
expect(source).toContain('placeholder="请输入拖车预约备注(可选)"')
|
||||
expect(source).toContain('重新加载')
|
||||
expect(source).toContain('请选择有效的合作中拖车供应商')
|
||||
})
|
||||
|
||||
it('labels the generated cabinet reference and physical container number separately', () => {
|
||||
expect(source).toContain('柜次号:${item.cabinetNo')
|
||||
expect(source).toContain('集装箱号:${item.containerNo')
|
||||
expect(source).toContain('集装箱号:${item.containerNo}')
|
||||
})
|
||||
|
||||
it('keeps the form usable at 390px', () => {
|
||||
|
||||
Reference in New Issue
Block a user