This commit is contained in:
2026-09-04 12:18:36 +08:00
parent 566b07be62
commit b697e4c9f0
51 changed files with 1898 additions and 623 deletions
@@ -342,7 +342,7 @@ class LoadingPickServiceTest {
preparePick(task, item, "pick-1");
when(repository.allTaskItemsResolved(20L)).thenReturn(false);
service.pick(20L, 30L, new PickRequest(101L, 2, List.of(), 0, "pick-1"), 9L, "operator");
service.pick(20L, 30L, new PickRequest(101L, 2, 0, "pick-1"), 9L, "operator");
verify(repository).touchTask(20L, 0);
verify(repository).syncInboundProjections(20L, 9L, "operator");
@@ -358,7 +358,7 @@ class LoadingPickServiceTest {
when(repository.allTaskItemsResolved(20L)).thenReturn(true);
when(repository.allPlanItemsPicked(10L)).thenReturn(true);
service.pick(20L, 30L, new PickRequest(101L, 2, List.of(), 0, "pick-2"), 9L, "operator");
service.pick(20L, 30L, new PickRequest(101L, 2, 0, "pick-2"), 9L, "operator");
verify(repository).touchTask(20L, 0);
verify(settlementService, never()).settle(20L, 9L, "operator");
@@ -374,7 +374,7 @@ class LoadingPickServiceTest {
preparePick(task, item, "pick-start-loading");
when(smartLoadingRepository.startPicking(10L, 9L, "operator")).thenReturn(1);
service.pick(20L, 30L, new PickRequest(101L, 2, List.of(), 0, "pick-start-loading"),
service.pick(20L, 30L, new PickRequest(101L, 2, 0, "pick-start-loading"),
9L, "operator");
verify(smartLoadingRepository).startPicking(10L, 9L, "operator");
@@ -393,7 +393,7 @@ class LoadingPickServiceTest {
new LoadingInboundMapper.Snapshot(50L, 101L, "WAIT_SPLIT", 4));
when(repository.beginInboundLoading(101L, 50L, 9L, 4)).thenReturn(1);
service.pick(20L, 30L, new PickRequest(101L, 2, List.of(), 0, "pick-start-inbound"),
service.pick(20L, 30L, new PickRequest(101L, 2, 0, "pick-start-inbound"),
9L, "operator");
verify(repository).beginInboundLoading(101L, 50L, 9L, 4);
@@ -419,7 +419,7 @@ class LoadingPickServiceTest {
new LoadingInboundMapper.Snapshot(50L, 101L, "LOADING", 5));
when(repository.beginInboundLoading(101L, 50L, 9L, 4)).thenReturn(0);
service.pick(20L, 30L, new PickRequest(101L, 2, List.of(), 0, "pick-concurrent-inbound"),
service.pick(20L, 30L, new PickRequest(101L, 2, 0, "pick-concurrent-inbound"),
9L, "operator");
verify(repository).beginInboundLoading(101L, 50L, 9L, 4);
@@ -518,7 +518,8 @@ class LoadingPickServiceTest {
void claimRechecksSameOperationAfterWaitingForTaskLock() {
LoadingPickTaskEntity task = task();
LoadingPickOperationEntity completed = taskOperation("claim-race", "CLAIM");
when(repository.operation("claim-race")).thenReturn(null, completed);
when(repository.operation("claim-race")).thenReturn(null);
when(repository.operationForUpdate("claim-race")).thenReturn(completed);
when(repository.taskForUpdate(20L)).thenReturn(task);
when(repository.task(20L)).thenReturn(task);
when(repository.items(20L)).thenReturn(List.of());
@@ -535,7 +536,8 @@ class LoadingPickServiceTest {
void assignRechecksSameOperationAfterWaitingForTaskLock() {
LoadingPickTaskEntity task = task();
LoadingPickOperationEntity completed = taskOperation("assign-race", "ASSIGN");
when(repository.operation("assign-race")).thenReturn(null, completed);
when(repository.operation("assign-race")).thenReturn(null);
when(repository.operationForUpdate("assign-race")).thenReturn(completed);
when(repository.taskForUpdate(20L)).thenReturn(task);
when(repository.task(20L)).thenReturn(task);
when(repository.items(20L)).thenReturn(List.of());
@@ -554,17 +556,18 @@ class LoadingPickServiceTest {
void pickRechecksSameHistoryAfterWaitingForTaskLock() {
LoadingPickTaskEntity task = task();
LoadingPickHistoryEntity completed = itemHistory("pick-race", "PICK",
"20|30|101|2|MANUAL|[]");
when(repository.history("pick-race")).thenReturn(null, completed);
"20|30|101|2");
when(repository.history("pick-race")).thenReturn(null);
when(repository.historyForUpdate("pick-race")).thenReturn(completed);
when(repository.taskForUpdate(20L)).thenReturn(task);
when(repository.assignment(20L)).thenReturn(assignment());
when(repository.items(20L, 101L)).thenReturn(List.of(item()));
Task replay = service.pick(20L, 30L,
new PickRequest(101L, 2, List.of(), 0, "pick-race"), 9L, "operator");
new PickRequest(101L, 2, 0, "pick-race"), 9L, "operator");
assertThat(replay.id()).isEqualTo(20L);
verify(repository, never()).pick(anyLong(), anyInt(), anyString(), anyString(), anyInt(), anyLong());
verify(repository, never()).pick(anyLong(), anyInt(), anyInt(), anyLong());
verify(repository, never()).insert(any(LoadingPickHistoryEntity.class));
verify(repository, never()).touchTask(anyLong(), anyInt());
}
@@ -573,17 +576,18 @@ class LoadingPickServiceTest {
void partialRechecksSameHistoryAfterWaitingForTaskLock() {
LoadingPickTaskEntity task = task();
LoadingPickHistoryEntity completed = itemHistory("partial-race", "PARTIAL",
"PARTIAL|20|30|101|1|MANUAL|[]");
when(repository.history("partial-race")).thenReturn(null, completed);
"PARTIAL|20|30|101|1");
when(repository.history("partial-race")).thenReturn(null);
when(repository.historyForUpdate("partial-race")).thenReturn(completed);
when(repository.taskForUpdate(20L)).thenReturn(task);
when(repository.assignment(20L)).thenReturn(assignment());
when(repository.items(20L, 101L)).thenReturn(List.of(item()));
Task replay = service.partial(20L, 30L,
new PartialPickRequest(101L, 1, List.of(), 0, "partial-race"), 9L, "operator");
new PartialPickRequest(101L, 1, 0, "partial-race"), 9L, "operator");
assertThat(replay.id()).isEqualTo(20L);
verify(repository, never()).partial(anyLong(), anyInt(), anyString(), anyString(), anyInt(), anyLong());
verify(repository, never()).partial(anyLong(), anyInt(), anyInt(), anyLong());
verify(repository, never()).insert(any(LoadingPickHistoryEntity.class));
verify(repository, never()).touchTask(anyLong(), anyInt());
}
@@ -593,7 +597,8 @@ class LoadingPickServiceTest {
LoadingPickTaskEntity task = task();
LoadingPickHistoryEntity completed = itemHistory("skip-race", "SKIP",
"SKIP|20|30|101|damaged");
when(repository.history("skip-race")).thenReturn(null, completed);
when(repository.history("skip-race")).thenReturn(null);
when(repository.historyForUpdate("skip-race")).thenReturn(completed);
when(repository.taskForUpdate(20L)).thenReturn(task);
when(repository.assignment(20L)).thenReturn(assignment());
when(repository.items(20L, 101L)).thenReturn(List.of(item()));
@@ -615,7 +620,7 @@ class LoadingPickServiceTest {
when(repository.allTaskItemsResolved(20L)).thenReturn(true);
when(repository.allPlanItemsPicked(10L)).thenReturn(true);
service.partial(20L, 30L, new PartialPickRequest(101L, 1, List.of(), 0, "partial-1"),
service.partial(20L, 30L, new PartialPickRequest(101L, 1, 0, "partial-1"),
9L, "operator");
verify(repository).touchTask(20L, 0);
@@ -1113,7 +1118,7 @@ class LoadingPickServiceTest {
when(repository.assignment(20L)).thenReturn(assignment());
when(repository.items(20L)).thenReturn(items);
when(repository.items(20L, 101L)).thenReturn(items);
when(repository.pick(30L, 2, "MANUAL", "[]", 0, 101L)).thenReturn(1);
when(repository.pick(30L, 2, 0, 101L)).thenReturn(1);
when(repository.skip(31L, 0, 101L)).thenReturn(1);
when(repository.allTaskItemsResolved(20L)).thenReturn(true);
when(repository.touchTask(20L, 0)).thenReturn(1);
@@ -1123,13 +1128,13 @@ class LoadingPickServiceTest {
71L, 72L, 0, 101L, 73L, 74L, "A-01", false, 2))));
String snapshotToken = service.inventorySnapshot(20L, 101L).snapshotToken();
BatchRequest request = new BatchRequest(101L, 10L, 99L, 0, snapshotToken, List.of(
new BatchItemRequest(30L, "PICK", 2, null, "MANUAL", List.of(), 0, null),
new BatchItemRequest(31L, "SKIP", null, null, null, null, 0, "damaged carton")));
new BatchItemRequest(30L, "PICK", 2, null, 0, null),
new BatchItemRequest(31L, "SKIP", null, null, 0, "damaged carton")));
service.batch(20L, "batch-1", request, 9L, "operator");
service.batch(20L, "batch-1", request, 9L, "operator");
verify(repository, times(1)).pick(30L, 2, "MANUAL", "[]", 0, 101L);
verify(repository, times(1)).pick(30L, 2, 0, 101L);
verify(repository, times(1)).skip(31L, 0, 101L);
verify(repository, times(1)).touchTask(20L, 0);
verify(settlementService, never()).settle(20L, 9L, "operator");
@@ -1154,7 +1159,7 @@ class LoadingPickServiceTest {
when(repository.assignment(20L)).thenReturn(assignment());
when(repository.items(20L)).thenReturn(List.of(item));
when(repository.items(20L, 101L)).thenReturn(List.of(item));
when(repository.pick(30L, 100, "AUTO", "[]", 0, 101L)).thenReturn(1);
when(repository.pick(30L, 100, 0, 101L)).thenReturn(1);
when(repository.allTaskItemsResolved(20L)).thenReturn(true);
when(repository.touchTask(20L, 0)).thenReturn(1);
when(smartLoadingRepository.startPicking(10L, 9L, "operator")).thenReturn(1);
@@ -1164,11 +1169,11 @@ class LoadingPickServiceTest {
71L, 72L, 0, 101L, 73L, 74L, "A-01", false, 100))));
String snapshotToken = service.inventorySnapshot(20L, 101L).snapshotToken();
BatchRequest request = new BatchRequest(101L, 10L, 99L, 0, snapshotToken, List.of(
new BatchItemRequest(30L, "PICK", 100, null, "AUTO", List.of(), 0, null)));
new BatchItemRequest(30L, "PICK", 100, null, 0, null)));
service.batch(20L, "batch-reset-plan", request, 9L, "operator");
verify(repository).pick(30L, 100, "AUTO", "[]", 0, 101L);
verify(repository).pick(30L, 100, 0, 101L);
verify(smartLoadingRepository).startPicking(10L, 9L, "operator");
verify(smartLoadingRepository, never()).insert(any(LoadingPlanHistoryEntity.class));
verify(repository).touchTask(20L, 0);
@@ -1190,14 +1195,14 @@ class LoadingPickServiceTest {
when(repository.items(20L)).thenReturn(items);
when(repository.items(20L, 101L)).thenReturn(items);
BatchRequest request = new BatchRequest(101L, 10L, 99L, 0, "stale-token", List.of(
new BatchItemRequest(30L, "PICK", 2, null, "MANUAL", List.of(), 0, null),
new BatchItemRequest(31L, "PARTIAL", null, 4, "AUTO", null, 0, null)));
new BatchItemRequest(30L, "PICK", 2, null, 0, null),
new BatchItemRequest(31L, "PARTIAL", null, 4, 0, null)));
assertThatThrownBy(() -> service.batch(20L, "batch-invalid", request, 9L, "operator"))
.isInstanceOf(BizException.class);
verify(repository, never()).pick(any(Long.class), any(Integer.class), any(), any(), any(Integer.class), any(Long.class));
verify(repository, never()).partial(any(Long.class), any(Integer.class), any(), any(), any(Integer.class), any(Long.class));
verify(repository, never()).pick(any(Long.class), any(Integer.class), any(Integer.class), any(Long.class));
verify(repository, never()).partial(any(Long.class), any(Integer.class), any(Integer.class), any(Long.class));
verify(repository, never()).touchTask(any(Long.class), any(Integer.class));
verify(settlementService, never()).settle(20L, 9L, "operator");
}
@@ -1214,13 +1219,13 @@ class LoadingPickServiceTest {
ApiResponse.success(List.of(new WarehousePalletLocationClient.OccupiedResource(
71L, 72L, 0, 101L, 73L, 74L, "A-01", false, 2))));
BatchRequest request = new BatchRequest(101L, 10L, 99L, 0, "0".repeat(64), List.of(
new BatchItemRequest(30L, "PICK", 2, null, "MANUAL", List.of(), 0, null)));
new BatchItemRequest(30L, "PICK", 2, null, 0, null)));
assertThatThrownBy(() -> service.batch(20L, "batch-inventory-stale", request, 9L, "operator"))
.isInstanceOf(BizException.class)
.hasMessageContaining("库存已变化");
verify(repository, never()).pick(any(Long.class), any(Integer.class), any(), any(),
verify(repository, never()).pick(any(Long.class), any(Integer.class),
any(Integer.class), any(Long.class));
verify(repository, never()).touchTask(any(Long.class), any(Integer.class));
verify(settlementService, never()).settle(20L, 9L, "operator");
@@ -1232,7 +1237,7 @@ class LoadingPickServiceTest {
task.setVersion(3);
when(repository.taskForUpdate(20L)).thenReturn(task);
BatchRequest request = new BatchRequest(101L, 10L, 99L, 2, "stale-token", List.of(
new BatchItemRequest(30L, "PICK", 2, null, "AUTO", null, 0, null)));
new BatchItemRequest(30L, "PICK", 2, null, 0, null)));
assertThatThrownBy(() -> service.batch(20L, "batch-stale", request, 9L, "operator"))
.isInstanceOf(BizException.class);
@@ -1250,15 +1255,14 @@ class LoadingPickServiceTest {
when(repository.assignment(20L)).thenReturn(assignment());
when(repository.items(20L)).thenReturn(List.of(item));
when(repository.items(20L, 101L)).thenReturn(List.of(item));
when(repository.pick(30L, 2, "MANUAL", "[]", 0, 101L)).thenReturn(1);
when(repository.pick(30L, 2, 0, 101L)).thenReturn(1);
when(repository.allTaskItemsResolved(20L)).thenReturn(true);
when(repository.touchTask(20L, 0)).thenReturn(1);
when(warehouse.occupiedResources(any(), any(Long.class), any(), any(Long.class))).thenReturn(
ApiResponse.success(List.of(new WarehousePalletLocationClient.OccupiedResource(
71L, 72L, 0, 101L, 73L, 74L, "A-01", false, 2))));
String snapshotToken = service.inventorySnapshot(20L, 101L).snapshotToken();
BatchItemRequest line = new BatchItemRequest(
30L, "PICK", 2, null, "MANUAL", List.of(), 0, null);
BatchItemRequest line = new BatchItemRequest(30L, "PICK", 2, null, 0, null);
assertThatThrownBy(() -> service.batch(20L, "batch-stale", new BatchRequest(
101L, 10L, 99L, 1, snapshotToken, List.of(line)), 9L, "operator"))
@@ -1270,7 +1274,7 @@ class LoadingPickServiceTest {
service.batch(20L, "batch-valid", new BatchRequest(
101L, 10L, 99L, 0, snapshotToken, List.of(line)), 9L, "operator");
verify(repository, times(1)).pick(30L, 2, "MANUAL", "[]", 0, 101L);
verify(repository, times(1)).pick(30L, 2, 0, 101L);
verify(repository, times(1)).touchTask(20L, 0);
}
@@ -1291,7 +1295,7 @@ class LoadingPickServiceTest {
BatchRequest staleRequest = new BatchRequest(101L, 10L, 99L, 1,
"stale-token", List.of(
new BatchItemRequest(30L, "PICK", 2, null, "AUTO", null, 0, null)));
new BatchItemRequest(30L, "PICK", 2, null, 0, null)));
assertThatThrownBy(() -> service.batch(20L, "batch-stale-after-resync", staleRequest,
9L, "operator")).isInstanceOf(BizException.class);
@@ -1299,7 +1303,7 @@ class LoadingPickServiceTest {
assertThat(pending.getPickedPackageCount()).isZero();
assertThat(pending.getItemStatus()).isEqualTo("PENDING");
verify(repository, never()).update(any(LoadingPickItemEntity.class));
verify(repository, never()).pick(any(Long.class), any(Integer.class), any(), any(),
verify(repository, never()).pick(any(Long.class), any(Integer.class),
any(Integer.class), any(Long.class));
verify(repository, never()).touchTask(any(Long.class), any(Integer.class));
}
@@ -1318,7 +1322,7 @@ class LoadingPickServiceTest {
when(repository.taskForUpdate(20L)).thenReturn(task);
when(repository.assignment(20L)).thenReturn(assignment());
when(repository.item(20L, 30L, 101L)).thenReturn(item);
when(repository.pick(30L, 2, "MANUAL", "[]", 0, 101L)).thenReturn(1);
when(repository.pick(30L, 2, 0, 101L)).thenReturn(1);
when(repository.touchTask(20L, 0)).thenReturn(1);
when(repository.items(20L, 101L)).thenReturn(List.of(item));
}
@@ -1329,7 +1333,7 @@ class LoadingPickServiceTest {
when(repository.taskForUpdate(20L)).thenReturn(task);
when(repository.assignment(20L)).thenReturn(assignment());
when(repository.item(20L, 30L, 101L)).thenReturn(item);
when(repository.partial(30L, 1, "MANUAL", "[]", 0, 101L)).thenReturn(1);
when(repository.partial(30L, 1, 0, 101L)).thenReturn(1);
when(repository.touchTask(20L, 0)).thenReturn(1);
when(repository.items(20L, 101L)).thenReturn(List.of(item));
}