fix(overseas): reuse original resource command after reopening conversion
This commit is contained in:
@@ -265,6 +265,7 @@ export interface ContainerInboundPlanPreviewGroupDto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ContainerInboundPlanPreviewDto {
|
export interface ContainerInboundPlanPreviewDto {
|
||||||
|
resourceRetry?: { idempotencyKey: string; snapshotVersion: number; snapshotHash: string } | null
|
||||||
sourceContainerBookingId: string
|
sourceContainerBookingId: string
|
||||||
containerNo: string | null
|
containerNo: string | null
|
||||||
overseasWarehouseId: 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)
|
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 () => {
|
it('renders the all-cabinet empty state and unit', async () => {
|
||||||
vi.mocked(listContainerPlanProgress).mockResolvedValueOnce({ records: [], page: 1, size: 10, total: 0, pages: 0 })
|
vi.mocked(listContainerPlanProgress).mockResolvedValueOnce({ records: [], page: 1, size: 10, total: 0, pages: 0 })
|
||||||
const wrapper = await mountView()
|
const wrapper = await mountView()
|
||||||
|
|||||||
@@ -740,7 +740,8 @@ async function loadContainerPreview(sourceContainerBookingId = selectedContainer
|
|||||||
const preview = await getContainerInboundPlanPreview(sourceContainerBookingId)
|
const preview = await getContainerInboundPlanPreview(sourceContainerBookingId)
|
||||||
if (request !== containerPreviewRequest || selectedContainerBookingId.value !== sourceContainerBookingId || !containerConvertOpen.value) return
|
if (request !== containerPreviewRequest || selectedContainerBookingId.value !== sourceContainerBookingId || !containerConvertOpen.value) return
|
||||||
containerPreview.value = preview
|
containerPreview.value = preview
|
||||||
if (!preserveResult) containerConversionIdempotencyKey = idempotencyKey('container-inbound-plan')
|
if (!preserveResult) containerConversionIdempotencyKey = preview.resourceRetry
|
||||||
|
? preview.resourceRetry.idempotencyKey : idempotencyKey('container-inbound-plan')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (request !== containerPreviewRequest || selectedContainerBookingId.value !== sourceContainerBookingId || !containerConvertOpen.value) return
|
if (request !== containerPreviewRequest || selectedContainerBookingId.value !== sourceContainerBookingId || !containerConvertOpen.value) return
|
||||||
containerPreviewError.value = getApiErrorDetails(error, '加载整柜入库计划预览失败,请重试').message
|
containerPreviewError.value = getApiErrorDetails(error, '加载整柜入库计划预览失败,请重试').message
|
||||||
@@ -757,6 +758,7 @@ async function confirmContainerInboundPlans() {
|
|||||||
if (!preview?.ready || preview.pendingOrderCount <= 0 || actionLoading.value) return
|
if (!preview?.ready || preview.pendingOrderCount <= 0 || actionLoading.value) return
|
||||||
if (!containerConversionIdempotencyKey) containerConversionIdempotencyKey = idempotencyKey('container-inbound-plan')
|
if (!containerConversionIdempotencyKey) containerConversionIdempotencyKey = idempotencyKey('container-inbound-plan')
|
||||||
const bookingId = preview.sourceContainerBookingId
|
const bookingId = preview.sourceContainerBookingId
|
||||||
|
const commandSnapshot = preview.resourceRetry ?? preview
|
||||||
const existingPlanNos = new Set(preview.groups.flatMap((group) => group.orders)
|
const existingPlanNos = new Set(preview.groups.flatMap((group) => group.orders)
|
||||||
.filter((order) => order.readiness !== 'READY' && order.existingPlanNo)
|
.filter((order) => order.readiness !== 'READY' && order.existingPlanNo)
|
||||||
.map((order) => String(order.existingPlanNo)))
|
.map((order) => String(order.existingPlanNo)))
|
||||||
@@ -765,8 +767,8 @@ async function confirmContainerInboundPlans() {
|
|||||||
try {
|
try {
|
||||||
const plans = await convertLastMileContainerToInboundPlans({
|
const plans = await convertLastMileContainerToInboundPlans({
|
||||||
sourceContainerBookingId: bookingId,
|
sourceContainerBookingId: bookingId,
|
||||||
snapshotVersion: preview.snapshotVersion,
|
snapshotVersion: commandSnapshot.snapshotVersion,
|
||||||
snapshotHash: preview.snapshotHash,
|
snapshotHash: commandSnapshot.snapshotHash,
|
||||||
}, containerConversionIdempotencyKey)
|
}, containerConversionIdempotencyKey)
|
||||||
if (selectedContainerBookingId.value !== bookingId || !containerConvertOpen.value) return
|
if (selectedContainerBookingId.value !== bookingId || !containerConvertOpen.value) return
|
||||||
const existingPlanCount = plans.filter((plan) => existingPlanNos.has(plan.planNo)).length
|
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('request !== containerPreviewRequest || selectedContainerBookingId.value !== sourceContainerBookingId || !containerConvertOpen.value')
|
||||||
expect(pageSource).toContain('containerPreviewRequest += 1')
|
expect(pageSource).toContain('containerPreviewRequest += 1')
|
||||||
expect(pageSource.match(/await convertLastMileContainerToInboundPlans\(\{/g)).toHaveLength(1)
|
expect(pageSource.match(/await convertLastMileContainerToInboundPlans\(\{/g)).toHaveLength(1)
|
||||||
expect(pageSource).toContain('snapshotVersion: preview.snapshotVersion')
|
expect(pageSource).toContain('const commandSnapshot = preview.resourceRetry ?? preview')
|
||||||
expect(pageSource).toContain('snapshotHash: preview.snapshotHash')
|
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('containerConversionIdempotencyKey')
|
||||||
expect(pageSource).toContain(':confirm-disabled="containerConfirmDisabled"')
|
expect(pageSource).toContain(':confirm-disabled="containerConfirmDisabled"')
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user