优化
This commit is contained in:
@@ -2,7 +2,7 @@ import { http, unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http'
|
||||
import { normalizeOverseasPage, type OverseasPagePayload } from './lastMileOrders'
|
||||
|
||||
export interface CargoDiscardQuery { page: number; size: number; customerId?: string; discardNo?: string; inboundCode?: string; overseasWarehouseId?: string; status?: string }
|
||||
export interface CargoDiscardSummary { id: string; customerId?: string | null; discardNo: string; outboundNo?: string | null; inboundCodes?: string | null; overseasWarehouseId?: string | null; overseasWarehouseName?: string | null; totalPackages?: number | null; totalFee?: number | string | null; currency?: string | null; status?: string | null; createdBy?: string | null; createdAt?: string | null; reviewedAt?: string | null }
|
||||
export interface CargoDiscardSummary { skuCodes?: string[]; skuCount?: number; requestedPackages?: number; actualPackages?: number | null; id: string; customerId?: string | null; discardNo: string; outboundNo?: string | null; inboundCodes?: string | null; overseasWarehouseId?: string | null; overseasWarehouseName?: string | null; totalPackages?: number | null; totalFee?: number | string | null; currency?: string | null; status?: string | null; createdBy?: string | null; createdAt?: string | null; reviewedAt?: string | null }
|
||||
export interface CargoDiscardItem { quantityUnit?: string | null; actualDiscardPackages?: number | null; pdaStatus?: string | null; cartonMarks?: string[]; id: string; orderId?: string | null; inboundCode?: string | null; skuCode?: string | null; productName?: string | null; availablePackagesSnapshot?: number | null; discardPackages?: number | null }
|
||||
export interface CargoDiscardStatistics { orderCount: number; skuCount: number; requestedPackages: number; actualPackages: number | null; requestedPieces: number | null; actualPieces: number | null; palletCount: number | null }
|
||||
export async function getCargoDiscardStatistics(query: CargoDiscardQuery) {
|
||||
|
||||
@@ -42,6 +42,36 @@ export interface InventoryDashboardDto {
|
||||
procurementPackages: number
|
||||
}
|
||||
|
||||
export interface InventoryPieceGroup {
|
||||
customerId: string
|
||||
warehouseId: string
|
||||
destinationCode: string | null
|
||||
anchorSkuCode: string | null
|
||||
availablePieceCount: number | string | null
|
||||
knownAvailablePieceCount: number | string
|
||||
unknownCartonCount: number | string
|
||||
availableCartonCount: number | string
|
||||
availablePalletCount: number | string
|
||||
skuContents: { skuCode: string; quantity: number | string }[]
|
||||
cartons: { cartonMark: string; inventoryPositionId: string; palletId: string | null; quantity: number | string | null; items: { skuCode: string; quantity: number | string }[] }[]
|
||||
}
|
||||
export interface InventoryPieceProjection {
|
||||
availablePieceCount: number | string | null
|
||||
knownAvailablePieceCount: number | string
|
||||
unknownCartonCount: number | string
|
||||
availableCartonCount: number | string
|
||||
availablePalletCount: number | string
|
||||
groups: InventoryPieceGroup[]
|
||||
}
|
||||
|
||||
/** 完整筛选的真实可用件数及混箱全部SKU,不按记账SKU换算。 */
|
||||
export async function getInventoryPieceProjection(query: InventoryBalanceQuery) {
|
||||
const response = await http.get<ApiEnvelope<InventoryPieceProjection>, ApiEnvelope<InventoryPieceProjection>>(
|
||||
'/platform/v1/last-leg/inventory/piece-projection', { params: params(query) },
|
||||
)
|
||||
return unwrapApiResponse(response)
|
||||
}
|
||||
|
||||
export interface InventoryPositionDto {
|
||||
id: string
|
||||
balanceId: string
|
||||
|
||||
@@ -51,8 +51,17 @@ export interface LastMileBusinessSource {
|
||||
businessOrderNo: string | null
|
||||
externalBookingNo: string | null
|
||||
}
|
||||
export interface ReturnOrderStatistics {
|
||||
totals: { orderCount: number; skuTypes: number; expectedQuantity: number; receivedQuantity: number; remainingQuantity: number; receivedBoxCount: number; receivedParcelCount: number; receivedPalletCount: number }
|
||||
pageDimensions: Array<{ returnNo: string; lastlegOrderId: string; expectedQuantity: number; receivedQuantity: number; remainingQuantity: number; receivedBoxCount: number; receivedParcelCount: number; receivedPalletCount: number }>
|
||||
}
|
||||
export async function getReturnOrderStatistics(params: LastMileOrderQuery) {
|
||||
const response = await http.get<ApiEnvelope<ReturnOrderStatistics>, ApiEnvelope<ReturnOrderStatistics>>('/platform/v1/last-leg/return-orders/statistics', { params })
|
||||
return unwrapApiResponse(response)
|
||||
}
|
||||
|
||||
export interface LastMileOrderSummaryDto {
|
||||
warehouseTransferQuantity?: import('./transferQuantityFacts').TransferQuantityFacts | null
|
||||
businessSource?: LastMileBusinessSource | null
|
||||
id: string
|
||||
customerId: string
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { listSharedReceivingOverseasWarehouseOptions } from '@/modules/iam'
|
||||
import { http } from '@/shared/api/http'
|
||||
import { changeRelabelOrderStatus, createRelabelOrder, getRelabelOrder, listRelabelOrders, listRelabelWarehouseOptions } from './relabelOrders'
|
||||
import { changeRelabelOrderStatus, createRelabelOrder, getRelabelOrder, listRelabelOrders, listRelabelWarehouseOptions, type CreateRelabelPayload } from './relabelOrders'
|
||||
|
||||
vi.mock('@/modules/iam', () => ({ listSharedReceivingOverseasWarehouseOptions: vi.fn() }))
|
||||
vi.mock('@/shared/api/http', async (importOriginal) => ({ ...(await importOriginal<typeof import('@/shared/api/http')>()), http: { get: vi.fn(), post: vi.fn(), put: vi.fn() } }))
|
||||
@@ -29,7 +29,7 @@ describe('relabel overseas API', () => {
|
||||
it('uses the real create and status endpoints', async () => {
|
||||
vi.mocked(http.post).mockResolvedValue({ code: '200', data: {} })
|
||||
vi.mocked(http.put).mockResolvedValue({ code: '200', data: {} })
|
||||
const payload = { customerOrderNo: 'CO-1', overseasWarehouseId: '9', labelDeadline: '2026-08-20T10:00:00', contactName: 'A', contactPhone: '1', chargeAmount: 20, idempotencyKey: 'k', items: [{ skuCode: 'SKU', productNameZh: 'P', totalPackageCount: 1, notifiedPackageCount: 1, shipmentNo: 'S', newSkuCode: 'SKU-2' }] }
|
||||
const payload: CreateRelabelPayload = { customerOrderNo: 'CO-1', operationWarehouseId: '9', labelDeadline: '2026-08-20T10:00:00', contactName: 'A', contactPhone: '1', chargeAmount: 20, idempotencyKey: 'k', items: [{ sourceInventoryBalanceId: '11', sourceInventoryPositionId: '12', sourceInboundOrderId: '13', cartonMark: 'BOX', operationType: 'SKU_LABEL', skuItems: [{ skuCode: 'SKU', newSkuCode: 'SKU-2', quantity: 8 }], skuCode: 'SKU', productNameZh: 'P', totalPackageCount: 1, notifiedPackageCount: 1, shipmentNo: 'S', newSkuCode: 'SKU-2' }] }
|
||||
await createRelabelOrder('10001', payload)
|
||||
await changeRelabelOrderStatus('RL/1', 'PROCESSING', 'ok')
|
||||
expect(http.post).toHaveBeenCalledWith('/platform/v1/last-leg/relabel-applications', payload, { params: { customerId: '10001' } })
|
||||
|
||||
@@ -12,6 +12,15 @@ export interface RelabelOrderQuery {
|
||||
}
|
||||
|
||||
export interface CreateRelabelItemPayload {
|
||||
sourceInventoryBalanceId?: string
|
||||
sourceInventoryPositionId?: string
|
||||
sourceInboundOrderId?: string
|
||||
returnCartonId?: string
|
||||
cartonMark: string
|
||||
fbaCartonMark?: string
|
||||
destinationFbaWarehouseCode?: string
|
||||
operationType: 'CARTON_LABEL' | 'SKU_LABEL' | 'CARTON_AND_SKU'
|
||||
skuItems: Array<{ skuCode: string; newSkuCode: string; quantity: number; remark?: string }>
|
||||
skuCode: string
|
||||
productNameZh: string
|
||||
totalPackageCount: number
|
||||
@@ -30,9 +39,9 @@ export interface CreateRelabelItemPayload {
|
||||
|
||||
export interface CreateRelabelPayload {
|
||||
customerOrderNo: string
|
||||
operationWarehouseId?: string
|
||||
/** @deprecated compatibility alias for older platform fixtures */
|
||||
overseasWarehouseId?: string
|
||||
operationWarehouseId: string
|
||||
deliveryMethod?: 'TRUCK' | 'EXPRESS' | 'PICKUP' | 'AMAZON_PICKUP' | 'CUSTOMER_PICKUP'
|
||||
printShippingLabel?: boolean
|
||||
labelDeadline: string
|
||||
contactName: string
|
||||
contactPhone: string
|
||||
@@ -131,6 +140,7 @@ export interface RelabelDetailDto {
|
||||
}
|
||||
|
||||
export interface RelabelQuantity {
|
||||
sourceUnitCounts?: Record<string, number | string> | null
|
||||
labelPieceCount: number | string | null
|
||||
cartonCount: number | string | null
|
||||
skuCount: number | string
|
||||
@@ -140,6 +150,10 @@ export interface RelabelQuantity {
|
||||
targetPalletCount: number | string | null
|
||||
}
|
||||
export interface RelabelQuantityTotals {
|
||||
knownSourcePalletCount?: number | string
|
||||
unknownSourcePalletOrders?: number | string
|
||||
knownTargetPalletCount?: number | string
|
||||
unknownTargetPalletOrders?: number | string
|
||||
orderCount: number | string
|
||||
skuCount: number | string
|
||||
knownLabelPieceCount: number | string
|
||||
@@ -148,6 +162,26 @@ export interface RelabelQuantityTotals {
|
||||
unknownCartonOrders: number | string
|
||||
orders: Record<string, RelabelQuantity>
|
||||
}
|
||||
export interface RelabelInventoryCandidate {
|
||||
inventoryBalanceId?: string | null
|
||||
inboundOrderId?: string | null
|
||||
inboundOrderNo: string
|
||||
inboundCode?: string
|
||||
skuCode: string
|
||||
productNameZh: string
|
||||
availablePackages: number | string
|
||||
sourceType: string
|
||||
returnCartonId?: string | null
|
||||
cartonMark?: string | null
|
||||
cartonAvailablePackages?: number | string
|
||||
cartonSkuItems?: Array<{ skuCode: string; quantity: number }>
|
||||
positions: Array<{ positionId: string; palletNo: string; availablePackages: number | string }>
|
||||
}
|
||||
/** 候选归属和可用量由服务端决定,长整型来源ID按字符串原样提交。 */
|
||||
export async function listRelabelInventoryCandidates(customerId: string, operationWarehouseId: string) {
|
||||
const response = await http.get<ApiEnvelope<RelabelInventoryCandidate[]>, ApiEnvelope<RelabelInventoryCandidate[]>>('/platform/v1/last-leg/relabel-applications/inventory-candidates', { params: { customerId, operationWarehouseId } })
|
||||
return unwrapApiResponse(response)
|
||||
}
|
||||
/** 汇总同一筛选下全部单据,不以当前页合计代替。 */
|
||||
export async function getRelabelQuantities(query: RelabelOrderQuery) {
|
||||
const response = await http.get<ApiEnvelope<RelabelQuantityTotals>, ApiEnvelope<RelabelQuantityTotals>>('/platform/v1/last-leg/relabel-applications/quantity-summary', { params: query })
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { http, unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http'
|
||||
import type { LastMileOrderQuery } from './lastMileOrders'
|
||||
export interface TransferQuantityFacts {
|
||||
declaredPieceCount: number | string | null
|
||||
receivedPieceCount: number | string | null
|
||||
declaredCartonCount: number | string
|
||||
receivedCartonCount: number | string
|
||||
receivedPalletCount: number | string
|
||||
availableCartonCount: number | string
|
||||
shippedCartonCount: number | string
|
||||
remainingPalletCount: number | string
|
||||
shippedPalletCount: number | string
|
||||
}
|
||||
export interface TransferQuantityTotals extends TransferQuantityFacts {
|
||||
orderCount: number | string
|
||||
knownDeclaredPieceCount: number | string
|
||||
unknownDeclaredOrderCount: number | string
|
||||
knownReceivedPieceCount: number | string
|
||||
unknownReceivedOrderCount: number | string
|
||||
}
|
||||
export async function getTransferQuantityTotals(query: LastMileOrderQuery) {
|
||||
const response = await http.get<ApiEnvelope<TransferQuantityTotals>, ApiEnvelope<TransferQuantityTotals>>(
|
||||
'/platform/v1/last-leg/orders/warehouse-transfer-quantities', { params: query },
|
||||
)
|
||||
return unwrapApiResponse(response)
|
||||
}
|
||||
Reference in New Issue
Block a user