This commit is contained in:
2026-08-12 14:37:45 +08:00
parent d183ad6330
commit fcb7c11af4
7 changed files with 162 additions and 13 deletions
@@ -120,6 +120,26 @@ public class PlatformInboundMeasurementController {
tenantId, user.userId(), inboundId, command));
}
@BusinessAudit(event = "INBOUND_CARTON_MANUAL_ENTRY", resourceType = "INBOUND",
resourceId = "#inboundId", description = "平台人工录入单箱测量")
@Operation(summary = "平台人工录入单箱测量",
description = "data 中传箱号和人工测量值,image 传当前箱图片,复用正式单箱覆盖规则。")
@PostMapping(value = "/measurement/manual-cartons", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@PreAuthorize("hasAuthority('platform:firstleg:inbound:measure:edit')")
public ApiResponse<CartonMeasurementResult> createManualCarton(
@AuthenticationPrincipal AuthenticatedUser user,
@RequestParam long tenantId,
@PathVariable long inboundId,
@Valid @RequestPart("data") InboundMeasurementRequests.CartonScanRequest request,
@RequestPart("image") MultipartFile image) {
requirePlatformTenant(user, tenantId);
CartonMeasurementCommand command = new CartonMeasurementCommand(
request.boxCode(), request.length(), request.width(), request.height(), request.weight(),
request.machineNo(), request.measuredAt(), image, request.scannedShipmentId());
return ApiResponse.success(cartonMeasurements.upsertManualForInbound(
tenantId, user.userId(), inboundId, command));
}
@BusinessAudit(event = "INBOUND_WEIGHT_OCR_RECORD", resourceType = "INBOUND",
resourceId = "#inboundId", description = "登记称重图片 OCR 原值")
@Operation(summary = "登记 OCR 重量结果", description = "按图片文件 ID 保存不可覆盖的 OCR 原值。")
@@ -64,7 +64,7 @@ public final class InboundMeasurementRequests {
) {
}
/** 平台联调使用;最终设备协议在外部适配层转换为相同领域命令。 */
/** 平台设备联调及人工录入使用;设备协议在外部适配层转换为相同领域命令。 */
public record CartonScanRequest(
@NotBlank @Size(max = 128) String boxCode,
@NotNull @DecimalMin("0.001") @Digits(integer = 9, fraction = 3) BigDecimal length,
@@ -60,7 +60,8 @@ public class CartonMeasurementService {
}
public CartonMeasurementResult upsert(long tenantId, long operatorId, CartonMeasurementCommand command) {
return upsert(tenantId, operatorId, null, command);
return upsert(tenantId, operatorId, null, command,
MeasurementBatchService.SOURCE_THIRD_PARTY, "DEVICE");
}
public CartonMeasurementResult upsertForInbound(long tenantId, long operatorId, long inboundId,
@@ -68,11 +69,22 @@ public class CartonMeasurementService {
if (inboundId <= 0) {
throw new BizException(ResultCode.BAD_REQUEST, "入库单ID必须大于0");
}
return upsert(tenantId, operatorId, inboundId, command);
return upsert(tenantId, operatorId, inboundId, command,
MeasurementBatchService.SOURCE_THIRD_PARTY, "DEVICE");
}
public CartonMeasurementResult upsertManualForInbound(long tenantId, long operatorId, long inboundId,
CartonMeasurementCommand command) {
if (inboundId <= 0) {
throw new BizException(ResultCode.BAD_REQUEST, "入库单ID必须大于0");
}
return upsert(tenantId, operatorId, inboundId, command,
MeasurementBatchService.SOURCE_MANUAL, "PLATFORM");
}
private CartonMeasurementResult upsert(long tenantId, long operatorId, Long expectedInboundId,
CartonMeasurementCommand command) {
CartonMeasurementCommand command,
String sourceType, String sourceCode) {
validateCommand(command);
String boxCode = command.boxCode().trim();
CartonLabelBindingResolver.Binding binding = requireBinding(tenantId, boxCode);
@@ -85,7 +97,7 @@ public class CartonMeasurementService {
UpsertOutcome outcome;
try {
outcome = transactionTemplate.execute(status -> persist(
tenantId, operatorId, binding, boxCode, command, uploaded.fileId()));
tenantId, operatorId, binding, boxCode, command, uploaded.fileId(), sourceType, sourceCode));
} catch (RuntimeException exception) {
cleanupImage(tenantId, operatorId, inbound.getId(), uploaded.fileId(), "回传落库失败补偿");
throw exception;
@@ -150,8 +162,8 @@ public class CartonMeasurementService {
private UpsertOutcome persist(long tenantId, long operatorId,
CartonLabelBindingResolver.Binding binding,
String boxCode,
CartonMeasurementCommand command, long imageFileId) {
String boxCode, CartonMeasurementCommand command, long imageFileId,
String sourceType, String sourceCode) {
InboundOrderEntity inbound = repository.lockInbound(tenantId, binding.inboundId());
if (inbound == null) {
throw new BizException(ResultCode.NOT_FOUND, "入库单不存在");
@@ -166,7 +178,7 @@ public class CartonMeasurementService {
if (created) {
measurement = repository.findLatestEditableMeasurement(tenantId, inbound.getId());
if (measurement == null) {
measurement = newMeasurement(tenantId, operatorId, inbound.getId());
measurement = newMeasurement(tenantId, operatorId, inbound.getId(), sourceType, sourceCode);
repository.insertMeasurement(measurement);
}
item = new InboundMeasurementItemEntity();
@@ -208,8 +220,8 @@ public class CartonMeasurementService {
}
measurement.setStatus(MeasurementBatchService.STATUS_RECEIVED);
measurement.setSourceType(MeasurementBatchService.SOURCE_THIRD_PARTY);
measurement.setSourceCode("DEVICE");
measurement.setSourceType(sourceType);
measurement.setSourceCode(sourceCode);
measurement.setDeviceCode(command.machineNo().trim());
measurement.setMeasuredAt(command.measuredAt());
measurement.setUpdatedAt(LocalDateTime.now());
@@ -220,13 +232,14 @@ public class CartonMeasurementService {
return new UpsertOutcome(result(measurement, item, created), oldImageFileId);
}
private InboundMeasurementEntity newMeasurement(long tenantId, long operatorId, long inboundId) {
private InboundMeasurementEntity newMeasurement(long tenantId, long operatorId, long inboundId,
String sourceType, String sourceCode) {
InboundMeasurementEntity measurement = new InboundMeasurementEntity();
measurement.setId(IdWorker.getId());
measurement.setTenantId(tenantId);
measurement.setInboundId(inboundId);
measurement.setSourceType(MeasurementBatchService.SOURCE_THIRD_PARTY);
measurement.setSourceCode("DEVICE");
measurement.setSourceType(sourceType);
measurement.setSourceCode(sourceCode);
measurement.setStatus(MeasurementBatchService.STATUS_RECEIVED);
measurement.setCreatedBy(operatorId);
measurement.setCreatedAt(LocalDateTime.now());