293 lines
8.9 KiB
TypeScript
293 lines
8.9 KiB
TypeScript
import { overseasHttp } from '@/shared/api/overseasHttp'
|
|
import { ApiResponseError, unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http'
|
|
import type { InboundPlanDetailDto } from './inboundPlans'
|
|
|
|
export interface OverseasPageResult<T> {
|
|
records: T[]
|
|
page: number
|
|
size: number
|
|
total: number
|
|
pages: number
|
|
}
|
|
|
|
export type OverseasPagePayload<T> = Omit<OverseasPageResult<T>, 'page' | 'size' | 'total' | 'pages'> & {
|
|
page: number | string
|
|
size: number | string
|
|
total: number | string
|
|
pages: number | string
|
|
}
|
|
|
|
export function normalizeOverseasPage<T>(value: OverseasPagePayload<T>): OverseasPageResult<T> {
|
|
return { ...value, page: Number(value.page), size: Number(value.size), total: Number(value.total), pages: Number(value.pages) }
|
|
}
|
|
|
|
export interface LastMileOrderQuery {
|
|
page: number
|
|
size: number
|
|
orderNo?: string
|
|
orderType?: string
|
|
inboundCode?: string
|
|
containerNo?: string
|
|
currentStatus?: string
|
|
status?: string
|
|
warehouse?: string
|
|
sourceOrderNo?: string
|
|
transferWarehouseCode?: string
|
|
abnormal?: boolean
|
|
detained?: boolean
|
|
createdFrom?: string
|
|
createdTo?: string
|
|
}
|
|
|
|
export interface LastMileOrderSummaryDto {
|
|
id: string
|
|
customerId: string
|
|
sourceContainerBookingId?: string | null
|
|
orderNo: string
|
|
orderType?: string | null
|
|
orderTypeName?: string | null
|
|
inboundCode?: string | null
|
|
sourceOrderNo?: string | null
|
|
sourceInboundId?: string | null
|
|
customerName?: string | null
|
|
overseasWarehouseName?: string | null
|
|
transferWarehouseName?: string | null
|
|
transferWarehouseId?: string | null
|
|
transferWarehouseCode?: string | null
|
|
fbaWarehouseCode?: string | null
|
|
containerNo?: string | null
|
|
containerStatus?: string | null
|
|
abnormal?: boolean | null
|
|
detained?: boolean | null
|
|
palletCount?: number | null
|
|
packageCount?: number | null
|
|
volumeCbm?: number | null
|
|
productQuantity?: number | null
|
|
volumeWeightKg?: number | null
|
|
estimatedArrivalAt?: string | null
|
|
actualArrivalAt?: string | null
|
|
estimatedWarehouseAt?: string | null
|
|
inboundOrderNo?: string | null
|
|
/** Legacy read-only association retained for compatibility; absent from current service DTO. */
|
|
deliveryOrderNo?: string | null
|
|
outboundOrderNo?: string | null
|
|
relabelOrderNo?: string | null
|
|
relabelStatus?: string | null
|
|
palletMergeFlag?: string | null
|
|
/** Optional grouping facts returned by newer last-leg services. */
|
|
palletMergeBatchId?: string | null
|
|
palletMergeInboundNos?: string[] | null
|
|
currentStatus?: string | null
|
|
privateRemark?: string | null
|
|
customerRemark?: string | null
|
|
warehouseRemark?: string | null
|
|
createdAt?: string | null
|
|
}
|
|
|
|
export interface LastMileOrderDto extends LastMileOrderSummaryDto {
|
|
customerId: string
|
|
sourceOrderNo?: string | null
|
|
subOrderStatus?: string | null
|
|
updatedAt?: string | null
|
|
}
|
|
|
|
export interface LastMileCargoDto {
|
|
id: string
|
|
skuCode?: string | null
|
|
productNameZh?: string | null
|
|
productNameEn?: string | null
|
|
packageCount?: number | null
|
|
productQuantity?: number | null
|
|
palletCount?: number | null
|
|
grossWeightKg?: number | null
|
|
dimensionalWeightKg?: number | null
|
|
volumeCbm?: number | null
|
|
destinationWarehouseName?: string | null
|
|
fbaTrackingNo?: string | null
|
|
shipmentNo?: string | null
|
|
}
|
|
|
|
export interface LastMileStatusHistoryDto {
|
|
id: string
|
|
fromStatus?: string | null
|
|
toStatus?: string | null
|
|
remark?: string | null
|
|
createdAt?: string | null
|
|
}
|
|
|
|
export interface LastMileFeeDto {
|
|
id: string
|
|
customerId: string
|
|
orderId: string
|
|
feeItem: string
|
|
currency: string
|
|
amount: number
|
|
status: string
|
|
supplierDescription?: string | null
|
|
createdBy: string
|
|
createdAt: string
|
|
updatedAt: string
|
|
}
|
|
|
|
export interface LastMileOperationDto {
|
|
id: string
|
|
operationNode: string
|
|
operatorName: string
|
|
result: string
|
|
createdAt: string
|
|
}
|
|
|
|
export interface CreateLastMileFeePayload {
|
|
feeItem: string
|
|
currency: string
|
|
amount: number
|
|
status: string
|
|
supplierDescription?: string
|
|
}
|
|
|
|
export interface TransferDestinationPayload {
|
|
orderIds: string[]
|
|
warehouseId: string
|
|
warehouseCode: string
|
|
warehouseName: string
|
|
remark?: string
|
|
}
|
|
|
|
export interface ConvertInboundPlanPayload {
|
|
orderId: string
|
|
customerId: string
|
|
}
|
|
|
|
export interface ContainerPlanProgressQuery {
|
|
page: number
|
|
size: number
|
|
containerNo?: string
|
|
createdFrom?: string
|
|
createdTo?: string
|
|
}
|
|
|
|
export interface ContainerPlanProgressSummaryDto {
|
|
sourceContainerBookingId: string
|
|
containerNo: string | null
|
|
totalOrderCount: number
|
|
inboundCodeCount: number
|
|
missingInboundCodeCount: number
|
|
planCount: number
|
|
plannedInboundCodeCount: number
|
|
pendingPlanCount: number
|
|
plannedArrivalAt: string | null
|
|
allPlansReady: boolean
|
|
blockingReason: string | null
|
|
}
|
|
|
|
export interface ContainerPlanProgressItemDto {
|
|
orderId: string
|
|
customerId: string
|
|
orderNo: string | null
|
|
inboundCode: string | null
|
|
orderStatus: string
|
|
planId: string | null
|
|
planNo: string | null
|
|
planStatus: string | null
|
|
planValid: boolean
|
|
plannedArrivalAt: string | null
|
|
}
|
|
|
|
export interface ContainerPlanProgressDetailDto {
|
|
summary: ContainerPlanProgressSummaryDto
|
|
orders: ContainerPlanProgressItemDto[]
|
|
}
|
|
|
|
export interface ConvertContainerInboundPlanPayload {
|
|
sourceContainerBookingId: string
|
|
}
|
|
|
|
export interface LastMileOrderDetailDto {
|
|
order: LastMileOrderDto
|
|
cargo: LastMileCargoDto[]
|
|
statusHistory: LastMileStatusHistoryDto[]
|
|
fees: LastMileFeeDto[]
|
|
operationHistory: LastMileOperationDto[]
|
|
}
|
|
|
|
export async function listLastMileOrders(query: LastMileOrderQuery) {
|
|
const response = await overseasHttp.get<ApiEnvelope<OverseasPagePayload<LastMileOrderSummaryDto>>, ApiEnvelope<OverseasPagePayload<LastMileOrderSummaryDto>>>(
|
|
'/platform/v1/last-leg/orders',
|
|
{ params: query },
|
|
)
|
|
return normalizeOverseasPage(unwrapApiResponse(response))
|
|
}
|
|
|
|
export async function getLastMileOrder(orderId: string) {
|
|
const response = await overseasHttp.get<ApiEnvelope<LastMileOrderDetailDto>, ApiEnvelope<LastMileOrderDetailDto>>(
|
|
`/platform/v1/last-leg/orders/${encodeURIComponent(orderId)}`,
|
|
)
|
|
return unwrapApiResponse(response)
|
|
}
|
|
|
|
export async function downloadLastMileOrders(query: Partial<LastMileOrderQuery>) {
|
|
const { page: _page, size: _size, ...filters } = query
|
|
const params = Object.fromEntries(
|
|
Object.entries(filters).filter(([, value]) => value !== undefined && value !== null && value !== ''),
|
|
)
|
|
const blob = await overseasHttp.get<Blob, Blob>('/platform/v1/last-leg/orders/export', { params, responseType: 'blob' })
|
|
if (!blob.type.toLowerCase().includes('json')) return blob
|
|
let error: Partial<ApiEnvelope<unknown>>
|
|
try {
|
|
error = JSON.parse(await blob.text()) as Partial<ApiEnvelope<unknown>>
|
|
} catch {
|
|
throw new ApiResponseError('导出接口返回了非 CSV 内容', 'INVALID_EXPORT_RESPONSE')
|
|
}
|
|
throw new ApiResponseError(
|
|
error.message || '尾程订单导出失败',
|
|
error.code || 'INVALID_EXPORT_RESPONSE',
|
|
undefined,
|
|
error.data,
|
|
error.requestId,
|
|
error.traceId,
|
|
)
|
|
}
|
|
|
|
export async function createLastMileOrderFee(orderId: string, payload: CreateLastMileFeePayload) {
|
|
const response = await overseasHttp.post<ApiEnvelope<LastMileFeeDto>, ApiEnvelope<LastMileFeeDto>>(
|
|
`/platform/v1/last-leg/orders/${encodeURIComponent(orderId)}/fees`, payload,
|
|
)
|
|
return unwrapApiResponse(response)
|
|
}
|
|
|
|
export async function transferLastMileOrders(payload: TransferDestinationPayload) {
|
|
const response = await overseasHttp.put<ApiEnvelope<number>, ApiEnvelope<number>>(
|
|
'/platform/v1/last-leg/orders/destination', payload,
|
|
)
|
|
return unwrapApiResponse(response)
|
|
}
|
|
|
|
export async function convertLastMileOrderToInboundPlan(payload: ConvertInboundPlanPayload) {
|
|
const response = await overseasHttp.post<ApiEnvelope<unknown>, ApiEnvelope<unknown>>(
|
|
'/platform/v1/last-leg/inbound-plans/convert', payload,
|
|
)
|
|
return unwrapApiResponse(response)
|
|
}
|
|
|
|
export async function listContainerPlanProgress(query: ContainerPlanProgressQuery): Promise<OverseasPageResult<ContainerPlanProgressSummaryDto>> {
|
|
const response = await overseasHttp.get<ApiEnvelope<OverseasPagePayload<ContainerPlanProgressSummaryDto>>, ApiEnvelope<OverseasPagePayload<ContainerPlanProgressSummaryDto>>>(
|
|
'/platform/v1/last-leg/orders/container-summaries',
|
|
{ params: query },
|
|
)
|
|
return normalizeOverseasPage(unwrapApiResponse(response))
|
|
}
|
|
|
|
export async function getContainerPlanProgress(sourceContainerBookingId: string) {
|
|
const response = await overseasHttp.get<ApiEnvelope<ContainerPlanProgressDetailDto>, ApiEnvelope<ContainerPlanProgressDetailDto>>(
|
|
`/platform/v1/last-leg/orders/container-summaries/${encodeURIComponent(sourceContainerBookingId)}`,
|
|
)
|
|
return unwrapApiResponse(response)
|
|
}
|
|
|
|
export async function convertLastMileContainerToInboundPlans(payload: ConvertContainerInboundPlanPayload) {
|
|
const response = await overseasHttp.post<ApiEnvelope<InboundPlanDetailDto[]>, ApiEnvelope<InboundPlanDetailDto[]>>(
|
|
'/platform/v1/last-leg/inbound-plans/convert-container', payload,
|
|
)
|
|
return unwrapApiResponse(response)
|
|
}
|