优化
This commit is contained in:
@@ -17,7 +17,6 @@ public interface WeightOcrClient {
|
||||
ApiResponse<Result> recognize(@RequestHeader("X-Internal-Service-Token") String token,
|
||||
@RequestPart("file") MultipartFile file);
|
||||
|
||||
record Result(String sourceImage, String croppedImage, String rawResponseFile,
|
||||
String status, BigDecimal weight, Double confidence,
|
||||
java.util.List<?> candidates, String error) {}
|
||||
record Result(String status, BigDecimal weight, BigDecimal confidence,
|
||||
String ocrRawText, String error) {}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Service
|
||||
@@ -39,7 +40,7 @@ public class MeasurementImageService {
|
||||
FileObjectEntity object = storeObject(
|
||||
tenantId, inboundId, operatorId, file, "INBOUND_MEASUREMENT_IMAGE");
|
||||
return new UploadResult(object.getId(), object.getOriginalName(), object.getContentType(),
|
||||
object.getSizeBytes(), "NOT_REQUIRED", null, null, null, null);
|
||||
object.getSizeBytes(), "NOT_REQUIRED", null, null, null, null, null);
|
||||
}
|
||||
|
||||
private FileObjectEntity storeObject(long tenantId, long inboundId, long operatorId,
|
||||
@@ -116,7 +117,8 @@ public class MeasurementImageService {
|
||||
}
|
||||
var result = response.data();
|
||||
return new UploadResult(object.getId(), object.getOriginalName(), object.getContentType(),
|
||||
object.getSizeBytes(), result.status(), result.weight(), "KG", result.confidence(), result.error());
|
||||
object.getSizeBytes(), result.status(), result.weight(), "KG",
|
||||
normalizeConfidence(result.confidence()), result.ocrRawText(), result.error());
|
||||
} catch (FeignException exception) {
|
||||
return failed(object, "OCR服务不可用,可稍后重试或人工录入");
|
||||
}
|
||||
@@ -124,12 +126,19 @@ public class MeasurementImageService {
|
||||
|
||||
private UploadResult failed(FileObjectEntity object, String message) {
|
||||
return new UploadResult(object.getId(), object.getOriginalName(), object.getContentType(),
|
||||
object.getSizeBytes(), "FAILED", null, null, null, message);
|
||||
object.getSizeBytes(), "FAILED", null, null, null, null, message);
|
||||
}
|
||||
|
||||
private BigDecimal normalizeConfidence(BigDecimal value) {
|
||||
if (value == null) return null;
|
||||
if (value.compareTo(BigDecimal.ZERO) < 0) value = BigDecimal.ZERO;
|
||||
if (value.compareTo(BigDecimal.ONE) > 0) value = BigDecimal.ONE;
|
||||
return value.setScale(5, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
public record UploadResult(Long fileId, String fileName, String contentType, Long sizeBytes,
|
||||
String recognitionStatus, BigDecimal weightValue, String weightUnit,
|
||||
Double confidence, String error) {}
|
||||
BigDecimal confidence, String ocrRawText, String error) {}
|
||||
public record Download(String fileName, String contentType, byte[] content) {}
|
||||
|
||||
private record StoredImageMultipartFile(String originalFilename, String contentType, byte[] bytes)
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ class InternalMeasurementImageControllerTest {
|
||||
var file = new MockMultipartFile("file", "measure.png", MediaType.IMAGE_PNG_VALUE,
|
||||
new byte[]{1, 2, 3});
|
||||
var result = new MeasurementImageService.UploadResult(41L, "measure.png",
|
||||
MediaType.IMAGE_PNG_VALUE, 3L, "NOT_REQUIRED", null, null, null, null);
|
||||
MediaType.IMAGE_PNG_VALUE, 3L, "NOT_REQUIRED", null, null, null, null, null);
|
||||
when(images.uploadMeasurementEvidence(11L, 21L, 31L, file)).thenReturn(result);
|
||||
|
||||
var response = controller.upload("internal-token", 31L, 11L, 21L, file);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.baiyue.file.service;
|
||||
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.file.client.WeightOcrClient;
|
||||
import com.baiyue.file.entity.FileObjectEntity;
|
||||
import com.baiyue.file.mapper.FileObjectMapper;
|
||||
@@ -18,6 +19,7 @@ import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
@@ -91,4 +93,27 @@ class MeasurementImageServiceEvidenceTest {
|
||||
.isInstanceOf(com.baiyue.common.core.exception.BizException.class);
|
||||
verifyNoInteractions(storage);
|
||||
}
|
||||
|
||||
@Test
|
||||
void forwardsSafeOcrTextAndCanonicalConfidence() {
|
||||
FileObjectEntity object = new FileObjectEntity();
|
||||
object.setId(41L);
|
||||
object.setTenantId(11L);
|
||||
object.setBusinessType("INBOUND_WEIGHT_IMAGE");
|
||||
object.setBusinessId("21");
|
||||
object.setOriginalName("weight.jpg");
|
||||
object.setContentType(MediaType.IMAGE_JPEG_VALUE);
|
||||
object.setObjectKey("measurements/11/21/weight.jpg");
|
||||
object.setSizeBytes(3L);
|
||||
when(files.selectOne(any())).thenReturn(object);
|
||||
when(storage.read(object.getObjectKey())).thenReturn(new byte[]{1, 2, 3});
|
||||
when(ocr.recognize(org.mockito.ArgumentMatchers.eq("internal-token"), any()))
|
||||
.thenReturn(ApiResponse.success(new WeightOcrClient.Result("RECOGNIZED",
|
||||
new BigDecimal("285.5"), new BigDecimal("0.5097191334"), "285.5\nKG", null)));
|
||||
|
||||
var result = service.retryRecognition(11L, 21L, 41L);
|
||||
|
||||
assertThat(result.confidence()).isEqualByComparingTo("0.50972");
|
||||
assertThat(result.ocrRawText()).isEqualTo("285.5\nKG");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user