Files
admin-web/src/modules/overseas-warehouse/lastMilePresentation.ts
T

117 lines
4.5 KiB
TypeScript
Raw Normal View History

2026-08-20 09:10:36 +08:00
import type { LastMileOrderSummaryDto } from './api/lastMileOrders'
import type { LastMileOrderListItem } from './types'
const orderTypeLabels: Record<string, string> = {
ONE_CLICK_DROPSHIP: '一件代发',
2026-08-22 12:24:15 +08:00
FIRST_LEG: '头程订单',
RELABEL_APPLICATION: '换标下单',
WAREHOUSE_TRANSFER: '仓储转运',
RETURN_RELABEL: '退货换标',
LOCAL_LOOSEBOARD: '本土散板',
2026-08-20 09:10:36 +08:00
REJECTED: '拒收订单',
EXPRESS: '快递订单',
}
const statusLabels: Record<string, string> = {
PENDING_ASSIGNMENT: '待分配',
DESTINATION_ASSIGNED: '已分配目的仓',
INBOUND_PLANNED: '已生成入库计划',
PENDING_PROCESSING: '待处理',
PROCESSING: '处理中',
COMPLETED: '已完成',
CANCELLED: '已取消',
}
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) : '—'
2026-08-20 09:10:36 +08:00
}
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 lastMileOrderTypeLabel(value: unknown) {
const code = String(value ?? '').trim()
return orderTypeLabels[code] || text(code)
}
2026-09-01 11:03:45 +08:00
export function lastMileOrderReference(value: unknown, emptyLabel = '—') {
const serverValue = value == null ? '' : String(value)
return serverValue || emptyLabel
}
2026-08-20 09:10:36 +08:00
export function formatOverseasDateTime(value: unknown) {
const raw = String(value ?? '').trim()
if (!raw) return '—'
2026-08-28 14:33:57 +08:00
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) : '未标记')
2026-08-20 09:10:36 +08:00
}
2026-08-21 11:20:09 +08:00
export function toLastMileOrderListItem(dto: LastMileOrderSummaryDto): LastMileOrderListItem {
2026-08-20 09:10:36 +08:00
return {
id: String(dto.id),
2026-08-21 11:20:09 +08:00
customerId: String(dto.customerId),
2026-08-27 16:34:32 +08:00
sourceContainerBookingId: String(dto.sourceContainerBookingId ?? '').trim(),
2026-09-01 11:03:45 +08:00
orderNo: lastMileOrderReference(dto.orderNo),
2026-08-20 09:10:36 +08:00
warning: dto.abnormal ? '异常' : '—',
2026-08-22 12:24:15 +08:00
orderType: text(dto.orderTypeName || lastMileOrderTypeLabel(dto.orderType)),
2026-08-20 09:10:36 +08:00
rejectedAt: '—',
inboundCode: text(dto.inboundCode),
owner: text(dto.customerName),
warehouse: text(dto.overseasWarehouseName),
transferWarehouse: text(dto.transferWarehouseName),
fbaWarehouse: text(dto.fbaWarehouseCode),
containerNo: text(dto.containerNo),
containerStatus: text(dto.containerStatus),
abnormal: yesNo(dto.abnormal),
held: yesNo(dto.detained),
pallets: metric(dto.palletCount),
cartons: metric(dto.packageCount),
volume: metric(dto.volumeCbm),
quantity: metric(dto.productQuantity),
volumeWeight: metric(dto.volumeWeightKg),
2026-08-20 09:10:36 +08:00
portEta: formatOverseasDateTime(dto.estimatedArrivalAt),
portAta: formatOverseasDateTime(dto.actualArrivalAt),
warehouseEta: formatOverseasDateTime(dto.estimatedWarehouseAt),
inboundOrderNo: text(dto.inboundOrderNo),
outboundOrderNo: text(dto.outboundOrderNo),
dispatchOrderNo: text(dto.deliveryOrderNo),
relabelOrderNo: text(dto.relabelOrderNo),
relabelStatus: lastMileStatusLabel(dto.relabelStatus),
2026-08-28 14:33:57 +08:00
consolidated: palletMergeLabel(dto.palletMergeFlag),
palletMergeFlag: String(dto.palletMergeFlag ?? '').trim(),
2026-08-31 14:42:28 +08:00
palletMergeRelation: Array.isArray(dto.palletMergeInboundNos) && dto.palletMergeInboundNos.length
? dto.palletMergeInboundNos.map((value) => text(value)).join('、')
2026-08-28 16:30:33 +08:00
: dto.palletMergeBatchId ? `批次 ${text(dto.palletMergeBatchId)}` : '—',
2026-08-20 09:10:36 +08:00
status: lastMileStatusLabel(dto.currentStatus),
internalRemark: text(dto.privateRemark),
customerRemark: text(dto.customerRemark),
warehouseRemark: text(dto.warehouseRemark),
2026-08-22 12:24:15 +08:00
createdAt: formatOverseasDateTime(dto.createdAt),
2026-08-20 09:10:36 +08:00
}
}