214 lines
8.8 KiB
TypeScript
214 lines
8.8 KiB
TypeScript
import type { LastMileOrderSummaryDto } from './api/lastMileOrders'
|
|
import type { LastMileOrderListItem } from './types'
|
|
|
|
const orderTypeLabels: Record<string, string> = {
|
|
ONE_CLICK_DROPSHIP: '一件代发',
|
|
FIRST_LEG: '头程订单',
|
|
RELABEL_APPLICATION: '换标下单',
|
|
WAREHOUSE_TRANSFER: '仓储转运',
|
|
RETURN_RELABEL: '退货换标',
|
|
LOCAL_LOOSEBOARD: '本土散板',
|
|
CARGO_DISCARD: '货物废弃订单',
|
|
REJECTED: '拒收订单',
|
|
EXPRESS: '快递订单',
|
|
}
|
|
|
|
const statusLabels: Record<string, string> = {
|
|
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<string, string> = {
|
|
PENDING_ASSIGNMENT: '待入库',
|
|
ASSIGNED: '待入库',
|
|
PDA_PENDING: '待入库',
|
|
SIGNED: '已签收',
|
|
PICKING: '拣货中',
|
|
PARTIAL_INBOUND: '部分入库',
|
|
COMPLETED: '全部入库',
|
|
}
|
|
|
|
const inventoryBusinessTypeLabels: Record<string, string> = {
|
|
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<string, string>)[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<string, string>)[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: warehouseTransfer ? (dto.warehouseTransferQuantity?.receivedPieceCount ?? '未记录') : metric(dto.productQuantity),
|
|
declaredPieces: warehouseTransfer ? (dto.warehouseTransferQuantity?.declaredPieceCount ?? '未记录') : '—',
|
|
receivedPieces: warehouseTransfer ? (dto.warehouseTransferQuantity?.receivedPieceCount ?? '未记录') : '—',
|
|
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),
|
|
}
|
|
}
|