import type { LastMileOrderSummaryDto } from './api/lastMileOrders' import type { LastMileOrderListItem } from './types' const orderTypeLabels: Record = { ONE_CLICK_DROPSHIP: '一件代发', FIRST_LEG: '头程订单', RELABEL_APPLICATION: '换标下单', WAREHOUSE_TRANSFER: '仓储转运', RETURN_RELABEL: '退货换标', LOCAL_LOOSEBOARD: '本土散板', CARGO_DISCARD: '货物废弃订单', REJECTED: '拒收订单', EXPRESS: '快递订单', } const statusLabels: Record = { PENDING_REVIEW: '待审核', PENDING_RECEIPT: '待签收入库', PARTIALLY_RECEIVED: '部分入库', INBOUND_COMPLETED: '全部入库', WAIT_PDA_RECEIVING: '入库测量中', INBOUND_MEASURING: '入库测量中', WAIT_CUSTOMER_CONFIRMATION: '待客户确认实测', APPROVED: '审核通过', PENDING_ASSIGNMENT: '待分配', WAIT_RELABEL: '待换标', WAIT_FBA_DESTINATION: '待确认目的仓', READY_FOR_DISPATCH: '待创建出库单', WAIT_OUTBOUND: '待出库', ALLOCATED: '已分配库存', OUTBOUNDED: '已出库', RECEIVED: '已收货', IN_TRANSIT: '运输中', DESTINATION_ASSIGNED: '已分配目的仓', INBOUND_PLANNED: '已生成入库计划', PENDING_PROCESSING: '待处理', PROCESSING: '处理中', COMPLETED: '已完成', REJECTED: '已驳回', CANCELLED: '已取消', } const inboundPlanStatusLabels: Record = { PENDING_ASSIGNMENT: '待入库', ASSIGNED: '待入库', PDA_PENDING: '待入库', SIGNED: '已签收', PICKING: '拣货中', PARTIAL_INBOUND: '部分入库', COMPLETED: '全部入库', } const inventoryBusinessTypeLabels: Record = { IN_TRANSIT: '在途入账', STOCK_IN: '入库', STOCK_IN_TRANSIT_RELEASE: '在途库存转入', HOLD: '库存暂扣', RELEASE: '解除暂扣', ALLOCATE: '库存分配', UNALLOCATE: '取消分配', PICK: '拣货', SHIP: '出库', ADJUST: '库存调整', STOCKTAKE_ADJUST: '盘点调整', PALLET_ASSEMBLE: '组托', PALLET_DISASSEMBLE: '拆托', PALLET_SWAP: '换托', PALLET_UNBIND: '解托', } function text(value: unknown) { const normalized = String(value ?? '').trim() return normalized || '—' } function metric(value: number | null | undefined): number | '—' { return value != null && Number.isFinite(value) ? Number(value) : '—' } function yesNo(value: boolean | null | undefined) { return value == null ? '—' : value ? '是' : '否' } export function lastMileStatusLabel(value: unknown) { const code = String(value ?? '').trim() return statusLabels[code] || text(code) } export function inboundPlanStatusLabel(value: unknown) { const code = String(value ?? '').trim() return inboundPlanStatusLabels[code] || text(code) } export function packageDifferenceText(value: number | '—' | null | undefined) { if (value == null || value === '—' || !Number.isFinite(value)) return '—' return value > 0 ? `+${value}` : String(value) } export function relabelApplicationStatusLabel(value: unknown) { const code = String(value ?? '').trim() return ({ PENDING_REVIEW: '待审核', PENDING_PROCESSING: '待处理', PROCESSING: '处理中', CUSTOMER_CONFIRM_PENDING: '待客户确认', READY_FOR_OUTBOUND: '待出库', COMPLETED: '已完成', REJECTED: '已驳回', CANCELLED: '已取消' } as Record)[code] || text(code) } // 兼容原有单张换标单的汇总展示;子单使用完整业务状态。 export function relabelBusinessStatusLabel(value: unknown) { const code = String(value ?? '').trim() if (code === 'PROCESSING') return '处理中' if (!code || code === 'NOT_REQUIRED') return '—' return ['CUSTOMER_CONFIRM_PENDING', 'READY_FOR_OUTBOUND', 'COMPLETED'].includes(code) ? '换标完成' : '待处理' } export function lastMileOrderTypeLabel(value: unknown) { const code = String(value ?? '').trim() return orderTypeLabels[code] || text(code) } export function inventoryBusinessTypeLabel(value: unknown) { const code = String(value ?? '').trim() return inventoryBusinessTypeLabels[code] || text(code) } export function lastMileOrderReference(value: unknown, emptyLabel = '—') { const serverValue = value == null ? '' : String(value) return serverValue || emptyLabel } export function formatOverseasDateTime(value: unknown) { const raw = String(value ?? '').trim() if (!raw) return '—' const dateOnly = /^(\d{4})-(\d{2})-(\d{2})$/.exec(raw) const date = value instanceof Date ? new Date(value.getTime()) : typeof value === 'number' ? new Date(value) : dateOnly ? new Date(Number(dateOnly[1]), Number(dateOnly[2]) - 1, Number(dateOnly[3])) : new Date(raw) if (Number.isNaN(date.getTime())) return raw const pad = (part: number) => String(part).padStart(2, '0') return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}` } export function palletMergeLabel(value: unknown) { const code = String(value ?? '').trim() return ({ REQUIRED: '待合托', MERGED: '已合托' } as Record)[code] || (code ? text(code) : '未标记') } export function toLastMileOrderListItem(dto: LastMileOrderSummaryDto): LastMileOrderListItem { const warehouseTransfer = dto.orderType === 'WAREHOUSE_TRANSFER' return { id: String(dto.id), customerId: String(dto.customerId), sourceContainerBookingId: String(dto.sourceContainerBookingId ?? '').trim(), orderNo: lastMileOrderReference(dto.orderNo), sourceOrderNo: lastMileOrderReference(dto.sourceOrderNo, ''), businessType: dto.businessSource?.businessType || '', businessSource: text(dto.businessSource?.label), businessOrderNo: text(dto.businessSource?.businessOrderNo), externalBookingNo: text(dto.businessSource?.externalBookingNo), orderTypeCode: String(dto.orderType ?? '').trim(), currentStatusCode: String(dto.currentStatus ?? '').trim(), warning: dto.abnormal ? '异常' : '—', orderType: text(dto.orderTypeName || lastMileOrderTypeLabel(dto.orderType)), rejectedAt: '—', inboundCode: text(dto.inboundCode), lxCode: text(dto.lxCode), owner: text(dto.customerName), overseasWarehouseId: String(dto.overseasWarehouseId ?? '').trim(), overseasWarehouseCode: String(dto.overseasWarehouseCode ?? '').trim(), warehouse: text(dto.overseasWarehouseName), transferWarehouse: text(dto.transferWarehouseName), fbaWarehouse: text(dto.fbaWarehouseCode), containerNo: text(dto.containerNo), containerNode: text(dto.containerNode), abnormal: yesNo(dto.abnormal), held: yesNo(dto.detained), detained: Boolean(dto.detained), holdChargeable: Boolean(dto.holdChargeable), holdReason: String(dto.holdReason ?? '').trim(), manualNodeOverride: Boolean(dto.manualOverrideEnabled), version: Number(dto.version ?? 0), pallets: metric(dto.palletCount), cartons: metric(dto.packageCount), cartonDifference: warehouseTransfer ? metric(dto.packageDifference) : '—', volume: metric(dto.volumeCbm), quantity: metric(dto.productQuantity), volumeWeight: metric(dto.volumeWeightKg), portEta: formatOverseasDateTime(dto.estimatedArrivalAt), portAta: formatOverseasDateTime(dto.actualArrivalAt), estimatedWarehouseAt: String(dto.estimatedWarehouseAt ?? '').trim(), warehouseEta: formatOverseasDateTime(dto.estimatedWarehouseAt), inboundOrderNo: text(dto.inboundOrderNo), dispatchStatus: dto.dispatchStatus === 'SCHEDULED' ? '已排车' : '未排车', outboundOrderNo: text(dto.outboundOrderNo), dispatchOrderNo: text(dto.deliveryOrderNo), relabelOrderNo: text(dto.relabelOrderNo), relabelApplications: (dto.relabelApplications || []).map(application => ({ ...application, statusLabel: relabelApplicationStatusLabel(application.status) })), relabelStatusCode: String(dto.relabelStatus ?? '').trim(), relabelStatus: relabelBusinessStatusLabel(dto.relabelStatus), consolidated: palletMergeLabel(dto.palletMergeFlag), palletMergeFlag: String(dto.palletMergeFlag ?? '').trim(), palletMergeRelation: Array.isArray(dto.palletMergeInboundNos) && dto.palletMergeInboundNos.length ? dto.palletMergeInboundNos.map((value) => text(value)).join('、') : dto.palletMergeBatchId ? `批次 ${text(dto.palletMergeBatchId)}` : '—', status: lastMileStatusLabel(dto.currentStatus), internalRemark: text(dto.privateRemark), customerRemark: text(dto.customerRemark), warehouseRemark: text(dto.warehouseRemark), createdAt: formatOverseasDateTime(dto.createdAt), } }