Files
admin-web/src/modules/overseas-warehouse/api/transportTasks.ts
T
2026-10-20 21:33:46 +08:00

27 lines
3.6 KiB
TypeScript

import { http, unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http'
import { normalizeTripDetail, type TripDetail, type PickupTask, type PickupCandidate, type PickupEvidence, type PickupPlan, type TripAssignment, type TripResourceRelease } from '@/modules/overseas-master-data'
export type TransportType = 'PICKUP' | 'LOCAL_TRUCK'
export const transportLabels = { DELIVERY: '仓库派送', PICKUP: '到仓取货', LOCAL_TRUCK: '本土卡车' }
export interface TransportDetail { dispatchNo: string; taskType: TransportType; execution: TripDetail; customerId: string | null; orderNo: string | null; pickups: PickupTask[]; completionEvidence: PickupEvidence[] }
export interface TruckCandidate { customerId: string; orderNo: string; origin: string; originAddress: string; destination: string; destinationAddress: string; palletCount: number; packageCount: number }
export interface TruckPlan { customerId: string; orderNo: string; warehouseId: string; plannedDepartureAt: string; expectedDriverEndAt: string; idempotencyKey: string }
type WireDetail = Omit<TransportDetail, 'execution'> & { execution: Parameters<typeof normalizeTripDetail>[0] }
const base = '/platform/v1/last-leg/dispatches/transport-tasks'
const path = (number: string) => `${base}/${encodeURIComponent(number)}`
async function get<T>(url: string, params?: object) { return unwrapApiResponse(await http.get<ApiEnvelope<T>, ApiEnvelope<T>>(url, { params })) }
async function post<T>(url: string, body: object) { return unwrapApiResponse(await http.post<ApiEnvelope<T>, ApiEnvelope<T>>(url, body)) }
const normalize = (value: WireDetail): TransportDetail => ({ ...value, execution: normalizeTripDetail(value.execution), pickups: value.pickups.map(row => ({ ...row, packageCount: Number(row.packageCount), actualPackages: row.actualPackages == null ? null : Number(row.actualPackages) })) })
export const getTransport = (number: string) => get<WireDetail>(path(number)).then(normalize)
export const pickupCandidates = () => get<{ records: PickupCandidate[]; total: number | string }>(`${base}/pickup-candidates`, { page: 1, size: 100 })
export const truckCandidates = () => get<TruckCandidate[]>(`${base}/truck-candidates`)
export const createTransportPickup = (body: PickupPlan) => post<WireDetail>(`${base}/pickup`, body).then(normalize)
export const createTransportTruck = (body: TruckPlan) => post<WireDetail>(`${base}/truck`, body).then(normalize)
export const assignTransport = (number: string, body: TripAssignment) => post<WireDetail>(`${path(number)}/assign`, body).then(normalize)
export const transportOccupancy = (number: string, kind: 'VEHICLE' | 'DRIVER', resourceIds: string[]) => resourceIds.length ? post<Array<{ resourceId: string; occupiedTripNo: string | null; available: boolean }>>(`${path(number)}/resource-occupancy`, { kind, resourceIds }) : Promise.resolve([])
export const cancelTransport = (number: string, body: object) => post(`${path(number)}/cancel`, body)
export const releaseTransport = (number: string, body: TripResourceRelease) => post(`${path(number)}/release`, body)
export const commandTransport = (number: string, suffix: string, body: object) => post(`${path(number)}/${suffix}`, body)
export async function uploadTransport(number: string, suffix: string, file: File) { const body = new FormData(); body.append('file', file); return post<PickupEvidence>(`${path(number)}/${suffix}/files`, body) }
export const downloadTransportEvidence = (number: string, fileId: string, row?: PickupTask): Promise<Blob> => http.get<Blob, Blob>(`${path(number)}/${row ? `pickup/${encodeURIComponent(row.customerId)}/${encodeURIComponent(row.transferNo)}` : 'truck'}/files/${encodeURIComponent(fileId)}`, { responseType: 'blob' })