Files
pda-overseas-uniapp/src/api/fulfillment.js
T

189 lines
8.2 KiB
JavaScript
Raw Normal View History

2026-10-14 11:43:44 +08:00
import { overseasRequest, overseasUpload, overseasDownload } from './overseas.js'
2026-09-01 14:23:55 +08:00
const DISPATCH_BASE = '/pda/v1/last-leg/dispatches'
const OUTBOUND_BASE = '/pda/v1/last-leg/outbound-tasks'
2026-09-28 17:26:50 +08:00
const CARGO_DISCARD_BASE = '/pda/v1/last-leg/cargo-discards'
2026-09-01 14:23:55 +08:00
const encoded = (value) => encodeURIComponent(String(value || '').trim())
function asList(value) {
if (Array.isArray(value)) return value
if (Array.isArray(value?.records)) return value.records
if (Array.isArray(value?.items)) return value.items
return []
}
function count(value) {
const number = Number(value || 0)
return Number.isFinite(number) ? Math.max(0, number) : 0
}
export function normalizeDispatchTask(value) {
return {
...value,
taskNo: String(value?.taskNo || ''),
dispatchNo: String(value?.dispatchNo || ''),
vehiclePlate: String(value?.vehiclePlate || ''),
tripNo: String(value?.tripNo || ''),
tripRecordVersion: value?.tripRecordVersion == null ? null : String(value.tripRecordVersion),
tripDispatchCount: count(value?.tripDispatchCount),
driverWarning: String(value?.driverWarning || ''),
2026-09-01 14:23:55 +08:00
status: String(value?.status || ''),
2026-09-02 14:01:08 +08:00
canDepart: value?.canDepart === true,
canPick: value?.canPick === true,
pickBlockReason: String(value?.pickBlockReason || ''),
2026-09-02 14:01:08 +08:00
departBlockReason: String(value?.departBlockReason || ''),
2026-09-01 14:23:55 +08:00
items: asList(value?.items).map((item) => ({
...item,
dispatchItemId: String(item?.dispatchItemId || ''),
palletNo: String(item?.palletNo || ''),
destinationWarehouseCode: String(item?.destinationWarehouseCode || ''),
destinationWarehouseName: String(item?.destinationWarehouseName || ''),
fbaWarehouseCode: String(item?.fbaWarehouseCode || ''),
warehouseRouteLabel: String(item?.warehouseRouteLabel || ''),
scheduledPackages: count(item?.scheduledPackages),
pickedPackages: count(item?.pickedPackages),
2026-10-08 15:34:47 +08:00
returnCartons: asList(item?.returnCartons).map((carton) => ({ ...carton, id: String(carton.id || ''), cartonMark: String(carton.cartonMark || ''), productQuantity: count(carton.productQuantity) })),
2026-09-01 14:23:55 +08:00
positions: asList(item?.positions).map((position) => ({
...position,
id: String(position?.id || ''),
availablePackages: count(position?.availablePackages ?? (count(item?.plannedPackages ?? item?.packages ?? item?.packageCount) - count(item?.pickedPackages ?? item?.pickedPackageCount))),
allocatedPackages: count(position?.allocatedPackages),
pickedPackages: count(position?.pickedPackages)
}))
}))
}
}
export function normalizeOutboundTask(value) {
const header = value?.task || value || {}
return {
...header,
taskNo: String(header?.taskNo || ''),
outboundNo: String(header?.outboundNo || ''),
2026-09-29 20:52:44 +08:00
outboundType: String(header?.outboundType || ''),
2026-09-01 14:23:55 +08:00
status: String(header?.status || ''),
items: asList(value?.items).map((item) => ({
...item,
outboundPalletItemId: String(item?.outboundPalletItemId || ''),
palletNo: String(item?.palletNo || ''),
plannedPackages: count(item?.packageCount),
pickedPackages: count(item?.pickedPackageCount),
positions: asList(item?.positions).map((position) => ({
...position,
inventoryPositionId: String(position?.inventoryPositionId || ''),
palletNo: String(position?.palletNo || item?.palletNo || ''),
cartonMark: String(position?.cartonMark || ''),
skuCode: String(position?.skuCode || position?.sku || ''),
inboundCode: String(position?.inboundCode || ''),
availablePackages: count(position?.availablePackages),
pickedPackages: count(position?.pickedPackages)
}))
}))
}
}
export async function listDispatchTasks(status = '') {
const suffix = status ? `?status=${encoded(status)}` : ''
return asList(await overseasRequest('GET', `${DISPATCH_BASE}${suffix}`)).map(normalizeDispatchTask)
}
export async function getDispatchTask(dispatchNo) {
return normalizeDispatchTask(await overseasRequest('GET', `${DISPATCH_BASE}/${encoded(dispatchNo)}`))
}
export function pickDispatchItem(dispatchNo, dispatchItemId, request) {
return overseasRequest('POST', `${DISPATCH_BASE}/${encoded(dispatchNo)}/items/${encoded(dispatchItemId)}/pick`, request)
}
export function completeDispatchPicking(dispatchNo, request) {
return overseasRequest('POST', `${DISPATCH_BASE}/${encoded(dispatchNo)}/complete`, request)
}
export function departDispatch(dispatchNo, request) {
return overseasRequest('POST', `${DISPATCH_BASE}/${encoded(dispatchNo)}/depart`, request)
}
export function tripDepartureRequest(task, idempotencyKey) {
if (!task?.tripNo || task.tripRecordVersion == null || !/^\d+$/.test(String(task.tripRecordVersion))) {
throw new Error('车次信息不完整,请刷新任务后再发车')
}
return { recordVersion: String(task.tripRecordVersion), idempotencyKey, remark: '海外 PDA 整车核平后发车' }
}
2026-09-01 14:23:55 +08:00
export async function listOutboundTasks(status = '') {
const suffix = status ? `?status=${encoded(status)}` : ''
return asList(await overseasRequest('GET', `${OUTBOUND_BASE}${suffix}`)).map(normalizeOutboundTask)
}
export async function getOutboundTask(taskNo) {
return normalizeOutboundTask(await overseasRequest('GET', `${OUTBOUND_BASE}/${encoded(taskNo)}`))
}
export function resolveOutboundTask(businessNo) {
return overseasRequest('GET', `${OUTBOUND_BASE}/resolve/${encoded(businessNo)}`)
}
2026-09-01 14:23:55 +08:00
export function pickOutboundTask(taskNo, request) {
return overseasRequest('POST', `${OUTBOUND_BASE}/${encoded(taskNo)}/pick`, request)
}
2026-09-15 21:05:09 +08:00
export function pickOutboundPallet(taskNo, palletNo, request) {
return overseasRequest('POST', `${OUTBOUND_BASE}/${encoded(taskNo)}/pallets/${encoded(palletNo)}/pick`, request)
}
2026-09-29 20:52:44 +08:00
export function outboundPickPayload(item, position, packages, scannedCode = '') {
const skuScan = item.skuCode && scannedCode === item.skuCode
return {
outboundPalletItemId: item.outboundPalletItemId,
inventoryPositionId: position.inventoryPositionId || null,
packages: Number(packages),
2026-10-09 20:39:46 +08:00
...(item.returnSkuQuantity != null ? { productQuantity: Number(item.returnSkuQuantity) } : {}),
2026-09-29 20:52:44 +08:00
cartonMarks: skuScan ? [] : position.cartonMark ? [position.cartonMark] : [],
...(skuScan ? { skuCode: item.skuCode } : {})
}
}
2026-09-01 14:23:55 +08:00
export function completeOutboundTask(taskNo, request) {
return overseasRequest('POST', `${OUTBOUND_BASE}/${encoded(taskNo)}/complete`, request)
}
2026-09-28 17:26:50 +08:00
export function normalizeCargoDiscardTask(value) {
const task = value || {}
return {
...task,
discardNo: String(task?.discardNo || ''),
2026-10-14 17:41:11 +08:00
outboundNo: String(task?.outboundNo || ''),
2026-09-28 17:26:50 +08:00
palletNo: String(task?.palletNo || ''),
2026-10-14 17:41:11 +08:00
scanMode: task?.scanMode === 'CARTON' ? 'CARTON' : 'PALLET',
cartonMarks: asList(task?.cartonMarks).map(String),
2026-09-28 17:26:50 +08:00
status: String(task?.status || 'PENDING'),
skus: asList(task?.skus).map((sku) => ({
...sku,
itemId: String(sku?.itemId || ''),
skuCode: String(sku?.skuCode || ''),
productName: String(sku?.productName || ''),
plannedPackages: count(sku?.plannedPackages),
actualPackages: sku?.actualPackages == null ? null : count(sku.actualPackages),
status: String(sku?.status || 'PENDING')
}))
}
}
export async function listCargoDiscardTasks() {
return asList(await overseasRequest('GET', CARGO_DISCARD_BASE)).map(normalizeCargoDiscardTask)
}
2026-10-14 17:41:11 +08:00
export async function resolveCargoDiscardPallet(palletNo, discardNo) {
return normalizeCargoDiscardTask(await overseasRequest('POST', `${CARGO_DISCARD_BASE}/resolve`, { palletNo, ...(discardNo ? { discardNo } : {}) }))
2026-09-28 17:26:50 +08:00
}
2026-10-14 17:41:11 +08:00
export async function confirmCargoDiscard(discardNo, palletNo, lines, photoFileIds, scannedCartonMarks = [], confirmAllCartons = false) {
return normalizeCargoDiscardTask(await overseasRequest('POST', `${CARGO_DISCARD_BASE}/${encoded(discardNo)}/pallets/${encoded(palletNo)}/confirm`, { lines, photoFileIds, scannedCartonMarks, confirmAllCartons }))
2026-09-28 17:26:50 +08:00
}
2026-10-14 11:43:44 +08:00
const discardPhotoPath = (discardNo, palletNo) => `${CARGO_DISCARD_BASE}/${encoded(discardNo)}/pallets/${encoded(palletNo)}/photos/files`
export const listCargoDiscardPhotos = (discardNo, palletNo) => overseasRequest('GET', discardPhotoPath(discardNo, palletNo))
export const uploadCargoDiscardPhoto = (discardNo, palletNo, filePath) => overseasUpload(discardPhotoPath(discardNo, palletNo), filePath)
export const downloadCargoDiscardPhoto = (discardNo, palletNo, fileId) => overseasDownload(`${discardPhotoPath(discardNo, palletNo)}/${encoded(fileId)}/download`, { expectedContentTypePrefix: 'image/' })