fix(firstleg): require real container before pda push

This commit is contained in:
2026-08-14 22:03:21 +08:00
parent fdd011bc57
commit 010098c4af
7 changed files with 71 additions and 13 deletions
@@ -26,5 +26,11 @@ class PlatformSmartLoadingControllerContractTest {
authority("delete","platform:firstleg:smart-loading:delete",AuthenticatedUser.class,long.class,long.class,DeleteRequest.class);
authority("push","platform:firstleg:smart-loading:push",AuthenticatedUser.class,long.class,String.class,PushRequest.class);
}
@Test void openApiRequiresRealContainerNumberBeforePreloadPush() throws Exception {
String yaml=java.nio.file.Files.readString(java.nio.file.Path.of("src/main/resources/openapi/firstleg-v1.yaml"));
assertThat(yaml).contains("/api/platform/v1/first-leg/smart-loading/plans/{planId}/push-preload:")
.contains("真实柜号必须已录入")
.contains("PDA作业任务");
}
private void authority(String method,String permission,Class<?>...types)throws Exception{Method m=PlatformSmartLoadingController.class.getDeclaredMethod(method,types);assertThat(m.getAnnotation(PreAuthorize.class).value()).isEqualTo("hasAuthority('"+permission+"')");}
}
@@ -20,6 +20,8 @@ class OceanBookingSqlContractTest {
.contains("CREATE TABLE IF NOT EXISTS fl_ocean_booking_operation")
.contains("customer_id BIGINT UNSIGNED NULL COMMENT '可选客户ID快照'")
.contains("customer_name VARCHAR(128) NULL COMMENT '可选客户名称快照'")
.contains("MODIFY COLUMN customer_id BIGINT UNSIGNED NULL COMMENT '可选客户ID快照'")
.contains("MODIFY COLUMN customer_name VARCHAR(128) NULL COMMENT '可选客户名称快照'")
.contains("service_term VARCHAR(32) NOT NULL COMMENT '运输服务条款快照'")
.contains("freight_term VARCHAR(32) NOT NULL COMMENT '海运费支付条款快照'")
.contains("container_booking_id BIGINT UNSIGNED NOT NULL COMMENT '明确引用现有柜次ID'")
@@ -387,10 +387,9 @@ class SmartLoadingServiceTest {
}
@Test
void rejectsOverweightPlanBeforePushEvenWithoutContainerNumber() {
void rejectsOverweightPlanBeforePush() {
LoadingPlanEntity editing = plan("EDITING", 1);
ContainerBookingEntity booking = booking();
booking.setContainerNo(null);
booking.setMaxWeightKg(new BigDecimal("1"));
LoadingPlanItemEntity overweight = item(8, 9, 20, 1);
overweight.setGrossWeightKg(new BigDecimal("2"));
@@ -409,21 +408,39 @@ class SmartLoadingServiceTest {
}
@Test
void pushesWithoutContainerNumberWhenCapacityIsWithinLimit() {
void rejectsPushWithoutContainerNumberBeforePdaOpening() {
LoadingPlanEntity editing = plan("EDITING", 1);
LoadingPlanEntity pushed = plan("EDITING", 2);
ContainerBookingEntity booking = booking();
booking.setContainerNo(null);
when(repository.plan(1)).thenReturn(editing, pushed);
when(repository.plan(1)).thenReturn(editing);
when(repository.booking(99)).thenReturn(booking);
when(repository.items(1)).thenReturn(List.of(item(8, 9, 20, 1)));
when(repository.push(1, "no-container-key", 1, 7, "u")).thenReturn(1);
Plan result = service.pushPreload(1, "no-container-key", new PushRequest(1), 7, "u");
BizException error = catchThrowableOfType(
() -> service.pushPreload(1, "no-container-key", new PushRequest(1), 7, "u"),
BizException.class);
assertThat(result.status()).isEqualTo("EDITING");
verify(repository).push(1, "no-container-key", 1, 7, "u");
verify(loadingPickService).beginIfReady(99L, 7L, "u");
assertThat(error.getResultCode()).isEqualTo(ResultCode.VALIDATION_FAILED);
assertThat(error.getMessage()).contains("真实柜号");
verify(repository, never()).push(anyLong(), anyString(), anyInt(), anyLong(), anyString());
verify(loadingPickService, never()).beginIfReady(anyLong(), anyLong(), anyString());
}
@Test
void rejectsReplayWhenTheContainerNumberIsStillMissing() {
LoadingPlanEntity pushed = plan("EDITING", 2);
pushed.setPushIdempotencyKey("replay-key");
ContainerBookingEntity booking = booking();
booking.setContainerNo(" ");
when(repository.plan(1)).thenReturn(pushed);
when(repository.booking(99)).thenReturn(booking);
BizException error = catchThrowableOfType(
() -> service.pushPreload(1, "replay-key", new PushRequest(2), 7, "u"),
BizException.class);
assertThat(error.getResultCode()).isEqualTo(ResultCode.VALIDATION_FAILED);
verify(repository, never()).push(anyLong(), anyString(), anyInt(), anyLong(), anyString());
verify(loadingPickService, never()).beginIfReady(anyLong(), anyLong(), anyString());
}
private void stubAssignment() {