feat: add overseas warehouse location management

This commit is contained in:
2026-09-22 09:38:56 +08:00
parent 3cb8b5b70e
commit 358ad38335
7 changed files with 185 additions and 6 deletions
@@ -53,6 +53,7 @@ export interface InboundPlanDetailDto {
customerName?: string | null
orderType?: string | null
containerNo?: string | null
overseasWarehouseId?: string | null
overseasWarehouseCode?: string | null
overseasWarehouseName?: string | null
status?: string | null
@@ -67,7 +68,7 @@ export interface InboundPlanDetailDto {
updatedAt?: string | null
remark?: string | null
lines: Array<{ id: string; orderId: string; inboundCode?: string | null; fbaWarehouseCode?: string | null; destinationWarehouseId?: string | null; destinationWarehouseCode?: string | null; destinationWarehouseName?: string | null; grossWeightKg?: number | null; netWeightKg?: number | null; volumeCbm?: number | null; requiredPackageCount: number; plannedPalletCount: number }>
pallets: Array<{ id: string; palletNo?: string | null; destinationWarehouseId?: string | null; destinationWarehouseCode?: string | null; destinationWarehouseName?: string | null; capacityCbm?: number | null; allocatedVolumeCbm?: number | null; sequenceNo: number; warehousePalletId?: string | null; warehouseLocationId?: string | null; warehouseResourceLockId?: string | null; assignmentStatus?: string | null; lockedAt?: string | null; actualVolumeCbm?: number | null; actualPackageCount: number }>
pallets: Array<{ id: string; palletNo?: string | null; destinationWarehouseId?: string | null; destinationWarehouseCode?: string | null; destinationWarehouseName?: string | null; capacityCbm?: number | null; allocatedVolumeCbm?: number | null; sequenceNo: number; warehousePalletId?: string | null; warehouseLocationId?: string | null; warehouseLocationCode?: string | null; warehouseLocationType?: string | null; warehouseLocationStatus?: string | null; sharedOverflow?: boolean | null; assignmentStatus?: string | null; lockedAt?: string | null; actualVolumeCbm?: number | null; actualPackageCount: number; version?: number }>
allocations: Array<{ lineId: string; palletId: string; palletNo: string; palletOwnerPlanNo: string; palletOwnedByCurrentPlan: boolean; allocatedVolumeCbm?: number | null; plannedPackageCount: number; countedPackageCount: number; pickedPackageCount: number; actualVolumeCbm?: number | null; status?: string | null; version: number }>
}
@@ -79,3 +80,27 @@ export async function listInboundPlans(query: InboundPlanQuery) {
export async function getInboundPlan(planNo: string, customerId: string) {
return unwrapApiResponse(await overseasHttp.get<ApiEnvelope<InboundPlanDetailDto>, ApiEnvelope<InboundPlanDetailDto>>(`/platform/v1/last-leg/inbound-plans/${encodeURIComponent(planNo)}`, { params: { customerId } }))
}
export interface PlatformInventoryMoveRequest {
overseasWarehouseId: string
sourcePalletCode: string
targetLocationCode: string
expectedPalletVersion: number
reason: string
idempotencyKey: string
}
export interface PlatformInventoryMoveResult {
commandId: string
status: string
canMove?: boolean
blockReason?: string | null
sourceLocationCode?: string | null
targetLocationCode?: string | null
sharedOverflow?: boolean | null
}
export async function moveInboundPallet(payload: PlatformInventoryMoveRequest) {
const response = await overseasHttp.post<ApiEnvelope<PlatformInventoryMoveResult>, ApiEnvelope<PlatformInventoryMoveResult>>('/platform/v1/last-leg/inventory-moves', payload, { headers: { 'Idempotency-Key': payload.idempotencyKey } })
return unwrapApiResponse(response)
}
@@ -0,0 +1,64 @@
import { overseasHttp } from '@/shared/api/overseasHttp'
import { unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http'
import { normalizeOverseasPage, type OverseasPagePayload } from './lastMileOrders'
export type OverseasLocationType = 'VIRTUAL' | 'NORMAL' | 'SHARED_OVERFLOW'
export type OverseasLocationStatus = 'ACTIVE' | 'IDLE' | 'OCCUPIED' | 'INACTIVE' | 'DISABLED'
export interface OverseasLocationDto {
id: string
warehouseId: string
warehouseCode?: string | null
warehouseName?: string | null
zoneCode: string
zoneName?: string | null
locationCode: string
locationName?: string | null
locationType: OverseasLocationType
sharedOverflow: boolean
status: OverseasLocationStatus
maxLoadKg?: number | string | null
occupiedPalletCount?: number | null
version: number
remark?: string | null
createdAt?: string | null
updatedAt?: string | null
}
export interface SaveOverseasLocationPayload {
zoneCode: string
locationCode: string
locationType: 'NORMAL'
maxLoadKg: number
status: 'ACTIVE' | 'INACTIVE'
remark?: string | null
}
export interface OverseasLocationQuery { page?: number; size?: number; zoneCode?: string; keyword?: string; locationType?: OverseasLocationType | ''; status?: OverseasLocationStatus | '' }
function base(warehouseId: string) { return `/platform/v1/warehouse-admin/${encodeURIComponent(warehouseId)}/locations` }
export async function listOverseasLocations(warehouseId: string, query: OverseasLocationQuery = {}) {
const response = await overseasHttp.get<ApiEnvelope<OverseasPagePayload<OverseasLocationDto>>, ApiEnvelope<OverseasPagePayload<OverseasLocationDto>>>(base(warehouseId), { params: { page: query.page ?? 1, size: query.size ?? 20, ...query } })
return normalizeOverseasPage(unwrapApiResponse(response))
}
export async function createOverseasLocation(warehouseId: string, payload: SaveOverseasLocationPayload) {
const response = await overseasHttp.post<ApiEnvelope<string>, ApiEnvelope<string>>(base(warehouseId), payload)
return unwrapApiResponse(response)
}
export async function updateOverseasLocation(warehouseId: string, locationId: string, payload: SaveOverseasLocationPayload & { version: number }) {
const response = await overseasHttp.put<ApiEnvelope<null>, ApiEnvelope<null>>(`${base(warehouseId)}/${encodeURIComponent(locationId)}`, payload)
return unwrapApiResponse(response)
}
export async function changeOverseasLocationStatus(warehouseId: string, locationId: string, payload: SaveOverseasLocationPayload & { version: number }) {
const response = await overseasHttp.put<ApiEnvelope<null>, ApiEnvelope<null>>(`${base(warehouseId)}/${encodeURIComponent(locationId)}`, payload)
return unwrapApiResponse(response)
}
export async function deleteOverseasLocation(warehouseId: string, locationId: string, version: number) {
const response = await overseasHttp.delete<ApiEnvelope<null>, ApiEnvelope<null>>(`${base(warehouseId)}/${encodeURIComponent(locationId)}`, { params: { version } })
return unwrapApiResponse(response)
}