Merge branch 'release/test' of http://8.163.30.128:10082/html/admin-web into release/test

This commit is contained in:
2026-10-15 18:25:24 +08:00
62 changed files with 2740 additions and 942 deletions
@@ -1,10 +1,20 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { http } from '@/shared/api/http'
import { cancelDispatch, createDispatchDraftContainer, deleteDispatchDraftContainer, getDispatch, getDispatchBolPdf, getDispatchExternalFreight, getDispatchFeeCoverage, listDispatchCandidates, listDispatchDrafts, listDispatches, lockDispatchDraftPallet, preArrangeDispatch, preArrangeDraftDispatch, releaseDispatchDraft, transferDispatchToDelivery, unlockDispatchDraftPallet, updateDispatch } from './dispatches'
import { cancelDispatch, createDispatchDraftContainer, deleteDispatchDraftContainer, getDispatch, getDispatchBolPdf, getDispatchExternalFreight, getDispatchFeeCoverage, listDispatchCandidates, listDispatchDrafts, listDispatches, lockDispatchDraftPallet, preArrangeDispatch, preArrangeDraftDispatch, releaseDispatchDraft, transferDispatchToDelivery, unlockDispatchDraftPallet, updateDispatch, getBatchDispatchCandidates } from './dispatches'
vi.mock('@/shared/api/http', async (importOriginal) => ({ ...(await importOriginal<typeof import('@/shared/api/http')>()), http: { get: vi.fn(), post: vi.fn(), put: vi.fn(), delete: vi.fn() } }))
describe('dispatch overseas API', () => {
it('reads an immutable batch and preserves its exact per-source allocations on grouped submission', async () => {
const allocation = { planPalletId: '9007199254740993', batchKey: 'FBA_APPOINTMENT:9', customerId: '9007199254740999', sourceKey: 'BOOKING:2', destinationKey: 'FBA:ONT8', packageCount: 12 }
vi.mocked(http.get).mockResolvedValue({ code: '200', data: { batchKey: allocation.batchKey, version: 4, candidates: [], blockReasons: [] } })
await getBatchDispatchCandidates(allocation.batchKey)
expect(http.get).toHaveBeenCalledWith('/platform/v1/last-leg/appointment-planning/batches/FBA_APPOINTMENT%3A9/dispatch-candidates')
vi.mocked(http.post).mockResolvedValue({ code: '200', data: [] })
const request = { draftToken: 'draft-1', groups: [{ draftContainerId: 'container-1', planPalletIds: [allocation.planPalletId], returnReceiptIds: [], batchAllocations: [allocation] }] }
await preArrangeDraftDispatch(request)
expect(http.post).toHaveBeenCalledWith('/platform/v1/last-leg/dispatches/drafts/pre-arrange', request)
})
it('submits all explicit draft groups once and preserves container and source identities', async () => {
const payload = { draftToken: 'original-draft', groups: [
{ draftContainerId: '190000000000000099', planPalletIds: ['11', '13'], returnReceiptIds: [] },
@@ -66,6 +66,7 @@ export interface DispatchDraftContainerDto { id: string; capacity: number; palle
export interface DispatchDraftDto { draftToken: string; containers?: DispatchDraftContainerDto[] }
export interface PreArrangeDispatchPayload {
batchAllocations?: DispatchBatchAllocation[]
planPalletIds: string[]
returnReceiptIds?: string[]
fbaAppointmentNo?: string
@@ -76,6 +77,7 @@ export interface PreArrangeDispatchPayload {
}
export interface PreArrangeDispatchDraftGroup {
batchAllocations?: DispatchBatchAllocation[]
draftContainerId: string
planPalletIds: string[]
returnReceiptIds: string[]
@@ -88,6 +90,12 @@ export interface PreArrangeDispatchDraftResult {
draftContainerId: string
dispatch: DispatchSummaryDto
}
export interface DispatchBatchAllocation { planPalletId: string; batchKey: string; customerId: string; sourceKey: string; destinationKey: string; packageCount: number }
export interface BatchDispatchCandidate { planPalletId: string; palletNo: string; planId: string; planNo: string; customerId: string; sourceStage: string; packageCount: number | null; allocations: DispatchBatchAllocation[]; blockReasons: string[] }
export interface BatchDispatchCandidates { batchKey: string; version: number; candidates: BatchDispatchCandidate[]; blockReasons: string[] }
export async function getBatchDispatchCandidates(batchKey: string) {
return unwrapApiResponse(await http.get<ApiEnvelope<BatchDispatchCandidates>, ApiEnvelope<BatchDispatchCandidates>>(`/platform/v1/last-leg/appointment-planning/batches/${encodeURIComponent(batchKey)}/dispatch-candidates`))
}
export interface DispatchSummaryDto {
workflow?: DispatchWorkflow | null
@@ -91,7 +91,11 @@ export interface FbaAppointmentDto {
appointmentRemark?: string | null
selectedCount: number
fbaWarehouseCode: string
items: Array<{ customerId: string; id: string; sourceKey: string; sourceVersion?: string | null; orderId?: string | null; inboundCode?: string | null; fbaWarehouseCode: string; packageCount?: number | null }>
batchKey?: string
replacementBatchKeys?: string[]
replacementAppointmentNos?: string[]
repartitionReason?: string | null
items: Array<{ customerId: string; id: string; sourceKey: string; sourceVersion?: string | null; orderId?: string | null; inboundCode?: string | null; fbaWarehouseCode: string; packageCount?: number | null; cargoVerificationVersion?: number | null; shipmentReferences?: string[]; destinationKey?: string | null }>
}
export interface UpdateFbaAppointmentPayload { details: FbaAppointmentDetailsPayload; version: number; idempotencyKey: string }