fix(overseas): reuse original resource command after reopening conversion

This commit is contained in:
2026-10-05 02:13:24 +08:00
parent ea24496b11
commit 058b0778a2
4 changed files with 41 additions and 5 deletions
@@ -265,6 +265,7 @@ export interface ContainerInboundPlanPreviewGroupDto {
}
export interface ContainerInboundPlanPreviewDto {
resourceRetry?: { idempotencyKey: string; snapshotVersion: number; snapshotHash: string } | null
sourceContainerBookingId: string
containerNo: string | null
overseasWarehouseId: string | null
@@ -724,6 +724,37 @@ describe('LastMileOrdersView pending order and container conversion', () => {
expect((button(wrapper, '修改接柜仓')!.element as HTMLButtonElement).disabled).toBe(false)
})
it('restores the original resource command after reopening a locally committed cabinet', async () => {
vi.mocked(listContainerPlanProgress).mockResolvedValueOnce({
records: [{ ...summary, pendingPlanCount: 0, resourcePendingPlanCount: 1, allPlansReady: true }],
page: 1, size: 10, total: 1, pages: 1,
})
const reopenedPreview = {
...preview, snapshotVersion: 10, snapshotHash: 'b'.repeat(64),
groups: preview.groups.map((group) => ({
...group, destinationType: 'FBA' as const,
orders: group.orders.map((order) => ({
...order, destinationType: 'FBA' as const, fbaWarehouseCode: 'ONT8',
readiness: 'RESOURCE_PENDING' as const, existingPlanNo: 'LIP-ORIGINAL', plannedPalletCount: 5,
})),
})),
resourceRetry: { idempotencyKey: 'original-container-command', snapshotVersion: 9, snapshotHash: 'a'.repeat(64) },
}
vi.mocked(getContainerInboundPlanPreview).mockResolvedValueOnce(reopenedPreview)
const wrapper = await mountView()
await openHiddenContainerWorkbench(wrapper)
await button(wrapper, '重试生成托盘码')!.trigger('click')
await flushPromises()
const confirm = [...document.body.querySelectorAll('button')]
.find((item) => item.textContent?.includes('确认生成')) as HTMLButtonElement
expect(confirm.disabled).toBe(false)
confirm.click()
await flushPromises()
expect(convertLastMileContainerToInboundPlans).toHaveBeenCalledWith({
sourceContainerBookingId: bookingId, snapshotVersion: 9, snapshotHash: 'a'.repeat(64),
}, 'original-container-command')
})
it('renders the all-cabinet empty state and unit', async () => {
vi.mocked(listContainerPlanProgress).mockResolvedValueOnce({ records: [], page: 1, size: 10, total: 0, pages: 0 })
const wrapper = await mountView()
@@ -740,7 +740,8 @@ async function loadContainerPreview(sourceContainerBookingId = selectedContainer
const preview = await getContainerInboundPlanPreview(sourceContainerBookingId)
if (request !== containerPreviewRequest || selectedContainerBookingId.value !== sourceContainerBookingId || !containerConvertOpen.value) return
containerPreview.value = preview
if (!preserveResult) containerConversionIdempotencyKey = idempotencyKey('container-inbound-plan')
if (!preserveResult) containerConversionIdempotencyKey = preview.resourceRetry
? preview.resourceRetry.idempotencyKey : idempotencyKey('container-inbound-plan')
} catch (error) {
if (request !== containerPreviewRequest || selectedContainerBookingId.value !== sourceContainerBookingId || !containerConvertOpen.value) return
containerPreviewError.value = getApiErrorDetails(error, '加载整柜入库计划预览失败,请重试').message
@@ -757,6 +758,7 @@ async function confirmContainerInboundPlans() {
if (!preview?.ready || preview.pendingOrderCount <= 0 || actionLoading.value) return
if (!containerConversionIdempotencyKey) containerConversionIdempotencyKey = idempotencyKey('container-inbound-plan')
const bookingId = preview.sourceContainerBookingId
const commandSnapshot = preview.resourceRetry ?? preview
const existingPlanNos = new Set(preview.groups.flatMap((group) => group.orders)
.filter((order) => order.readiness !== 'READY' && order.existingPlanNo)
.map((order) => String(order.existingPlanNo)))
@@ -765,8 +767,8 @@ async function confirmContainerInboundPlans() {
try {
const plans = await convertLastMileContainerToInboundPlans({
sourceContainerBookingId: bookingId,
snapshotVersion: preview.snapshotVersion,
snapshotHash: preview.snapshotHash,
snapshotVersion: commandSnapshot.snapshotVersion,
snapshotHash: commandSnapshot.snapshotHash,
}, containerConversionIdempotencyKey)
if (selectedContainerBookingId.value !== bookingId || !containerConvertOpen.value) return
const existingPlanCount = plans.filter((plan) => existingPlanNos.has(plan.planNo)).length
@@ -28,8 +28,10 @@ describe('container inbound plan preview contract', () => {
expect(pageSource).toContain('request !== containerPreviewRequest || selectedContainerBookingId.value !== sourceContainerBookingId || !containerConvertOpen.value')
expect(pageSource).toContain('containerPreviewRequest += 1')
expect(pageSource.match(/await convertLastMileContainerToInboundPlans\(\{/g)).toHaveLength(1)
expect(pageSource).toContain('snapshotVersion: preview.snapshotVersion')
expect(pageSource).toContain('snapshotHash: preview.snapshotHash')
expect(pageSource).toContain('const commandSnapshot = preview.resourceRetry ?? preview')
expect(pageSource).toContain('snapshotVersion: commandSnapshot.snapshotVersion')
expect(pageSource).toContain('snapshotHash: commandSnapshot.snapshotHash')
expect(pageSource).toContain('preview.resourceRetry.idempotencyKey')
expect(pageSource).toContain('containerConversionIdempotencyKey')
expect(pageSource).toContain(':confirm-disabled="containerConfirmDisabled"')
})