From 4377a7acd933987fe8e94185110d5076180074b7 Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Mon, 24 Aug 2026 12:34:34 +0800 Subject: [PATCH] fix(firstleg): allow confirmed preload reassign during loading --- .../firstleg/service/SmartLoadingService.java | 9 +++++++-- .../split/service/SplitPreloadService.java | 18 +++++++++++++++++- .../service/SmartLoadingServiceTest.java | 2 ++ .../split/service/SplitPreloadServiceTest.java | 12 ++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/firstleg/src/main/java/com/baiyue/firstleg/service/SmartLoadingService.java b/firstleg/src/main/java/com/baiyue/firstleg/service/SmartLoadingService.java index e902a6e79..33230e466 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/service/SmartLoadingService.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/service/SmartLoadingService.java @@ -136,8 +136,13 @@ public class SmartLoadingService { if (candidate == null) throw conflict("入库货物不存在或尚未完成入库"); requireSameChannel(booking, candidate); requireSameCustomerScope(booking, candidate); - splitPreloadService.ensurePendingForLoadingAllocation(candidate.accountId(), candidate.inboundId(), - operatorId, operatorName); + if ("LOADING".equals(plan.getPlanStatus())) { + splitPreloadService.ensureForRunningLoadingAllocation(candidate.accountId(), candidate.inboundId(), + operatorId, operatorName); + } else { + splitPreloadService.ensurePendingForLoadingAllocation(candidate.accountId(), candidate.inboundId(), + operatorId, operatorName); + } OrderCargoClient.CargoBinding cargo = loadCargo(candidate); LoadingPlanItemEntity existing = repository.activeItem(planId, candidate.accountId(), request.inboundDetailId()); int total = request.packageCount() + (existing == null ? 0 : existing.getPackageCount()); diff --git a/firstleg/src/main/java/com/baiyue/firstleg/split/service/SplitPreloadService.java b/firstleg/src/main/java/com/baiyue/firstleg/split/service/SplitPreloadService.java index 70146cf38..3a5314063 100644 --- a/firstleg/src/main/java/com/baiyue/firstleg/split/service/SplitPreloadService.java +++ b/firstleg/src/main/java/com/baiyue/firstleg/split/service/SplitPreloadService.java @@ -68,11 +68,27 @@ public class SplitPreloadService { @Transactional public void ensurePendingForLoadingAllocation(long tenantId, long inboundId, long operatorId, String operatorName) { + ensureForLoadingAllocation(tenantId, inboundId, operatorId, operatorName, false); + } + + /** + * A running loading task may re-add an inbound whose preload was confirmed by an earlier + * incremental allocation. Draft plans must still use the stricter pending-only entry point. + */ + @Transactional + public void ensureForRunningLoadingAllocation(long tenantId, long inboundId, long operatorId, + String operatorName) { + ensureForLoadingAllocation(tenantId, inboundId, operatorId, operatorName, true); + } + + private void ensureForLoadingAllocation(long tenantId, long inboundId, long operatorId, + String operatorName, boolean allowConfirmed) { InboundSnapshot inbound = requireInbound(tenantId, inboundId); requireWaitingSplit(inbound, "仅待分柜订单可以建立智能装柜预装计划"); PreloadPlanEntity plan = repository.findPlan(tenantId, inboundId); if (plan != null) { - if (!PreloadStatus.PENDING.equals(plan.getStatus())) { + if (!PreloadStatus.PENDING.equals(plan.getStatus()) + && !(allowConfirmed && PreloadStatus.CONFIRMED.equals(plan.getStatus()))) { throw new BizException(ResultCode.CONFLICT, "预装计划已进入确认流程,不能修改智能装柜分配"); } return; diff --git a/firstleg/src/test/java/com/baiyue/firstleg/service/SmartLoadingServiceTest.java b/firstleg/src/test/java/com/baiyue/firstleg/service/SmartLoadingServiceTest.java index c26f94ef7..8cc6b1698 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/service/SmartLoadingServiceTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/service/SmartLoadingServiceTest.java @@ -360,6 +360,8 @@ class SmartLoadingServiceTest { Plan result = service.assign(1, new AssignRequest(10L, 20L, 1, 5, "assign-loading"), 7, "u"); assertThat(result.status()).isEqualTo("LOADING"); + verify(splitPreloadService).ensureForRunningLoadingAllocation(9L, 10L, 7L, "u"); + verify(splitPreloadService, never()).ensurePendingForLoadingAllocation(anyLong(), anyLong(), anyLong(), anyString()); var order = inOrder(loadingPickService, repository, loadingModelBridge); order.verify(loadingPickService).lockMutable(1L); order.verify(repository).touch(1, 5, 7, "u"); diff --git a/firstleg/src/test/java/com/baiyue/firstleg/split/service/SplitPreloadServiceTest.java b/firstleg/src/test/java/com/baiyue/firstleg/split/service/SplitPreloadServiceTest.java index 267aaaf36..08ea4d1bb 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/split/service/SplitPreloadServiceTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/split/service/SplitPreloadServiceTest.java @@ -80,4 +80,16 @@ class SplitPreloadServiceTest { verify(repository, never()).createPlan(any()); } + @Test + void runningLoadingAllocationMayReuseConfirmedPreload() { + when(repository.findInbound(10, 20)).thenReturn(new InboundSnapshot(20L, 10L, "WAIT_SPLIT", 3)); + PreloadPlanEntity plan = new PreloadPlanEntity(); + plan.setStatus("CONFIRMED"); + when(repository.findPlan(10, 20)).thenReturn(plan); + + service.ensureForRunningLoadingAllocation(10, 20, 7, "admin"); + + verify(repository, never()).createPlan(any()); + } + }