This commit is contained in:
2026-08-08 14:13:32 +08:00
parent 6f0859e4f3
commit a3a09d1dec
9 changed files with 59 additions and 43 deletions
@@ -3,7 +3,7 @@ import type { OceanBookingDetail, OceanBookingPage, OceanBookingQuery, OceanBook
const basePath = '/platform/v1/ocean-bookings'
function pageNumber(value: number | string, fallback: number) { const n = Number(value); return Number.isFinite(n) ? Math.trunc(n) : fallback }
function booking(raw: OceanBookingResource): OceanBookingResource { return { ...raw, id: String(raw.id), customerId: raw.customerId == null ? null : String(raw.customerId), containers: (raw.containers || []).map((item) => ({ ...item, id: String(item.id) })) } }
function booking(raw: OceanBookingResource): OceanBookingResource { const item = raw as OceanBookingResource & { departurePortName?: string | null; destinationPortName?: string | null; shippingCompanyName?: string | null; estimatedSailingAt?: string | null; estimatedArrivalAt?: string | null }; return { ...raw, id: String(raw.id), customerId: raw.customerId == null ? null : String(raw.customerId), pol: raw.pol ?? item.departurePortName ?? null, pod: raw.pod ?? item.destinationPortName ?? null, carrierName: raw.carrierName ?? item.shippingCompanyName ?? null, etd: raw.etd ?? item.estimatedSailingAt ?? null, eta: raw.eta ?? item.estimatedArrivalAt ?? null, containers: (raw.containers || []).map((container) => ({ ...container, id: String(container.id ?? '') })) } }
export async function listOceanBookings(query: OceanBookingQuery) {
const response = await http.get<ApiEnvelope<OceanBookingPage>, ApiEnvelope<OceanBookingPage>>(basePath, { params: query })
const result = unwrapApiResponse(response)
@@ -13,7 +13,7 @@ const router = useRouter(); const rows = ref<OceanBookingResource[]>([]); const
const query = reactive<QueryModel>({ keyword: '', status: '', pol: '', pod: '', soNo: '' })
const statuses: Array<{ label: string; value: string }> = [{ label: '草稿', value: 'DRAFT' }, { label: '已提交', value: 'SUBMITTED' }, { label: '已确认', value: 'CONFIRMED' }, { label: '已放舱', value: 'RELEASED' }, { label: '失败', value: 'FAILED' }, { label: '变更中', value: 'CHANGE_PENDING' }, { label: '已取消', value: 'CANCELLED' }]
const fields: QueryField[] = [{ key: 'keyword', type: 'input', label: '关键词', placeholder: '订舱号/订单号/客户', width: 220 }, { key: 'status', type: 'select', label: '状态', options: statuses }, { key: 'pol', type: 'input', label: '起运港', width: 150 }, { key: 'pod', type: 'input', label: '目的港', width: 150 }, { key: 'soNo', type: 'input', label: 'S/O号', width: 150 }]
const columns = [{ key: 'actions', label: '操作', fixed: 'left', width: 170, slotName: 'actions', hideable: false, movable: false }, { prop: 'bookingNo', label: '订舱编号', minWidth: 150 }, { prop: 'orderNo', label: '关联订单', minWidth: 140 }, { prop: 'customerName', label: '客户', minWidth: 140 }, { prop: 'pol', label: '起运港', minWidth: 110 }, { prop: 'pod', label: '目的港', minWidth: 110 }, { prop: 'vesselName', label: '船名/航次', minWidth: 150, slotName: 'vessel' }, { prop: 'soNo', label: 'S/O号', minWidth: 130 }, { prop: 'cutoffAt', label: '截关时间', minWidth: 150 }, { prop: 'status', label: '状态', minWidth: 110, slotName: 'status' }]
const columns = [{ key: 'actions', label: '操作', fixed: 'left', width: 170, slotName: 'actions', hideable: false, movable: false }, { prop: 'bookingNo', label: '订舱编号', minWidth: 150 }, { prop: 'orderNo', label: '关联订单', minWidth: 140 }, { prop: 'customerName', label: '委托单位', minWidth: 160 }, { prop: 'mblShipper', label: 'MB/L货人', minWidth: 150 }, { prop: 'mblConsignee', label: 'MB/L收人', minWidth: 150 }, { prop: 'pol', label: '起运港(POL)', minWidth: 125 }, { prop: 'pod', label: '目的港(POD)', minWidth: 125 }, { prop: 'containerSummary', label: '箱型/箱量', minWidth: 120 }, { prop: 'carrierName', label: '船公司', minWidth: 130 }, { prop: 'vesselName', label: '船名/航次', minWidth: 150, slotName: 'vessel' }, { prop: 'soNo', label: 'S/O号', minWidth: 130 }, { prop: 'cutoffAt', label: '预计截关', minWidth: 150 }, { prop: 'etd', label: 'ETD', minWidth: 140 }, { prop: 'atd', label: 'ATD', minWidth: 140 }, { prop: 'eta', label: 'ETA', minWidth: 140 }, { prop: 'ata', label: 'ATA', minWidth: 140 }, { prop: 'status', label: '状态', minWidth: 110, slotName: 'status' }]
async function load() { loading.value = true; error.value = null; try { const result = await listOceanBookings({ page: page.value, size: pageSize.value, keyword: String(query.keyword || '') || undefined, status: (query.status || undefined) as OceanBookingStatus | undefined, pol: String(query.pol || '') || undefined, pod: String(query.pod || '') || undefined, soNo: String(query.soNo || '') || undefined } satisfies OceanBookingQuery); rows.value = result.records; total.value = result.total } catch (e) { error.value = getApiErrorDetails(e) } finally { loading.value = false } }
function search() { page.value = 1; void load() }; function open(id?: string) { void router.push(id ? `/ocean-bookings/${id}` : '/ocean-bookings/new') }
watch([page, pageSize], () => void load()); onMounted(load)