优化
This commit is contained in:
+43
-7
@@ -12,6 +12,9 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jakarta.validation.ConstraintViolation;
|
import jakarta.validation.ConstraintViolation;
|
||||||
import jakarta.validation.Validator;
|
import jakarta.validation.Validator;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.slf4j.MDC;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
@@ -27,6 +30,7 @@ import java.util.Set;
|
|||||||
/** 将墨家固定 AppKey + JSON/Base64 协议转换为统一单箱测量命令。 */
|
/** 将墨家固定 AppKey + JSON/Base64 协议转换为统一单箱测量命令。 */
|
||||||
@Service
|
@Service
|
||||||
public class MojiaMeasurementOpenApiService {
|
public class MojiaMeasurementOpenApiService {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(MojiaMeasurementOpenApiService.class);
|
||||||
static final String CALLBACK_PATH = "/openapi/v1/inbound-measurements";
|
static final String CALLBACK_PATH = "/openapi/v1/inbound-measurements";
|
||||||
private static final String JPEG_PREFIX = "data:image/jpeg;base64,";
|
private static final String JPEG_PREFIX = "data:image/jpeg;base64,";
|
||||||
private static final long MAX_IMAGE_BYTES = 5L * 1024 * 1024;
|
private static final long MAX_IMAGE_BYTES = 5L * 1024 * 1024;
|
||||||
@@ -47,13 +51,34 @@ public class MojiaMeasurementOpenApiService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CartonMeasurementResult receive(MeasurementRequestHeaders headers, String rawJson) {
|
public CartonMeasurementResult receive(MeasurementRequestHeaders headers, String rawJson) {
|
||||||
AuthenticatedMeasurementApp app = authenticator.authenticate(
|
UploadRequest request = null;
|
||||||
"POST", CALLBACK_PATH, headers, rawJson, false);
|
try {
|
||||||
UploadRequest request = parseAndValidate(rawJson);
|
AuthenticatedMeasurementApp app = authenticator.authenticate(
|
||||||
MultipartFile image = decodeJpeg(request.picture());
|
"POST", CALLBACK_PATH, headers, rawJson, false);
|
||||||
return cartonMeasurements.upsert(app.tenantId(), app.subjectId(), new CartonMeasurementCommand(
|
request = parseAndValidate(rawJson);
|
||||||
request.boxCode(), request.length(), request.width(), request.height(), request.weight(),
|
MultipartFile image = decodeJpeg(request.picture());
|
||||||
request.machineNo(), request.measuredAt() == null ? LocalDateTime.now() : request.measuredAt(), image));
|
CartonMeasurementResult result = cartonMeasurements.upsert(
|
||||||
|
app.tenantId(), app.subjectId(), new CartonMeasurementCommand(
|
||||||
|
request.boxCode(), request.length(), request.width(), request.height(), request.weight(),
|
||||||
|
request.machineNo(), request.measuredAt() == null ? LocalDateTime.now() : request.measuredAt(),
|
||||||
|
image));
|
||||||
|
log.info("MOJIA_MEASUREMENT accepted requestId={} traceId={} boxCode={} machineNo={} "
|
||||||
|
+ "lengthCm={} widthCm={} heightCm={} weightKg={} imageBytes={} measurementId={} "
|
||||||
|
+ "itemId={} created={}",
|
||||||
|
correlation("requestId"), correlation("traceId"), safe(request.boxCode()),
|
||||||
|
safe(request.machineNo()), request.length(), request.width(), request.height(), request.weight(),
|
||||||
|
image.getSize(), result.measurementId(), result.itemId(), result.created());
|
||||||
|
return result;
|
||||||
|
} catch (RuntimeException exception) {
|
||||||
|
String code = exception instanceof BizException biz ? biz.getResultCode().code() : "S0500";
|
||||||
|
log.warn("MOJIA_MEASUREMENT rejected requestId={} traceId={} boxCode={} machineNo={} "
|
||||||
|
+ "payloadChars={} code={} reason={}",
|
||||||
|
correlation("requestId"), correlation("traceId"),
|
||||||
|
request == null ? "unparsed" : safe(request.boxCode()),
|
||||||
|
request == null ? "unparsed" : safe(request.machineNo()),
|
||||||
|
rawJson == null ? 0 : rawJson.length(), code, safe(exception.getMessage()));
|
||||||
|
throw exception;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private UploadRequest parseAndValidate(String rawJson) {
|
private UploadRequest parseAndValidate(String rawJson) {
|
||||||
@@ -93,6 +118,17 @@ public class MojiaMeasurementOpenApiService {
|
|||||||
return new InMemoryMultipartFile(bytes);
|
return new InMemoryMultipartFile(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String correlation(String name) {
|
||||||
|
String value = MDC.get(name);
|
||||||
|
return value == null || value.isBlank() ? "missing" : safe(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String safe(String value) {
|
||||||
|
if (value == null) return "null";
|
||||||
|
String normalized = value.replace('\r', '_').replace('\n', '_');
|
||||||
|
return normalized.length() <= 160 ? normalized : normalized.substring(0, 160);
|
||||||
|
}
|
||||||
|
|
||||||
private record InMemoryMultipartFile(byte[] content) implements MultipartFile {
|
private record InMemoryMultipartFile(byte[] content) implements MultipartFile {
|
||||||
@Override public String getName() { return "image"; }
|
@Override public String getName() { return "image"; }
|
||||||
@Override public String getOriginalFilename() { return "mojia-measurement.jpg"; }
|
@Override public String getOriginalFilename() { return "mojia-measurement.jpg"; }
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user