Files
admin-web/src/modules/overseas-warehouse/api/dispatches.ts
T
2026-09-18 11:41:27 +08:00

263 lines
9.9 KiB
TypeScript

import { overseasHttp } from '@/shared/api/overseasHttp'
import { unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http'
import { normalizeOverseasPage, type OverseasPagePayload } from './lastMileOrders'
export interface DispatchQuery {
page: number
size: number
dispatchNo?: string
vehiclePlate?: string
status?: string
fbaAppointmentNo?: string
}
export interface DispatchPalletCandidateDto {
planId?: string | null
planPalletId?: string | null
warehousePalletId?: string | null
orderId: string
customerId?: string | null
customerName?: string | null
planNo?: string | null
orderType?: string | null
volumeWeightKg?: number | null
grossWeightKg?: number | null
containerNo?: string | null
appointmentAt?: string | null
expectedLoadingAt?: string | null
overseasWarehouseId?: string | null
overseasWarehouseCode?: string | null
overseasWarehouseName?: string | null
orderNo?: string | null
orderRefs?: string | null
inboundCode?: string | null
palletNo?: string | null
destinationWarehouseId?: string | null
destinationWarehouseCode?: string | null
destinationWarehouseName?: string | null
fbaWarehouseCode?: string | null
packageCount?: number | null
volumeCbm?: number | null
sourceStage?: 'PLAN' | 'RECEIVED' | 'RELABEL' | null
cartonMarks?: string | null
relabelCartonMarks?: string | null
destinationType?: 'FBA' | 'PRIVATE' | null
deliveryAddress?: string | null
postalCode?: string | null
contactName?: string | null
contactPhone?: string | null
}
export interface DispatchCandidateQuery {
planIds?: string
orderNo?: string
fbaWarehouseCode?: string
sourceStage?: 'PLAN' | 'RECEIVED' | 'RELABEL'
draftToken?: string
}
export interface DispatchDraftContainerDto { id: string; capacity: number; palletIds: string[] }
export interface DispatchDraftDto { draftToken: string; containers?: DispatchDraftContainerDto[] }
export interface PreArrangeDispatchPayload {
planPalletIds: string[]
fbaAppointmentNo?: string
fbaAppointmentStatus?: string
vehicleAppointmentStatus?: string
draftToken?: string
relabelNo?: string
}
export interface DispatchSummaryDto {
id: string
dispatchNo: string
vehiclePlate?: string | null
driverName?: string | null
driverPhone?: string | null
carrierName?: string | null
orderNos?: string | null
route?: string | null
overseasWarehouseId?: string | null
overseasWarehouseName?: string | null
departAt?: string | null
fbaAppointmentNo?: string | null
fbaAppointmentStatus?: string | null
vehicleAppointmentStatus?: string | null
estimatedArrivalAt?: string | null
status?: string | null
itemCount?: number | null
palletCount?: number | null
packageCount?: number | null
pickedPackageCount?: number | null
shippedPackageCount?: number | null
remainingPackageCount?: number | null
partialCompletionReason?: string | null
createdAt?: string | null
items?: DispatchItemDto[]
bolLines?: DispatchBolLineDto[]
}
export interface DispatchBolLineDto {
containerNo?: string | null
palletNo?: string | null
fbaWarehouseCode?: string | null
destinationWarehouseName?: string | null
warehouseNo?: string | null
fbaShipmentId?: string | null
poReferenceNo?: string | null
packageCount: number
}
export interface UpdateDispatchPayload {
vehiclePlate?: string | null
driverName?: string | null
driverPhone?: string | null
carrierName?: string | null
departAt?: string | null
fbaAppointmentNo?: string | null
fbaAppointmentStatus?: string | null
vehicleAppointmentStatus?: string | null
estimatedArrivalAt?: string | null
}
export interface DispatchItemDto {
id: string
planPalletId: string
warehousePalletId?: string | null
palletNo?: string | null
overseasWarehouseId?: string | null
overseasWarehouseName?: string | null
orderNo?: string | null
orderRefs?: string | null
inboundCode?: string | null
destinationWarehouseCode?: string | null
destinationWarehouseName?: string | null
fbaWarehouseCode?: string | null
packageCount?: number | null
volumeCbm?: number | null
sourceStage?: string | null
}
export async function listDispatches(query: DispatchQuery) {
const response = await overseasHttp.get<ApiEnvelope<OverseasPagePayload<DispatchSummaryDto>>, ApiEnvelope<OverseasPagePayload<DispatchSummaryDto>>>(
'/platform/v1/last-leg/dispatches',
{ params: query },
)
return normalizeOverseasPage(unwrapApiResponse(response))
}
export async function getDispatch(dispatchNo: string) {
const response = await overseasHttp.get<ApiEnvelope<DispatchSummaryDto>, ApiEnvelope<DispatchSummaryDto>>(
`/platform/v1/last-leg/dispatches/${encodeURIComponent(dispatchNo)}`,
)
return unwrapApiResponse(response)
}
export async function getDispatchBolPdf(dispatchNo: string) {
return overseasHttp.get<Blob, Blob>(
`/platform/v1/last-leg/dispatches/${encodeURIComponent(dispatchNo)}/prints/bol`,
{ responseType: 'blob' },
)
}
export async function updateDispatch(dispatchNo: string, payload: UpdateDispatchPayload) {
const response = await overseasHttp.put<ApiEnvelope<DispatchSummaryDto>, ApiEnvelope<DispatchSummaryDto>>(
`/platform/v1/last-leg/dispatches/${encodeURIComponent(dispatchNo)}`, payload,
)
return unwrapApiResponse(response)
}
export async function cancelDispatch(dispatchNo: string) {
const response = await overseasHttp.delete<ApiEnvelope<null>, ApiEnvelope<null>>(
`/platform/v1/last-leg/dispatches/${encodeURIComponent(dispatchNo)}`,
)
return unwrapApiResponse(response)
}
export async function removeDispatchItem(dispatchNo: string, itemId: string) {
const response = await overseasHttp.delete<ApiEnvelope<DispatchSummaryDto>, ApiEnvelope<DispatchSummaryDto>>(
`/platform/v1/last-leg/dispatches/${encodeURIComponent(dispatchNo)}/items/${encodeURIComponent(itemId)}`,
)
return unwrapApiResponse(response)
}
export async function listDispatchCandidates(query: DispatchCandidateQuery) {
const response = await overseasHttp.get<ApiEnvelope<DispatchPalletCandidateDto[]>, ApiEnvelope<DispatchPalletCandidateDto[]>>(
'/platform/v1/last-leg/dispatches/candidates',
{ params: query },
)
return unwrapApiResponse(response)
}
export async function preArrangeDispatch(payload: PreArrangeDispatchPayload) {
const response = await overseasHttp.post<ApiEnvelope<DispatchSummaryDto>, ApiEnvelope<DispatchSummaryDto>>(
'/platform/v1/last-leg/dispatches/pre-arrange',
payload,
)
return unwrapApiResponse(response)
}
export async function lockDispatchDraftPallet(planPalletId: string, draftToken: string, draftContainerId?: string) {
const response = await overseasHttp.post<ApiEnvelope<null>, ApiEnvelope<null>>(
'/platform/v1/last-leg/dispatches/draft-locks/lock', { planPalletId, draftToken, ...(draftContainerId ? { draftContainerId } : {}) },
)
return unwrapApiResponse(response)
}
export async function listDispatchDrafts() {
const response = await overseasHttp.get<ApiEnvelope<DispatchDraftDto[]>, ApiEnvelope<DispatchDraftDto[]>>('/platform/v1/last-leg/dispatches/drafts')
return unwrapApiResponse(response)
}
export async function createDispatchDraftContainer(draftToken: string, capacity: number) {
const response = await overseasHttp.post<ApiEnvelope<DispatchDraftContainerDto>, ApiEnvelope<DispatchDraftContainerDto>>('/platform/v1/last-leg/dispatches/drafts/containers', { draftToken, capacity })
return unwrapApiResponse(response)
}
export async function deleteDispatchDraftContainer(draftToken: string, containerId: string) {
const response = await overseasHttp.delete<ApiEnvelope<null>, ApiEnvelope<null>>(`/platform/v1/last-leg/dispatches/drafts/${encodeURIComponent(draftToken)}/containers/${encodeURIComponent(containerId)}`)
return unwrapApiResponse(response)
}
export async function unlockDispatchDraftPallet(planPalletId: string, draftToken: string) {
const response = await overseasHttp.post<ApiEnvelope<null>, ApiEnvelope<null>>(
'/platform/v1/last-leg/dispatches/draft-locks/unlock', { planPalletId, draftToken },
)
return unwrapApiResponse(response)
}
export async function releaseDispatchDraft(draftToken: string) {
const response = await overseasHttp.post<ApiEnvelope<null>, ApiEnvelope<null>>(
'/platform/v1/last-leg/dispatches/draft-locks/release', { draftToken },
)
return unwrapApiResponse(response)
}
export interface TransferDeliveryItem { deliveryNo: string; deliveryStatus: string; destinationWarehouseId?: string | null; destinationWarehouseCode?: string | null; destinationWarehouseName?: string | null; palletCount: number; packageCount: number }
export interface TransferDeliveryResult { dispatchNo: string; outboundNo: string; outboundStatus: string; palletCount: number; packageCount: number; deliveries: TransferDeliveryItem[]; replayed: boolean }
export interface TransferDeliveryPayload {
idempotencyKey: string
plannedDeliveryAt: string
deliveryMethod: string
waybillNo?: string
carrierName?: string
pickupMethod: string
loadingType: string
vehicleType?: string
vehicleSize?: string
driverName?: string
driverPhone?: string
vehiclePlate?: string
appointmentAccount?: string
sellerName?: string
remark?: string
fees: Array<{ feeType: string; feeName: string; direction: 'RECEIVABLE' | 'PAYABLE'; currency: 'CNY' | 'USD'; amount: number
supplierId?: string; supplierName?: string; supplierCategory?: string; settlementMode?: 'ON_ACCOUNT' | 'DIRECT_PAID'
paidAt?: string; paymentMethod?: 'ONLINE' | 'BANK_TRANSFER' | 'CASH' | 'OTHER'; paymentReferenceNo?: string
paymentVoucherFileIds?: string[]; chargeableQuantity?: number; quantityUnit?: string; unitPrice?: number
periodStart?: string; periodEnd?: string; remark?: string }>
}
export async function transferDispatchToDelivery(dispatchNo: string, payload: TransferDeliveryPayload) {
const response = await overseasHttp.post<ApiEnvelope<TransferDeliveryResult>, ApiEnvelope<TransferDeliveryResult>>(
`/platform/v1/last-leg/dispatches/${encodeURIComponent(dispatchNo)}/transfer-delivery`, payload,
)
return unwrapApiResponse(response)
}