This commit is contained in:
2026-09-20 10:06:14 +08:00
parent d5c4059942
commit 507763a0d6
12 changed files with 199 additions and 24 deletions
@@ -52,6 +52,19 @@ public class InboundCartonLabelRepository {
.eq(InboundCartonLabelEntity::getBoxCode, boxCode));
}
public List<InboundCartonLabelEntity> findGloballyByBoxCode(String boxCode) {
return labels.selectList(new LambdaQueryWrapper<InboundCartonLabelEntity>()
.eq(InboundCartonLabelEntity::getBoxCode, boxCode)
.last("LIMIT 2"));
}
public InboundOrderEntity findInbound(long tenantId, long inboundId) {
return inbounds.selectOne(new LambdaQueryWrapper<InboundOrderEntity>()
.eq(InboundOrderEntity::getTenantId, tenantId)
.eq(InboundOrderEntity::getId, inboundId)
.eq(InboundOrderEntity::getDeleted, false));
}
public void initializeLegacyFingerprint(long tenantId, long inboundId, int version, String fingerprint) {
labels.update(null, new LambdaUpdateWrapper<InboundCartonLabelEntity>()
.eq(InboundCartonLabelEntity::getTenantId, tenantId)
@@ -45,7 +45,7 @@ public class MeasurementRequestAuthenticator {
MeasurementOpenApiProperties.AppCredential credential = properties.getApps().get(headers.appKey());
if (credential == null || !credential.isEnabled()
|| properties.isSignatureRequired() && !StringUtils.hasText(credential.getSecret())
|| credential.getTenantId() == null || credential.getTenantId() <= 0
|| credential.getTenantId() == null || credential.getTenantId() < 0
|| credential.getSubjectId() == null || credential.getSubjectId() <= 0) {
throw unauthorized("应用凭据无效");
}
@@ -154,9 +154,28 @@ public class InboundCartonLabelService implements CartonLabelBindingResolver {
@Override
public CartonLabelBindingResolver.Binding resolveByBoxCode(long tenantId, String boxCode) {
InboundCartonLabelEntity label = requireByBoxCode(tenantId, boxCode);
return new CartonLabelBindingResolver.Binding(label.getInboundId(), label.getInboundDetailId(),
label.getInboundCode(), label.getCartonIndex(), label.getTotalCartonCount(),
label.getBoxSpecification());
return binding(label);
}
public PlatformBinding resolvePlatformByBoxCode(String boxCode) {
if (!StringUtils.hasText(boxCode)) {
throw new BizException(ResultCode.BAD_REQUEST, "箱号不能为空");
}
List<InboundCartonLabelEntity> matches = repository.findGloballyByBoxCode(boxCode.trim());
if (matches.isEmpty()) throw new BizException(ResultCode.NOT_FOUND, "箱号不存在");
if (matches.size() != 1) {
throw new BizException(ResultCode.CONFLICT, "箱号归属不唯一,禁止设备写入");
}
InboundCartonLabelEntity label = matches.get(0);
if ("VOID".equals(label.getBatchStatus())) {
throw new BizException(ResultCode.CONFLICT, "箱码已失效,请重新打印");
}
InboundOrderEntity inbound = repository.findInbound(label.getTenantId(), label.getInboundId());
if (inbound == null) throw new BizException(ResultCode.NOT_FOUND, "箱号关联的入库单不存在");
if (inbound.getWarehouseId() == null || inbound.getWarehouseId() <= 0) {
throw new BizException(ResultCode.CONFLICT, "入库单未绑定有效国内仓库");
}
return new PlatformBinding(label.getTenantId(), inbound.getWarehouseId(), binding(label));
}
public InboundCartonLabels.Resolution resolveDetailsByBoxCode(long tenantId, String boxCode) {
@@ -179,6 +198,16 @@ public class InboundCartonLabelService implements CartonLabelBindingResolver {
return label;
}
private CartonLabelBindingResolver.Binding binding(InboundCartonLabelEntity label) {
return new CartonLabelBindingResolver.Binding(label.getInboundId(), label.getInboundDetailId(),
label.getInboundCode(), label.getCartonIndex(), label.getTotalCartonCount(),
label.getBoxSpecification());
}
public record PlatformBinding(long tenantId, long warehouseId,
CartonLabelBindingResolver.Binding binding) {
}
private List<OrderCargoClient.CargoLabelBinding> loadCargoes(InboundOrderEntity inbound) {
try {
ApiResponse<List<OrderCargoClient.CargoLabelBinding>> response = orderCargoClient.listForCartonLabels(
@@ -48,6 +48,7 @@ public class MojiaMeasurementOpenApiService {
private final Validator validator;
private final MeasurementImageClient imageClient;
private final MojiaMeasurementReceiptRepository receipts;
private final InboundCartonLabelService cartonLabels;
@Value("${baiyue.security.internal-service-token}")
private String internalToken;
@@ -57,13 +58,15 @@ public class MojiaMeasurementOpenApiService {
ObjectMapper objectMapper,
Validator validator,
MeasurementImageClient imageClient,
MojiaMeasurementReceiptRepository receipts) {
MojiaMeasurementReceiptRepository receipts,
InboundCartonLabelService cartonLabels) {
this.authenticator = authenticator;
this.cartonMeasurements = cartonMeasurements;
this.objectMapper = objectMapper;
this.validator = validator;
this.imageClient = imageClient;
this.receipts = receipts;
this.cartonLabels = cartonLabels;
}
public UploadResponse receive(MeasurementRequestHeaders headers, String rawJson) {
@@ -73,10 +76,26 @@ public class MojiaMeasurementOpenApiService {
"POST", CALLBACK_PATH, headers, rawJson, false);
request = parseAndValidate(rawJson);
MultipartFile image = decodeJpeg(request.picture());
if (app.tenantId() != 0) {
throw new BizException(ResultCode.UNAUTHORIZED, "墨家设备必须使用平台级应用凭据");
}
long machineWarehouseId = requireMachineWarehouse(app, request.machineNo());
final InboundCartonLabelService.PlatformBinding platformBinding;
try {
platformBinding = cartonLabels.resolvePlatformByBoxCode(request.boxCode());
} catch (BizException exception) {
if (exception.getResultCode() == ResultCode.NOT_FOUND) {
return saveUnmatched(app, request, image, exception);
}
throw exception;
}
if (platformBinding.warehouseId() != machineWarehouseId) {
throw new BizException(ResultCode.FORBIDDEN, "箱号不属于当前设备绑定仓库");
}
CartonMeasurementResult result;
try {
result = cartonMeasurements.upsert(
app.tenantId(), app.subjectId(), new CartonMeasurementCommand(
platformBinding.tenantId(), app.subjectId(), new CartonMeasurementCommand(
request.boxCode(), request.length(), request.width(), request.height(),
request.machineNo(), request.measuredAt() == null ? LocalDateTime.now() : request.measuredAt(),
image, optionalTrim(request.shipmentId())));
@@ -106,6 +125,14 @@ public class MojiaMeasurementOpenApiService {
}
}
private long requireMachineWarehouse(AuthenticatedMeasurementApp app, String machineNo) {
Long warehouseId = app.warehouseBindings().get(machineNo.trim());
if (warehouseId == null || warehouseId <= 0) {
throw new BizException(ResultCode.UNAUTHORIZED, "设备编号未绑定有效仓库");
}
return warehouseId;
}
private UploadResponse saveUnmatched(AuthenticatedMeasurementApp app, UploadRequest request,
MultipartFile image, BizException matchFailure) {
long receiptId = IdWorker.getId();