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