feat(phase3): 收口父子单与全链路验收

This commit is contained in:
2026-08-10 12:23:43 +08:00
parent b294695169
commit 75d5fd4e26
55 changed files with 1110 additions and 115 deletions
@@ -57,6 +57,8 @@ class OpenApiInboundMeasurementControllerContractTest {
.contains("Nonce")
.contains("inboundDetailId")
.contains("multipart/form-data")
.contains("required: [boxCode, shipment_id, length, width, height, machineNo, picture]")
.contains("shipment_id:")
.contains("不改变入库单状态");
}
}
@@ -48,12 +48,14 @@ class PlatformCartonScanControllerTest {
.setCustomArgumentResolvers(authenticationPrincipal(user))
.build();
when(cartonMeasurements.upsertForInbound(eq(10001L), eq(90001L), eq(70001L), any()))
.thenReturn(new CartonMeasurementResult(30001L, 1, 40001L, "RK-001#5-1", 1,
.thenReturn(new CartonMeasurementResult(30001L, 1, 40001L, "RK-001#5-1",
"FBA-SCAN-001", 1,
new BigDecimal("60.1"), new BigDecimal("40.2"), new BigDecimal("30.3"),
new BigDecimal("12.5"), 99001L, "SIM-01",
LocalDateTime.parse("2026-08-07T10:30:00"), true));
MockPart data = new MockPart("data", "data", ("""
{"boxCode":"RK-001#5-1","length":60.1,"width":40.2,"height":30.3,
{"boxCode":"RK-001#5-1","scannedShipmentId":"FBA-SCAN-001",
"length":60.1,"width":40.2,"height":30.3,
"weight":12.5,"machineNo":"SIM-01","measuredAt":"2026-08-07T10:30:00"}
""").getBytes(java.nio.charset.StandardCharsets.UTF_8));
data.getHeaders().setContentType(MediaType.APPLICATION_JSON);
@@ -70,6 +72,7 @@ class PlatformCartonScanControllerTest {
verify(cartonMeasurements).upsertForInbound(
eq(10001L), eq(90001L), eq(70001L), command.capture());
assertThat(command.getValue().machineNo()).isEqualTo("SIM-01");
assertThat(command.getValue().scannedShipmentId()).isEqualTo("FBA-SCAN-001");
assertThat(command.getValue().image().getOriginalFilename()).isEqualTo("carton.jpg");
}
@@ -22,6 +22,7 @@ class MojiaMeasurementReceiptSqlContractTest {
assertThat(sql)
.contains("CREATE TABLE IF NOT EXISTS fl_mojia_measurement_receipt")
.contains("box_code VARCHAR(128) NOT NULL")
.contains("scanned_shipment_id VARCHAR(64) NULL")
.contains("image_file_id BIGINT UNSIGNED NOT NULL")
.contains("status VARCHAR(24) NOT NULL DEFAULT 'UNMATCHED'")
.contains("idx_mojia_receipt_status_time")
@@ -29,6 +30,7 @@ class MojiaMeasurementReceiptSqlContractTest {
}
assertThat(unified)
.contains("墨家未匹配测量收件箱字段未完整创建")
.contains("箱级测量实扫Shipment ID字段未创建")
.contains("测量计算规则版本字段长度不是64");
}
}
@@ -86,6 +86,8 @@ class CartonMeasurementServiceTest {
assertThat(result.created()).isTrue();
assertThat(result.confirmedPackageCount()).isEqualTo(1);
assertThat(result.boxCode()).isEqualTo("RK-001#5-1");
assertThat(result.scannedShipmentId()).isEqualTo("FBA-SCAN-002");
assertThat(insertedItem.get().getScannedShipmentId()).isEqualTo("FBA-SCAN-002");
assertThat(insertedItem.get().getMeasurementId()).isEqualTo(30001L);
assertThat(insertedItem.get().getTotalVolumeCbm()).isEqualByComparingTo("0.1870");
assertThat(insertedItem.get().getOuterLengthCm()).isEqualByComparingTo("64.000");
@@ -112,6 +114,7 @@ class CartonMeasurementServiceTest {
assertThat(existing.getTotalVolumeCbm()).isEqualByComparingTo("0.7480");
assertThat(existing.getVolumeWeightKg()).isEqualByComparingTo("124.916");
assertThat(existing.getSourceImageFileId()).isEqualTo(99001L);
assertThat(existing.getScannedShipmentId()).isEqualTo("FBA-SCAN-002");
verify(images).delete("internal-token", 90001L, 10001L, 70001L, 88001L);
}
@@ -126,7 +129,8 @@ class CartonMeasurementServiceTest {
"RK-001#5-1", new BigDecimal("60.100"), new BigDecimal("50.100"),
new BigDecimal("50.100"), new BigDecimal("12.500"), "MJ-01",
LocalDateTime.parse("2026-08-07T10:30:00"),
new MockMultipartFile("image", "measure.jpg", "image/jpeg", "image".getBytes()));
new MockMultipartFile("image", "measure.jpg", "image/jpeg", "image".getBytes()),
"FBA-SCAN-001");
CartonMeasurementResult result = service.upsert(10001L, 90001L, oversize);
@@ -253,7 +257,8 @@ class CartonMeasurementServiceTest {
return new CartonMeasurementCommand("RK-001#5-1", new BigDecimal("59.100"),
new BigDecimal("40.200"), new BigDecimal("30.300"), new BigDecimal("12.500"),
"MJ-01", LocalDateTime.parse("2026-08-07T10:30:00"),
new MockMultipartFile("image", "measure.jpg", "image/jpeg", "image".getBytes()));
new MockMultipartFile("image", "measure.jpg", "image/jpeg", "image".getBytes()),
"FBA-SCAN-001");
}
private CartonMeasurementCommand acceptanceCommand() {
@@ -261,7 +266,8 @@ class CartonMeasurementServiceTest {
"RK-001#5-1", new BigDecimal("59.500"), new BigDecimal("41.200"),
new BigDecimal("31.300"), new BigDecimal("13.600"), "MJ-ADMIN-E2E-02",
LocalDateTime.parse("2026-08-08T10:01:00"),
new MockMultipartFile("image", "measure.jpg", "image/jpeg", "image".getBytes()));
new MockMultipartFile("image", "measure.jpg", "image/jpeg", "image".getBytes()),
"FBA-SCAN-002");
}
private InboundOrderEntity inbound(String status) {
@@ -6,6 +6,7 @@ import com.baiyue.common.core.exception.BizException;
import com.baiyue.firstleg.client.MeasurementImageClient;
import com.baiyue.firstleg.dto.CartonMeasurementCommand;
import com.baiyue.firstleg.dto.CartonMeasurementResult;
import com.baiyue.firstleg.dto.MojiaMeasurementDtos.UploadRequest;
import com.baiyue.firstleg.dto.MojiaMeasurementDtos.UploadResponse;
import com.baiyue.firstleg.entity.MojiaMeasurementReceiptEntity;
import com.baiyue.firstleg.repository.MojiaMeasurementReceiptRepository;
@@ -21,6 +22,7 @@ import org.springframework.test.util.ReflectionTestUtils;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -30,6 +32,23 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
class MojiaMeasurementOpenApiServiceTest {
@Test
void shipmentIdIsRequiredAndCamelCaseAliasIsAccepted() throws Exception {
ObjectMapper mapper = new ObjectMapper().findAndRegisterModules();
var validator = Validation.buildDefaultValidatorFactory().getValidator();
UploadRequest camelCase = mapper.readValue(
json().replace("\"shipment_id\"", "\"shipmentId\""), UploadRequest.class);
UploadRequest missing = mapper.readValue(
json().replace("\"shipment_id\":\"FBA19L5KMY2CU000002\",", ""), UploadRequest.class);
assertThat(camelCase.shipmentId()).isEqualTo("FBA19L5KMY2CU000002");
assertThat(validator.validate(camelCase)).isEmpty();
assertThat(validator.validate(missing).stream()
.map(violation -> violation.getPropertyPath().toString()).collect(java.util.stream.Collectors.toSet()))
.isEqualTo(Set.of("shipmentId"));
}
@Test
void fixedAppKeyJsonIsConvertedToTheExistingCartonMeasurementFlow() throws Exception {
MeasurementRequestAuthenticator authenticator = mock(MeasurementRequestAuthenticator.class);
@@ -43,7 +62,8 @@ class MojiaMeasurementOpenApiServiceTest {
when(authenticator.authenticate("POST", MojiaMeasurementOpenApiService.CALLBACK_PATH,
headers, json(), false)).thenReturn(new AuthenticatedMeasurementApp("mojia", 10001L, 90001L, Map.of()));
when(cartons.upsert(eq(10001L), eq(90001L), any())).thenReturn(new CartonMeasurementResult(
1L, 1, 2L, "RK-001#4-1", 1, new BigDecimal("60.1"), new BigDecimal("40.2"),
1L, 1, 2L, "RK-001#4-1", "FBA19L5KMY2CU000002", 1,
new BigDecimal("60.1"), new BigDecimal("40.2"),
new BigDecimal("30.3"), new BigDecimal("12.5"), 3L, "MJ-01", LocalDateTime.now(), true));
UploadResponse result = service.receive(headers, json());
@@ -53,6 +73,7 @@ class MojiaMeasurementOpenApiServiceTest {
ArgumentCaptor<CartonMeasurementCommand> command = ArgumentCaptor.forClass(CartonMeasurementCommand.class);
verify(cartons).upsert(eq(10001L), eq(90001L), command.capture());
assertThat(command.getValue().boxCode()).isEqualTo("RK-001#4-1");
assertThat(command.getValue().scannedShipmentId()).isEqualTo("FBA19L5KMY2CU000002");
assertThat(command.getValue().lengthCm()).isEqualByComparingTo("60.1");
assertThat(command.getValue().image().getContentType()).isEqualTo("image/jpeg");
assertThat(command.getValue().image().getBytes()).containsExactly(0xff, 0xd8, 0xff, 0xd9);
@@ -87,6 +108,7 @@ class MojiaMeasurementOpenApiServiceTest {
ArgumentCaptor.forClass(MojiaMeasurementReceiptEntity.class);
verify(receipts).insert(receipt.capture());
assertThat(receipt.getValue().getBoxCode()).isEqualTo("RK-001#4-1");
assertThat(receipt.getValue().getScannedShipmentId()).isEqualTo("FBA19L5KMY2CU000002");
assertThat(receipt.getValue().getLengthCm()).isEqualByComparingTo("60.1");
assertThat(receipt.getValue().getImageFileId()).isEqualTo(3L);
assertThat(receipt.getValue().getStatus()).isEqualTo("UNMATCHED");
@@ -94,7 +116,8 @@ class MojiaMeasurementOpenApiServiceTest {
private String json() {
return """
{"boxCode":"RK-001#4-1","length":60.1,"width":40.2,"height":30.3,
{"boxCode":"RK-001#4-1","shipment_id":"FBA19L5KMY2CU000002",
"length":60.1,"width":40.2,"height":30.3,
"weight":12.5,"machineNo":"MJ-01","picture":"data:image/jpeg;base64,/9j/2Q=="}
""";
}