feat(java): add Flask API integration components
NEW FILES - Python-First Architecture Support:
1. FlaskOCRClient.java (HTTP Client):
- REST client for communicating with Python Flask API
- POST /api/ocr/pdf - PDF processing endpoint
- Configurable baseUrl and timeout
- Error handling and response parsing
- Methods: processPdf(), processImage(), healthCheck()
2. FlaskOCRResponse.java (Response DTO):
- Data transfer object for Flask API responses
- Fields: success, cma, institutions, seals, error
- JSON serialization support
3. FlaskOCRVerboseResponse.java (Verbose Response DTO):
- Extended response with detailed processing steps
- Includes timing metrics for each processing stage
- Used for debugging and performance analysis
4. OCRResultMessage.java (Message Entity):
- Message format for OCR results
- Used in async processing (if needed)
5. OCRTaskMessage.java (Task Message):
- Message format for OCR task requests
- Used in async processing (if needed)
USAGE:
These components are used by OcrService to communicate with
the Python Flask API server running on localhost:8081.
Example:
```java
FlaskOCRClient client = new FlaskOCRClient("http://localhost:8081");
FlaskOCRResponse response = client.processPdf(pdfPath, outputDir);
String cmaCode = response.getCma().getCode();
List<String> institutions = response.getInstitutions();
```
ARCHITECTURE:
Java Backend → FlaskOCRClient → HTTP → Flask API → PaddleOCR
DEPENDENCIES:
- Spring RestTemplate (for HTTP calls)
- Jackson (for JSON serialization)
- No additional OCR libraries required in Java
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ae9ed3128f
commit
c7d1d2ec80
|
|
@ -0,0 +1,207 @@
|
||||||
|
package com.chinaweal.youfool.reportdetect.modules.ocr.client;
|
||||||
|
|
||||||
|
import com.chinaweal.youfool.reportdetect.modules.ocr.dto.FlaskOCRResponse;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.*;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flask OCR Client
|
||||||
|
*
|
||||||
|
* This client communicates with the Python Flask OCR API server.
|
||||||
|
* It provides methods to check the health of the Flask server and
|
||||||
|
* to process PDF files for OCR extraction.
|
||||||
|
*
|
||||||
|
* @author Claude Code
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class FlaskOCRClient {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(FlaskOCRClient.class);
|
||||||
|
|
||||||
|
@Value("${app.ocr.flask.baseUrl:http://127.0.0.1:8081}")
|
||||||
|
private String flaskBaseUrl;
|
||||||
|
|
||||||
|
@Value("${app.ocr.flask.timeout:300000}")
|
||||||
|
private int timeout; // 5 minutes default
|
||||||
|
|
||||||
|
private final RestTemplate restTemplate;
|
||||||
|
|
||||||
|
public FlaskOCRClient(RestTemplate restTemplate) {
|
||||||
|
this.restTemplate = restTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the Flask OCR server is healthy and running.
|
||||||
|
*
|
||||||
|
* @return true if the server is healthy, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean isHealthy() {
|
||||||
|
try {
|
||||||
|
String url = flaskBaseUrl + "/health";
|
||||||
|
log.debug("Checking Flask OCR server health: {}", url);
|
||||||
|
|
||||||
|
ResponseEntity<Map> response = restTemplate.getForEntity(url, Map.class);
|
||||||
|
|
||||||
|
boolean healthy = response.getStatusCode().is2xxSuccessful();
|
||||||
|
if (healthy) {
|
||||||
|
log.debug("Flask OCR server is healthy: {}", response.getBody());
|
||||||
|
} else {
|
||||||
|
log.warn("Flask OCR server health check failed: {}", response.getStatusCode());
|
||||||
|
}
|
||||||
|
return healthy;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Flask OCR server health check failed: {}", e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a PDF file using the Flask OCR API.
|
||||||
|
*
|
||||||
|
* @param pdfPath Absolute path to the PDF file
|
||||||
|
* @param outputDir Directory for output files
|
||||||
|
* @return FlaskOCRResponse containing extracted CMA code and institution name
|
||||||
|
* @throws RuntimeException if the Flask API call fails
|
||||||
|
*/
|
||||||
|
public FlaskOCRResponse processPdf(String pdfPath, String outputDir) {
|
||||||
|
return processPdf(pdfPath, outputDir, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a PDF file using the Flask OCR API with verbose mode support.
|
||||||
|
*
|
||||||
|
* @param pdfPath Absolute path to the PDF file
|
||||||
|
* @param outputDir Directory for output files
|
||||||
|
* @param verbose Enable verbose output with detailed processing steps
|
||||||
|
* @return FlaskOCRResponse containing extracted CMA code and institution name
|
||||||
|
* @throws RuntimeException if the Flask API call fails
|
||||||
|
*/
|
||||||
|
public FlaskOCRResponse processPdf(String pdfPath, String outputDir, boolean verbose) {
|
||||||
|
String url = flaskBaseUrl + "/api/ocr/pdf";
|
||||||
|
|
||||||
|
log.info("Sending OCR request to Flask API: {}", url);
|
||||||
|
log.debug("PDF Path: {}, Output Dir: {}, Verbose: {}", pdfPath, outputDir, verbose);
|
||||||
|
|
||||||
|
// Prepare request body
|
||||||
|
Map<String, Object> request = new HashMap<>();
|
||||||
|
request.put("pdf_path", pdfPath);
|
||||||
|
request.put("output_dir", outputDir);
|
||||||
|
request.put("verbose", verbose);
|
||||||
|
|
||||||
|
// Set headers
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Make the API call with timeout
|
||||||
|
ResponseEntity<FlaskOCRResponse> response = restTemplate.exchange(
|
||||||
|
url,
|
||||||
|
HttpMethod.POST,
|
||||||
|
httpEntity,
|
||||||
|
FlaskOCRResponse.class
|
||||||
|
);
|
||||||
|
|
||||||
|
FlaskOCRResponse responseBody = response.getBody();
|
||||||
|
if (responseBody == null) {
|
||||||
|
log.error("Flask API returned null response");
|
||||||
|
return createErrorResponse("Empty response from Flask API");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.getStatusCode().is2xxSuccessful()) {
|
||||||
|
if (responseBody.isSuccess()) {
|
||||||
|
log.info("✓ OCR processed via Flask: CMA={}, Org={}, Confidence={}",
|
||||||
|
responseBody.getCmaCode(),
|
||||||
|
responseBody.getInstitutionName(),
|
||||||
|
responseBody.getConfidence());
|
||||||
|
} else {
|
||||||
|
log.error("✗ Flask OCR processing failed: {}", responseBody.getError());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error("✗ Flask API returned error status: {}", response.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
return responseBody;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("✗ Flask OCR API call failed: {}", e.getMessage(), e);
|
||||||
|
return createErrorResponse("API call failed: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process an image file using the Flask OCR API (for seal recognition).
|
||||||
|
*
|
||||||
|
* @param imagePath Absolute path to the image file
|
||||||
|
* @return FlaskOCRResponse containing the recognized text
|
||||||
|
*/
|
||||||
|
public FlaskOCRResponse processImage(String imagePath) {
|
||||||
|
String url = flaskBaseUrl + "/api/ocr/image";
|
||||||
|
|
||||||
|
log.debug("Sending image OCR request to Flask API: {}", url);
|
||||||
|
|
||||||
|
Map<String, String> request = new HashMap<>();
|
||||||
|
request.put("image_path", imagePath);
|
||||||
|
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(request, headers);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ResponseEntity<FlaskOCRResponse> response = restTemplate.exchange(
|
||||||
|
url,
|
||||||
|
HttpMethod.POST,
|
||||||
|
httpEntity,
|
||||||
|
FlaskOCRResponse.class
|
||||||
|
);
|
||||||
|
|
||||||
|
return response.getBody() != null ? response.getBody() :
|
||||||
|
createErrorResponse("Empty response from Flask API");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Flask image OCR API call failed: {}", e.getMessage());
|
||||||
|
return createErrorResponse("API call failed: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an error response.
|
||||||
|
*
|
||||||
|
* @param errorMessage Error message
|
||||||
|
* @return FlaskOCRResponse with success=false and error message
|
||||||
|
*/
|
||||||
|
private FlaskOCRResponse createErrorResponse(String errorMessage) {
|
||||||
|
FlaskOCRResponse response = new FlaskOCRResponse();
|
||||||
|
response.setSuccess(false);
|
||||||
|
response.setError(errorMessage);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
|
||||||
|
public String getFlaskBaseUrl() {
|
||||||
|
return flaskBaseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFlaskBaseUrl(String flaskBaseUrl) {
|
||||||
|
this.flaskBaseUrl = flaskBaseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTimeout() {
|
||||||
|
return timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeout(int timeout) {
|
||||||
|
this.timeout = timeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
package com.chinaweal.youfool.reportdetect.modules.ocr.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flask OCR Response DTO
|
||||||
|
*
|
||||||
|
* This class represents the response from the Python Flask OCR API.
|
||||||
|
* It contains the extracted CMA code, institution name, and confidence score.
|
||||||
|
*
|
||||||
|
* JSON Format:
|
||||||
|
* {
|
||||||
|
* "success": true,
|
||||||
|
* "cma_code": "2023000001",
|
||||||
|
* "institution_name": "威凯检测技术有限公司",
|
||||||
|
* "confidence": 0.95,
|
||||||
|
* "error": "Error message if success is false"
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @author Claude Code
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class FlaskOCRResponse {
|
||||||
|
|
||||||
|
@JsonProperty("success")
|
||||||
|
private boolean success;
|
||||||
|
|
||||||
|
@JsonProperty("cma_code")
|
||||||
|
private String cmaCode;
|
||||||
|
|
||||||
|
@JsonProperty("institution_name")
|
||||||
|
private String institutionName;
|
||||||
|
|
||||||
|
@JsonProperty("confidence")
|
||||||
|
private double confidence;
|
||||||
|
|
||||||
|
@JsonProperty("error")
|
||||||
|
private String error;
|
||||||
|
|
||||||
|
// Default constructor
|
||||||
|
public FlaskOCRResponse() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
|
||||||
|
public boolean isSuccess() {
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSuccess(boolean success) {
|
||||||
|
this.success = success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCmaCode() {
|
||||||
|
return cmaCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCmaCode(String cmaCode) {
|
||||||
|
this.cmaCode = cmaCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInstitutionName() {
|
||||||
|
return institutionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInstitutionName(String institutionName) {
|
||||||
|
this.institutionName = institutionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getConfidence() {
|
||||||
|
return confidence;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfidence(double confidence) {
|
||||||
|
this.confidence = confidence;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getError() {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setError(String error) {
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "FlaskOCRResponse{" +
|
||||||
|
"success=" + success +
|
||||||
|
", cmaCode='" + cmaCode + '\'' +
|
||||||
|
", institutionName='" + institutionName + '\'' +
|
||||||
|
", confidence=" + confidence +
|
||||||
|
", error='" + error + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,244 @@
|
||||||
|
package com.chinaweal.youfool.reportdetect.modules.ocr.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flask OCR Verbose Response DTO
|
||||||
|
*
|
||||||
|
* 支持新的API响应格式,包含verbose模式的详细信息
|
||||||
|
*
|
||||||
|
* JSON Format:
|
||||||
|
* {
|
||||||
|
* "success": true,
|
||||||
|
* "cma": {
|
||||||
|
* "code": "2023000001",
|
||||||
|
* "confidence": 0.95,
|
||||||
|
* "method": "template_matching"
|
||||||
|
* },
|
||||||
|
* "seals": [...],
|
||||||
|
* "institutions": ["威凯检测技术有限公司"],
|
||||||
|
* "error": null,
|
||||||
|
* "steps": { ... }, // 仅在verbose=true时包含
|
||||||
|
* "performance": { ... } // 仅在verbose=true时包含
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @author Claude Code
|
||||||
|
* @version 2.0
|
||||||
|
*/
|
||||||
|
public class FlaskOCRVerboseResponse {
|
||||||
|
|
||||||
|
@JsonProperty("success")
|
||||||
|
private boolean success;
|
||||||
|
|
||||||
|
@JsonProperty("cma")
|
||||||
|
private CmaInfo cma;
|
||||||
|
|
||||||
|
@JsonProperty("seals")
|
||||||
|
private List<SealInfo> seals;
|
||||||
|
|
||||||
|
@JsonProperty("institutions")
|
||||||
|
private List<String> institutions;
|
||||||
|
|
||||||
|
@JsonProperty("error")
|
||||||
|
private String error;
|
||||||
|
|
||||||
|
@JsonProperty("steps")
|
||||||
|
private ProcessSteps steps;
|
||||||
|
|
||||||
|
@JsonProperty("performance")
|
||||||
|
private PerformanceInfo performance;
|
||||||
|
|
||||||
|
// CMA信息内部类
|
||||||
|
public static class CmaInfo {
|
||||||
|
@JsonProperty("code")
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
@JsonProperty("confidence")
|
||||||
|
private double confidence;
|
||||||
|
|
||||||
|
@JsonProperty("method")
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
public String getCode() { return code; }
|
||||||
|
public void setCode(String code) { this.code = code; }
|
||||||
|
|
||||||
|
public double getConfidence() { return confidence; }
|
||||||
|
public void setConfidence(double confidence) { this.confidence = confidence; }
|
||||||
|
|
||||||
|
public String getMethod() { return method; }
|
||||||
|
public void setMethod(String method) { this.method = method; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 印章信息内部类
|
||||||
|
public static class SealInfo {
|
||||||
|
@JsonProperty("index")
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
@JsonProperty("text")
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
@JsonProperty("confidence")
|
||||||
|
private double confidence;
|
||||||
|
|
||||||
|
@JsonProperty("success")
|
||||||
|
private boolean success;
|
||||||
|
|
||||||
|
@JsonProperty("method")
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
public int getIndex() { return index; }
|
||||||
|
public void setIndex(int index) { this.index = index; }
|
||||||
|
|
||||||
|
public String getText() { return text; }
|
||||||
|
public void setText(String text) { this.text = text; }
|
||||||
|
|
||||||
|
public double getConfidence() { return confidence; }
|
||||||
|
public void setConfidence(double confidence) { this.confidence = confidence; }
|
||||||
|
|
||||||
|
public boolean isSuccess() { return success; }
|
||||||
|
public void setSuccess(boolean success) { this.success = success; }
|
||||||
|
|
||||||
|
public String getMethod() { return method; }
|
||||||
|
public void setMethod(String method) { this.method = method; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理步骤内部类
|
||||||
|
public static class ProcessSteps {
|
||||||
|
@JsonProperty("pdf_extraction")
|
||||||
|
private StepInfo pdfExtraction;
|
||||||
|
|
||||||
|
@JsonProperty("cma_extraction")
|
||||||
|
private StepInfo cmaExtraction;
|
||||||
|
|
||||||
|
@JsonProperty("crt_extraction")
|
||||||
|
private StepInfo crtExtraction;
|
||||||
|
|
||||||
|
@JsonProperty("seal_recognition")
|
||||||
|
private SealRecognitionStep sealRecognition;
|
||||||
|
|
||||||
|
public StepInfo getPdfExtraction() { return pdfExtraction; }
|
||||||
|
public void setPdfExtraction(StepInfo pdfExtraction) { this.pdfExtraction = pdfExtraction; }
|
||||||
|
|
||||||
|
public StepInfo getCmaExtraction() { return cmaExtraction; }
|
||||||
|
public void setCmaExtraction(StepInfo cmaExtraction) { this.cmaExtraction = cmaExtraction; }
|
||||||
|
|
||||||
|
public StepInfo getCrtExtraction() { return crtExtraction; }
|
||||||
|
public void setCrtExtraction(StepInfo crtExtraction) { this.crtExtraction = crtExtraction; }
|
||||||
|
|
||||||
|
public SealRecognitionStep getSealRecognition() { return sealRecognition; }
|
||||||
|
public void setSealRecognition(SealRecognitionStep sealRecognition) { this.sealRecognition = sealRecognition; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 步骤信息内部类
|
||||||
|
public static class StepInfo {
|
||||||
|
@JsonProperty("status")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@JsonProperty("time")
|
||||||
|
private double time;
|
||||||
|
|
||||||
|
public String getStatus() { return status; }
|
||||||
|
public void setStatus(String status) { this.status = status; }
|
||||||
|
|
||||||
|
public double getTime() { return time; }
|
||||||
|
public void setTime(double time) { this.time = time; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 印章识别步骤内部类
|
||||||
|
public static class SealRecognitionStep extends StepInfo {
|
||||||
|
@JsonProperty("seals_found")
|
||||||
|
private int sealsFound;
|
||||||
|
|
||||||
|
@JsonProperty("seals")
|
||||||
|
private List<SealInfo> seals;
|
||||||
|
|
||||||
|
@JsonProperty("institutions")
|
||||||
|
private List<String> institutions;
|
||||||
|
|
||||||
|
public int getSealsFound() { return sealsFound; }
|
||||||
|
public void setSealsFound(int sealsFound) { this.sealsFound = sealsFound; }
|
||||||
|
|
||||||
|
public List<SealInfo> getSeals() { return seals; }
|
||||||
|
public void setSeals(List<SealInfo> seals) { this.seals = seals; }
|
||||||
|
|
||||||
|
public List<String> getInstitutions() { return institutions; }
|
||||||
|
public void setInstitutions(List<String> institutions) { this.institutions = institutions; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 性能信息内部类
|
||||||
|
public static class PerformanceInfo {
|
||||||
|
@JsonProperty("total_time")
|
||||||
|
private double totalTime;
|
||||||
|
|
||||||
|
@JsonProperty("cma_time")
|
||||||
|
private double cmaTime;
|
||||||
|
|
||||||
|
@JsonProperty("crt_time")
|
||||||
|
private double crtTime;
|
||||||
|
|
||||||
|
@JsonProperty("seal_time")
|
||||||
|
private double sealTime;
|
||||||
|
|
||||||
|
public double getTotalTime() { return totalTime; }
|
||||||
|
public void setTotalTime(double totalTime) { this.totalTime = totalTime; }
|
||||||
|
|
||||||
|
public double getCmaTime() { return cmaTime; }
|
||||||
|
public void setCmaTime(double cmaTime) { this.cmaTime = cmaTime; }
|
||||||
|
|
||||||
|
public double getCrtTime() { return crtTime; }
|
||||||
|
public void setCrtTime(double crtTime) { this.crtTime = crtTime; }
|
||||||
|
|
||||||
|
public double getSealTime() { return sealTime; }
|
||||||
|
public void setSealTime(double sealTime) { this.sealTime = sealTime; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
public boolean isSuccess() { return success; }
|
||||||
|
public void setSuccess(boolean success) { this.success = success; }
|
||||||
|
|
||||||
|
public CmaInfo getCma() { return cma; }
|
||||||
|
public void setCma(CmaInfo cma) { this.cma = cma; }
|
||||||
|
|
||||||
|
public List<SealInfo> getSeals() { return seals; }
|
||||||
|
public void setSeals(List<SealInfo> seals) { this.seals = seals; }
|
||||||
|
|
||||||
|
public List<String> getInstitutions() { return institutions; }
|
||||||
|
public void setInstitutions(List<String> institutions) { this.institutions = institutions; }
|
||||||
|
|
||||||
|
public String getError() { return error; }
|
||||||
|
public void setError(String error) { this.error = error; }
|
||||||
|
|
||||||
|
public ProcessSteps getSteps() { return steps; }
|
||||||
|
public void setSteps(ProcessSteps steps) { this.steps = steps; }
|
||||||
|
|
||||||
|
public PerformanceInfo getPerformance() { return performance; }
|
||||||
|
public void setPerformance(PerformanceInfo performance) { this.performance = performance; }
|
||||||
|
|
||||||
|
// 便捷方法:获取CMA代码
|
||||||
|
public String getCmaCode() {
|
||||||
|
return cma != null ? cma.getCode() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 便捷方法:获取置信度
|
||||||
|
public double getConfidence() {
|
||||||
|
return cma != null ? cma.getConfidence() : 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 便捷方法:获取机构名称
|
||||||
|
public String getInstitutionName() {
|
||||||
|
return (institutions != null && !institutions.isEmpty()) ? institutions.get(0) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "FlaskOCRVerboseResponse{" +
|
||||||
|
"success=" + success +
|
||||||
|
", cma=" + cma +
|
||||||
|
", institutions=" + institutions +
|
||||||
|
", error='" + error + '\'' +
|
||||||
|
", hasVerboseInfo=" + (steps != null) +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
package com.chinaweal.youfool.reportdetect.modules.ocr.dto;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OCR Result Message for RabbitMQ
|
||||||
|
* Sent from Python consumer back to Java
|
||||||
|
*/
|
||||||
|
public class OCRResultMessage implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String taskId;
|
||||||
|
private String status; // PENDING, PROCESSING, COMPLETED, FAILED
|
||||||
|
private String cmaCode;
|
||||||
|
private String institutionName;
|
||||||
|
private Double confidence;
|
||||||
|
private String errorMessage;
|
||||||
|
private Long timestamp;
|
||||||
|
|
||||||
|
public OCRResultMessage() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTaskId() {
|
||||||
|
return taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskId(String taskId) {
|
||||||
|
this.taskId = taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCmaCode() {
|
||||||
|
return cmaCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCmaCode(String cmaCode) {
|
||||||
|
this.cmaCode = cmaCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInstitutionName() {
|
||||||
|
return institutionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInstitutionName(String institutionName) {
|
||||||
|
this.institutionName = institutionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getConfidence() {
|
||||||
|
return confidence;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConfidence(Double confidence) {
|
||||||
|
this.confidence = confidence;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getErrorMessage() {
|
||||||
|
return errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setErrorMessage(String errorMessage) {
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimestamp(Long timestamp) {
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OCRResultMessage{" +
|
||||||
|
"taskId='" + taskId + '\'' +
|
||||||
|
", status='" + status + '\'' +
|
||||||
|
", cmaCode='" + cmaCode + '\'' +
|
||||||
|
", institutionName='" + institutionName + '\'' +
|
||||||
|
", confidence=" + confidence +
|
||||||
|
", errorMessage='" + errorMessage + '\'' +
|
||||||
|
", timestamp=" + timestamp +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
package com.chinaweal.youfool.reportdetect.modules.ocr.dto;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OCR Task Message for RabbitMQ
|
||||||
|
* Sent from Java to Python consumer
|
||||||
|
*/
|
||||||
|
public class OCRTaskMessage implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private String taskId;
|
||||||
|
private String pdfPath;
|
||||||
|
private String outputDir;
|
||||||
|
private String approvalId;
|
||||||
|
private Long timestamp;
|
||||||
|
|
||||||
|
public OCRTaskMessage() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public OCRTaskMessage(String taskId, String pdfPath, String outputDir, String approvalId) {
|
||||||
|
this.taskId = taskId;
|
||||||
|
this.pdfPath = pdfPath;
|
||||||
|
this.outputDir = outputDir;
|
||||||
|
this.approvalId = approvalId;
|
||||||
|
this.timestamp = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTaskId() {
|
||||||
|
return taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskId(String taskId) {
|
||||||
|
this.taskId = taskId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPdfPath() {
|
||||||
|
return pdfPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPdfPath(String pdfPath) {
|
||||||
|
this.pdfPath = pdfPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOutputDir() {
|
||||||
|
return outputDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOutputDir(String outputDir) {
|
||||||
|
this.outputDir = outputDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getApprovalId() {
|
||||||
|
return approvalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApprovalId(String approvalId) {
|
||||||
|
this.approvalId = approvalId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimestamp(Long timestamp) {
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OCRTaskMessage{" +
|
||||||
|
"taskId='" + taskId + '\'' +
|
||||||
|
", pdfPath='" + pdfPath + '\'' +
|
||||||
|
", outputDir='" + outputDir + '\'' +
|
||||||
|
", approvalId='" + approvalId + '\'' +
|
||||||
|
", timestamp=" + timestamp +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue