diff --git a/bonus-admin/src/main/java/com/bonus/web/controller/analysis/AnalysisController.java b/bonus-admin/src/main/java/com/bonus/web/controller/analysis/AnalysisController.java index 80e8e9d..1a325d4 100644 --- a/bonus-admin/src/main/java/com/bonus/web/controller/analysis/AnalysisController.java +++ b/bonus-admin/src/main/java/com/bonus/web/controller/analysis/AnalysisController.java @@ -91,6 +91,14 @@ public class AnalysisController extends BaseController { return analysisService.editBidData(dto); } + @ApiOperation(value = "招标解析", notes = "删除项目数据") + @PostMapping("delBidData") + @SysLog(title = "招标解析", module = "招标解析->删除项目数据", businessType = OperaType.DELETE, details = "删除项目数据", logType = 1) + @RequiresPermissions("analysis:analysis:del") + public AjaxResult delProData(@RequestBody AnalysisDto.TemplateDto dto) { + return analysisService.delProData(dto); + } + @ApiOperation(value = "测试mq异步消息", notes = "测试mq异步消息") @GetMapping("/testAsyncMq2") public AjaxResult testAsyncMq2() { diff --git a/bonus-admin/src/main/java/com/bonus/web/service/analysis/AnalysisService.java b/bonus-admin/src/main/java/com/bonus/web/service/analysis/AnalysisService.java index 48333f2..45da06c 100644 --- a/bonus-admin/src/main/java/com/bonus/web/service/analysis/AnalysisService.java +++ b/bonus-admin/src/main/java/com/bonus/web/service/analysis/AnalysisService.java @@ -55,8 +55,6 @@ public class AnalysisService { @Resource(name = "ValidatorsUtils") private ValidatorsUtils validatorsUtils; - - @Resource(name = "WordConvertPdfService") private WordConvertPdfService wordConvertPdfService; @@ -148,6 +146,8 @@ public class AnalysisService { @Transactional(rollbackFor = Exception.class) public AjaxResult saveData(AnalysisDto.TemplateDto dto) { try { + // 异步任务集合 + List> asyncTaskList = new ArrayList<>(); // 校验数据是否合法 String validResult = validatorsUtils.valid(dto, AnalysisDto.TemplateDto.ADD.class); if (StringUtils.isNotBlank(validResult)) { @@ -168,12 +168,19 @@ public class AnalysisService { Long id = compositions.get(i).getId(); dto.getFiles().get(i).setBusinessId(id); dto.getFiles().get(i).setSourceTable(TableConstants.TB_PRO_COMPOSITION); + // 添加异步任务数据 + Map map = new HashMap<>(); + String taskId = UUID.randomUUID().toString(); + map.put("taskId", taskId); + map.put("uploadPath", dto.getFiles().get(i).getFilePath()); + map.put("businessId", dto.getProId()); + map.put("templateId",dto.getTemplateId()); + map.put("analysisLabelId",dto.getAnalysisLabelId()); + asyncTaskList.add(map); } sourceFileService.saveResourceFile(dto.getFiles()); - // 同步解析规则数据 - // 执行异步解析任务 - /*CompletableFuture.runAsync(() -> { - }, taskExecutor);*/ + // 执行异步任务 + AsyncManager.me().executeSendRabbitMqMessage(asyncTaskList); return AjaxResult.success(); } catch (Exception e) { log.error(e.toString(),e); @@ -291,5 +298,43 @@ public class AnalysisService { return AjaxResult.error(); } } + + /** + * 删除项目数据 + * @param dto + * @return AjaxResult + * @author cwchen + * @date 2025/11/29 15:42 + */ + @Transactional(rollbackFor = Exception.class) + public AjaxResult delProData(AnalysisDto.TemplateDto dto) { + try { + // 校验数据是否合法 + String validResult = validatorsUtils.valid(dto, AnalysisDto.TemplateDto.DELETE.class); + if (StringUtils.isNotBlank(validResult)) { + return AjaxResult.error(validResult); + } + // 删除项目数据 + analysisService.delProData(dto); + // 删除标段数据 + analysisService.delBidData(dto); + // 删除项目组成文件 + List compositions = analysisService.getProComposition(dto); + if(CollectionUtils.isNotEmpty(compositions)){ + for (ProComposition composition : compositions) { + sourceFileService.delResourceFileByTable(composition.getId(),TableConstants.TB_PRO_COMPOSITION); + } + } + // 删除模板组成数据 + analysisService.delProComposition(dto); + // 删除项目/标段解析数据 + analysisService.delProBidAnalysisResult(dto); + return AjaxResult.success(); + } catch (Exception e) { + log.error(e.toString(),e); + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return AjaxResult.error(); + } + } } diff --git a/bonus-admin/src/main/resources/application-ocr.yml b/bonus-admin/src/main/resources/application-ocr.yml index b578922..82ca3ef 100644 --- a/bonus-admin/src/main/resources/application-ocr.yml +++ b/bonus-admin/src/main/resources/application-ocr.yml @@ -2,6 +2,7 @@ ocr: service: url: http://192.168.0.37:9091/extract # ocr 请求地址 convertUrl: http://192.168.0.37:10000/extract # word 转pdf 请求地址 - analysisUrl: http://192.168.0.37:10001/extract # 招标解析算法服务 请求地址 + processPdfUrl: http://192.168.0.37:10001/process-pdf # 招标解析算法服务 请求地址 + extractInfoUrl: http://192.168.0.37:10001/extract-info # 招标解析算法服务 请求地址 timeout: 30000 # ocr 请求超时时间 max-connections: 100 \ No newline at end of file diff --git a/bonus-analysis/src/main/java/com/bonus/analysis/mapper/IASAnalysisMapper.java b/bonus-analysis/src/main/java/com/bonus/analysis/mapper/IASAnalysisMapper.java index 4c72d1d..bf0145c 100644 --- a/bonus-analysis/src/main/java/com/bonus/analysis/mapper/IASAnalysisMapper.java +++ b/bonus-analysis/src/main/java/com/bonus/analysis/mapper/IASAnalysisMapper.java @@ -5,7 +5,9 @@ import com.bonus.common.domain.analysis.dto.AnalysisDto; import com.bonus.common.domain.analysis.dto.AnalysisProDto; import com.bonus.common.domain.analysis.po.ProComposition; import com.bonus.common.domain.analysis.vo.AnalysisBidVo; +import com.bonus.common.domain.analysis.vo.AnalysisLabelItemOcrVo; import com.bonus.common.domain.analysis.vo.AnalysisVo; +import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; import java.util.List; @@ -90,4 +92,49 @@ public interface IASAnalysisMapper { * @date 2025/11/26 15:55 */ List getProComposition(AnalysisDto.TemplateDto dto); + + /** + * 获取解析标签项 + * @param analysisLabelId + * @return List + * @author cwchen + * @date 2025/11/29 14:49 + */ + List getAnalysisLabels(@Param("analysisLabelId") Long analysisLabelId, @Param("templateId") Long templateId); + + /** + * 删除项目数据 + * @param dto + * @return void + * @author cwchen + * @date 2025/11/29 15:51 + */ + void delProData(AnalysisDto.TemplateDto dto); + + /** + * 删除标段数据 + * @param dto + * @return void + * @author cwchen + * @date 2025/11/29 15:51 + */ + void delBidData(AnalysisDto.TemplateDto dto); + + /** + * 删除模板组成数据 + * @param dto + * @return void + * @author cwchen + * @date 2025/11/29 15:51 + */ + void delProComposition(AnalysisDto.TemplateDto dto); + + /** + * 删除项目/标段解析数据 + * @param dto + * @return void + * @author cwchen + * @date 2025/11/29 15:51 + */ + void delProBidAnalysisResult(AnalysisDto.TemplateDto dto); } diff --git a/bonus-analysis/src/main/java/com/bonus/analysis/service/IASAnalysisService.java b/bonus-analysis/src/main/java/com/bonus/analysis/service/IASAnalysisService.java index 9f30485..d16d826 100644 --- a/bonus-analysis/src/main/java/com/bonus/analysis/service/IASAnalysisService.java +++ b/bonus-analysis/src/main/java/com/bonus/analysis/service/IASAnalysisService.java @@ -5,6 +5,7 @@ import com.bonus.common.domain.analysis.dto.AnalysisDto; import com.bonus.common.domain.analysis.dto.AnalysisProDto; import com.bonus.common.domain.analysis.po.ProComposition; import com.bonus.common.domain.analysis.vo.AnalysisBidVo; +import com.bonus.common.domain.analysis.vo.AnalysisLabelItemOcrVo; import com.bonus.common.domain.analysis.vo.AnalysisVo; import java.util.List; @@ -88,4 +89,50 @@ public interface IASAnalysisService { * @date 2025/11/26 15:54 */ List getProComposition(AnalysisDto.TemplateDto dto); + + + /** + * 获取解析标签项 + * @param analysisLabelId + * @return List + * @author cwchen + * @date 2025/11/29 14:48 + */ + List getAnalysisLabels(Long analysisLabelId, Long templateId); + + /** + * 删除项目数据 + * @param dto + * @return void + * @author cwchen + * @date 2025/11/29 15:48 + */ + void delProData(AnalysisDto.TemplateDto dto); + + /** + * 删除标段数据 + * @param dto + * @return void + * @author cwchen + * @date 2025/11/29 15:48 + */ + void delBidData(AnalysisDto.TemplateDto dto); + + /** + * 删除模板组成数据 + * @param dto + * @return void + * @author cwchen + * @date 2025/11/29 15:48 + */ + void delProComposition(AnalysisDto.TemplateDto dto); + + /** + * 删除项目/标段解析数据 + * @param dto + * @return void + * @author cwchen + * @date 2025/11/29 15:48 + */ + void delProBidAnalysisResult(AnalysisDto.TemplateDto dto); } diff --git a/bonus-analysis/src/main/java/com/bonus/analysis/service/impl/ASAnalysisServiceImpl.java b/bonus-analysis/src/main/java/com/bonus/analysis/service/impl/ASAnalysisServiceImpl.java index 1f945d2..dbfb6d8 100644 --- a/bonus-analysis/src/main/java/com/bonus/analysis/service/impl/ASAnalysisServiceImpl.java +++ b/bonus-analysis/src/main/java/com/bonus/analysis/service/impl/ASAnalysisServiceImpl.java @@ -7,13 +7,13 @@ import com.bonus.common.domain.analysis.dto.AnalysisDto; import com.bonus.common.domain.analysis.dto.AnalysisProDto; import com.bonus.common.domain.analysis.po.ProComposition; import com.bonus.common.domain.analysis.vo.AnalysisBidVo; +import com.bonus.common.domain.analysis.vo.AnalysisLabelItemOcrVo; import com.bonus.common.domain.analysis.vo.AnalysisVo; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Optional; @@ -78,4 +78,33 @@ public class ASAnalysisServiceImpl implements IASAnalysisService { return new ArrayList<>(); } } + + @Override + public List getAnalysisLabels(Long analysisLabelId, Long templateId) { + try { + return Optional.ofNullable(analysisMapper.getAnalysisLabels(analysisLabelId,templateId)).orElse(new ArrayList()); + } catch (Exception e) { + return new ArrayList<>(); + } + } + + @Override + public void delProData(AnalysisDto.TemplateDto dto) { + analysisMapper.delProData(dto); + } + + @Override + public void delBidData(AnalysisDto.TemplateDto dto) { + analysisMapper.delBidData(dto); + } + + @Override + public void delProComposition(AnalysisDto.TemplateDto dto) { + analysisMapper.delProComposition(dto); + } + + @Override + public void delProBidAnalysisResult(AnalysisDto.TemplateDto dto) { + analysisMapper.delProBidAnalysisResult(dto); + } } diff --git a/bonus-analysis/src/main/resources/mapper/AnalysisMapper.xml b/bonus-analysis/src/main/resources/mapper/AnalysisMapper.xml index 57ed4ab..6274b2f 100644 --- a/bonus-analysis/src/main/resources/mapper/AnalysisMapper.xml +++ b/bonus-analysis/src/main/resources/mapper/AnalysisMapper.xml @@ -118,4 +118,38 @@ composition_file_name AS compositionFileName FROM tb_pro_composition WHERE pro_id = #{proId} AND composition_type = #{compositionType} + + + + + + + UPDATE tb_pro SET del_flag = '1' WHERE pro_id = #{proId} + + + + + UPDATE tb_pro_bid SET del_flag = '1' WHERE pro_id = #{proId} + + + + + DELETE FROM tb_pro_composition WHERE pro_id = #{proId} + + + + + DELETE FROM tb_pro_bid_analysis_result WHERE pro_id = #{proId} + diff --git a/bonus-common/src/main/java/com/bonus/common/domain/analysis/dto/AnalysisBidDto.java b/bonus-common/src/main/java/com/bonus/common/domain/analysis/dto/AnalysisBidDto.java index 558caf8..bece125 100644 --- a/bonus-common/src/main/java/com/bonus/common/domain/analysis/dto/AnalysisBidDto.java +++ b/bonus-common/src/main/java/com/bonus/common/domain/analysis/dto/AnalysisBidDto.java @@ -147,4 +147,5 @@ public class AnalysisBidDto { */ public interface UPDATE { } + } diff --git a/bonus-common/src/main/java/com/bonus/common/domain/analysis/dto/AnalysisDto.java b/bonus-common/src/main/java/com/bonus/common/domain/analysis/dto/AnalysisDto.java index af4b570..7ff9d75 100644 --- a/bonus-common/src/main/java/com/bonus/common/domain/analysis/dto/AnalysisDto.java +++ b/bonus-common/src/main/java/com/bonus/common/domain/analysis/dto/AnalysisDto.java @@ -50,11 +50,15 @@ public class AnalysisDto { /** * 项目id * */ + @NotNull(message = "项目ID不能为空", groups = {DELETE.class}) private Long proId; @NotNull(message = "模板不能为空", groups = {ADD.class}) private Long templateId; + @NotNull(message = "标签组id不能为空", groups = {ADD.class}) + private Long analysisLabelId; + /**文件组成名称*/ private String[] uploadType; @@ -108,5 +112,11 @@ public class AnalysisDto { public interface ADD { } + /** + * 删除条件限制 + */ + public interface DELETE { + } + } } diff --git a/bonus-common/src/main/java/com/bonus/common/domain/analysis/vo/AnalysisLabelItemOcrVo.java b/bonus-common/src/main/java/com/bonus/common/domain/analysis/vo/AnalysisLabelItemOcrVo.java new file mode 100644 index 0000000..efe8714 --- /dev/null +++ b/bonus-common/src/main/java/com/bonus/common/domain/analysis/vo/AnalysisLabelItemOcrVo.java @@ -0,0 +1,53 @@ +package com.bonus.common.domain.analysis.vo; + +import lombok.Data; + + +/** + * @className:AnalysisLabelItemVo + * @author:cwchen + * @date:2025-11-29-14:42 + * @version:1.0 + * @description:解析标签项 + */ +@Data +public class AnalysisLabelItemOcrVo { + + + /** + * 配置id + */ + private Long id; + + + /** + * 解析名称 + */ + private String searchKeyword; + + /** + * 解析编码 + */ + private String targetField; + + /** + * 父节点 + */ + private String parentId; + + /** + * 层级 + */ + private Integer analysisLevel; + + /** + * 排序 + */ + private Integer analysisSort; + + /** + * 提示词 + * */ + private String description; + +} diff --git a/bonus-common/src/main/java/com/bonus/common/domain/ocr/dto/AnalysisOcrRequest.java b/bonus-common/src/main/java/com/bonus/common/domain/ocr/dto/AnalysisOcrRequest.java new file mode 100644 index 0000000..4921a0b --- /dev/null +++ b/bonus-common/src/main/java/com/bonus/common/domain/ocr/dto/AnalysisOcrRequest.java @@ -0,0 +1,53 @@ +package com.bonus.common.domain.ocr.dto; + +import com.bonus.common.domain.analysis.vo.AnalysisLabelItemOcrVo; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.io.File; +import java.util.List; + +/** + * @className:AnalysisOcrRequest + * @author:cwchen + * @date:2025-11-29-13:33 + * @version:1.0 + * @description: 招标解析orc请求 + */ +@Data +public class AnalysisOcrRequest { + + @JsonProperty("file") + private File file; // 文件对象 + + @JsonProperty("type") + private String type; // 文件类型 + + @JsonProperty("fields_json") + private String fields_json; + + @JsonProperty("analysisType") + private String analysisType; // 招标解析类型 1.招标解析一次处理 2.招标解析二次处理 + + private String gpus = "2"; + + private String doc_folder_path; + private String cover_keys; + private List extraction_items; + + public AnalysisOcrRequest(String doc_folder_path, String cover_keys, List extraction_items) { + this.doc_folder_path = doc_folder_path; + this.cover_keys = cover_keys; + this.extraction_items = extraction_items; + } + + public AnalysisOcrRequest(File file, String type, String fields_json, String analysisType) { + this.file = file; + this.type = type; + this.fields_json = fields_json; + this.analysisType = analysisType; + } + + public AnalysisOcrRequest() { + } +} diff --git a/bonus-common/src/main/java/com/bonus/common/domain/rabbitmq/dto/RabbitMqMessage.java b/bonus-common/src/main/java/com/bonus/common/domain/rabbitmq/dto/RabbitMqMessage.java index 9be76cf..a52f3eb 100644 --- a/bonus-common/src/main/java/com/bonus/common/domain/rabbitmq/dto/RabbitMqMessage.java +++ b/bonus-common/src/main/java/com/bonus/common/domain/rabbitmq/dto/RabbitMqMessage.java @@ -15,6 +15,21 @@ public class RabbitMqMessage implements Serializable { private static final long serialVersionUID = 1L; + /** + * 业务id + * */ + private Long businessId; + + /** + * 标签组id + * */ + private Long analysisLabelId; + + /** + * 模板id + * */ + private Long templateId; + /** * 消息名称/任务类型 */ diff --git a/bonus-common/src/main/java/com/bonus/common/domain/system/vo/SelectVo.java b/bonus-common/src/main/java/com/bonus/common/domain/system/vo/SelectVo.java index b9be22d..55ea386 100644 --- a/bonus-common/src/main/java/com/bonus/common/domain/system/vo/SelectVo.java +++ b/bonus-common/src/main/java/com/bonus/common/domain/system/vo/SelectVo.java @@ -26,4 +26,10 @@ public class SelectVo { */ @JsonInclude(JsonInclude.Include.NON_EMPTY) private String uploadType; + + /** + * 解析标签组id + */ + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private String analysisLabelId; } diff --git a/bonus-ocr/src/main/java/com/bonus/ocr/service/AnalysisOcrService.java b/bonus-ocr/src/main/java/com/bonus/ocr/service/AnalysisOcrService.java index a783661..3f5e24f 100644 --- a/bonus-ocr/src/main/java/com/bonus/ocr/service/AnalysisOcrService.java +++ b/bonus-ocr/src/main/java/com/bonus/ocr/service/AnalysisOcrService.java @@ -1,7 +1,8 @@ package com.bonus.ocr.service; -import com.bonus.common.domain.ocr.dto.OcrRequest; +import com.bonus.common.domain.ocr.dto.AnalysisOcrRequest; import com.bonus.common.domain.ocr.vo.AnalysisResponse; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.http.HttpEntity; @@ -9,6 +10,7 @@ import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.entity.mime.content.FileBody; @@ -20,10 +22,10 @@ import org.springframework.stereotype.Service; import java.io.IOException; import java.nio.charset.StandardCharsets; -import java.util.Optional; +import java.util.Objects; /** - * @className: 招标解析算法服务 + * @className: 招标解析算法服务 - 处理pdf文件 * @author: cwchen * @date: 2025-10-16-10:35 * @version: 1.0 @@ -35,11 +37,14 @@ public class AnalysisOcrService { private static final String UTF_8 = "UTF-8"; private static final String FILE_PART_NAME = "file"; - private static final String TYPE_PART_NAME = "type"; - private static final String FIELDS_JSON_PART_NAME = "fields_json"; + private static final String GPUS = "gpus"; + + @Value("${ocr.service.processPdfUrl}") + private String processPdfUrl; + + @Value("${ocr.service.extractInfoUrl}") + private String extractInfoUrl; - @Value("${ocr.service.analysisUrl}") - private String ocrServiceUrl; @Value("${ocr.service.timeout}") private int timeout; @@ -63,45 +68,65 @@ public class AnalysisOcrService { /** * 调用招标解析服务 * - * @param ocrRequest 招标解析请求参数 + * @param analysisOcrRequest 招标解析请求参数 * @return OCR响应结果 * @throws IOException 当招标解析算法服务调用失败时抛出 */ - public AnalysisResponse callOcrService(OcrRequest ocrRequest) throws IOException { - validateOcrRequest(ocrRequest); + public AnalysisResponse callOcrService(AnalysisOcrRequest analysisOcrRequest) throws IOException { + if (Objects.equals(analysisOcrRequest.getAnalysisType(), "1")) { + // 招标解析一次处理 + validateAnalysisOcrRequest(analysisOcrRequest); + } else { + // 招标解析二次处理 + validateAnalysisOcrRequest2(analysisOcrRequest); + } + HttpPost httpPost = null; try { - httpPost = createHttpPost(ocrRequest); - return executeOcrRequest(httpPost); + // 一次解析处理 + if (Objects.equals(analysisOcrRequest.getAnalysisType(), "1")) { + httpPost = createHttpPost(analysisOcrRequest); + } else { + // 二次解析处理 + httpPost = createHttpPost2(analysisOcrRequest); + } + return executeAnalysisOcrRequest(httpPost); } catch (IOException e) { log.error("调用招标解析算法服务失败", e); return null; } finally { - cleanupResources(ocrRequest, httpPost); + cleanupResources(analysisOcrRequest, httpPost); } } /** - * 验证招标解析算法请求参数 + * 验证招标解析算法一次请求参数 */ - private void validateOcrRequest(OcrRequest ocrRequest) { - if (ocrRequest == null) { + private void validateAnalysisOcrRequest(AnalysisOcrRequest analysisOcrRequest) { + if (analysisOcrRequest == null) { throw new IllegalArgumentException("招标解析算法请求参数不能为空"); } - if (ocrRequest.getFile() == null || !ocrRequest.getFile().exists()) { + if (analysisOcrRequest.getFile() == null || !analysisOcrRequest.getFile().exists()) { throw new IllegalArgumentException("招标解析文件不能为空或文件不存在"); } - if (ocrRequest.getType() == null || ocrRequest.getType().trim().isEmpty()) { - throw new IllegalArgumentException("招标解析类型不能为空"); + } + + /** + * 验证招标解析算法二次请求参数 + */ + private void validateAnalysisOcrRequest2(AnalysisOcrRequest analysisOcrRequest) { + if (analysisOcrRequest == null) { + throw new IllegalArgumentException("招标解析算法请求参数不能为空"); } + } /** * 创建HTTP POST请求 */ - private HttpPost createHttpPost(OcrRequest ocrRequest) { - HttpPost httpPost = new HttpPost(ocrServiceUrl); + private HttpPost createHttpPost(AnalysisOcrRequest analysisOcrRequest) { + HttpPost httpPost = new HttpPost(processPdfUrl); MultipartEntityBuilder builder = MultipartEntityBuilder.create(); builder.setCharset(StandardCharsets.UTF_8); @@ -109,32 +134,51 @@ public class AnalysisOcrService { // 添加文件字段 builder.addPart(FILE_PART_NAME, - new FileBody(ocrRequest.getFile(), + new FileBody(analysisOcrRequest.getFile(), ContentType.MULTIPART_FORM_DATA, - ocrRequest.getFile().getName())); - - // 添加类型字段 - builder.addTextBody(TYPE_PART_NAME, - ocrRequest.getType(), + analysisOcrRequest.getFile().getName())); + // 添加GPUS字段 + builder.addTextBody(GPUS, + analysisOcrRequest.getGpus(), ContentType.TEXT_PLAIN.withCharset(UTF_8)); - - // 添加解析内容字段 - if (ocrRequest.getFields_json() != null) { - builder.addTextBody(FIELDS_JSON_PART_NAME, - ocrRequest.getFields_json(), - ContentType.TEXT_PLAIN.withCharset(UTF_8)); - } - httpPost.setEntity(builder.build()); httpPost.setHeader("Accept", "application/json"); - return httpPost; } + /** + * 创建HTTP POST请求2 + */ + private HttpPost createHttpPost2(AnalysisOcrRequest analysisOcrRequest) { + HttpPost httpPost = new HttpPost(extractInfoUrl); + + try { + // 将请求对象转换为JSON字符串 + String jsonRequest = convertToJson(analysisOcrRequest); + // 设置请求体为JSON + StringEntity entity = new StringEntity(jsonRequest, ContentType.APPLICATION_JSON); + httpPost.setEntity(entity); + // 设置请求头 + httpPost.setHeader("Accept", "application/json"); + httpPost.setHeader("Content-Type", "application/json; charset=UTF-8"); + } catch (Exception e) { + throw new RuntimeException("创建HTTP POST请求失败", e); + } + return httpPost; + } + + /** + * 将请求对象转换为JSON字符串 + */ + private String convertToJson(AnalysisOcrRequest request) throws JsonProcessingException { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.writeValueAsString(request); + } + /** * 执行招标解析算法请求 */ - private AnalysisResponse executeOcrRequest(HttpPost httpPost) throws IOException { + private AnalysisResponse executeAnalysisOcrRequest(HttpPost httpPost) throws IOException { log.info("开始调用招标解析算法服务"); try (CloseableHttpResponse response = httpClient.execute(httpPost)) { @@ -182,58 +226,34 @@ public class AnalysisOcrService { } } - /** - * 处理OCR识别结果 - */ - private void handleOcrResult(AnalysisResponse AnalysisResponse) { - if (AnalysisResponse.isSuccess()) { - log.info("OCR识别成功"); - logOcrResults(AnalysisResponse); - } else { - log.warn("OCR识别失败", AnalysisResponse.getMessage()); - } - } - - /** - * 记录OCR识别结果 - */ - private void logOcrResults(AnalysisResponse AnalysisResponse) { - Optional.ofNullable(AnalysisResponse.getData()) - .ifPresent(data -> { - if (log.isInfoEnabled()) { - data.forEach((key, value) -> - log.info("识别结果 - key: {}, value: {}", key, value)); - } - }); - } - /** * 清理资源 */ - private void cleanupResources(OcrRequest ocrRequest, HttpPost httpPost) { + private void cleanupResources(AnalysisOcrRequest analysisOcrRequest, HttpPost httpPost) { // 清理HTTP连接 if (httpPost != null) { httpPost.releaseConnection(); } - - // 清理临时文件 - cleanupTempFile(ocrRequest); + if (Objects.equals(analysisOcrRequest.getAnalysisType(), "1")) { + // 清理临时文件 + cleanupTempFile(analysisOcrRequest); + } } /** * 清理临时文件 */ - private void cleanupTempFile(OcrRequest ocrRequest) { - if (ocrRequest.getFile() != null && ocrRequest.getFile().exists()) { + private void cleanupTempFile(AnalysisOcrRequest analysisOcrRequest) { + if (analysisOcrRequest.getFile() != null && analysisOcrRequest.getFile().exists()) { try { - boolean deleted = ocrRequest.getFile().delete(); + boolean deleted = analysisOcrRequest.getFile().delete(); if (!deleted) { - log.warn("临时文件删除失败: {}", ocrRequest.getFile().getAbsolutePath()); + log.warn("临时文件删除失败: {}", analysisOcrRequest.getFile().getAbsolutePath()); } else { - log.debug("临时文件已删除: {}", ocrRequest.getFile().getAbsolutePath()); + log.debug("临时文件已删除: {}", analysisOcrRequest.getFile().getAbsolutePath()); } } catch (SecurityException e) { - log.error("删除临时文件时发生安全异常: {}", ocrRequest.getFile().getAbsolutePath(), e); + log.error("删除临时文件时发生安全异常: {}", analysisOcrRequest.getFile().getAbsolutePath(), e); } } } diff --git a/bonus-rabbitmq/pom.xml b/bonus-rabbitmq/pom.xml index 684a734..cec1ef2 100644 --- a/bonus-rabbitmq/pom.xml +++ b/bonus-rabbitmq/pom.xml @@ -29,6 +29,10 @@ com.bonus bonus-file + + com.bonus + bonus-analysis + diff --git a/bonus-rabbitmq/src/main/java/com/bonus/rabbitmq/consumer/RabbitMQConsumerService.java b/bonus-rabbitmq/src/main/java/com/bonus/rabbitmq/consumer/RabbitMQConsumerService.java index 0636dfb..84ba5cc 100644 --- a/bonus-rabbitmq/src/main/java/com/bonus/rabbitmq/consumer/RabbitMQConsumerService.java +++ b/bonus-rabbitmq/src/main/java/com/bonus/rabbitmq/consumer/RabbitMQConsumerService.java @@ -1,6 +1,8 @@ package com.bonus.rabbitmq.consumer; -import com.bonus.common.domain.ocr.dto.OcrRequest; +import com.bonus.analysis.service.IASAnalysisService; +import com.bonus.common.domain.analysis.vo.AnalysisLabelItemOcrVo; +import com.bonus.common.domain.ocr.dto.AnalysisOcrRequest; import com.bonus.common.domain.ocr.vo.AnalysisResponse; import com.bonus.common.domain.rabbitmq.dto.RabbitMqMessage; import com.bonus.common.utils.FileUtil; @@ -10,6 +12,7 @@ import com.bonus.ocr.service.AnalysisOcrService; import com.fasterxml.jackson.databind.ObjectMapper; import com.rabbitmq.client.Channel; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; @@ -18,7 +21,9 @@ import javax.annotation.Resource; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.List; import java.util.Objects; +import java.util.Optional; /** * @className:RabbitMQConsumerService @@ -42,6 +47,11 @@ public class RabbitMQConsumerService { @Resource(name = "AnalysisOcrService") private AnalysisOcrService analysisOcrService; + @Resource(name = "IASAnalysisService") + private IASAnalysisService analysisService; + + + @RabbitListener( queues = "myQueue", containerFactory = "multiConsumerFactory" // 使用上面配置的工厂,保证按顺序消费 @@ -100,7 +110,18 @@ public class RabbitMQConsumerService { String uploadPath = message.getUploadPath(); File fileFromMinio = getFileFromMinio(uploadPath); AnalysisResponse ocrResponse = performAnalysisRecognition(fileFromMinio); - + String folderPath = Optional.ofNullable(ocrResponse) + .map(AnalysisResponse::getData) + .map(data -> data.get("folder_path")) + .filter(Objects::nonNull) + .map(Object::toString) + .orElse(null); + if(StringUtils.isNotBlank(folderPath)) { + // 一次处理解析成功后执行二次处理 + performAnalysisRecognition2(message, folderPath); + }else{ + // 解析失败 + } } /** @@ -131,8 +152,8 @@ public class RabbitMQConsumerService { */ private AnalysisResponse performAnalysisRecognition(File file) { try { - OcrRequest ocrRequest = buildOcrRequest(file); - AnalysisResponse ocrResponse = analysisOcrService.callOcrService(ocrRequest); + AnalysisOcrRequest analysisOcrRequest = buildOcrRequest(file); + AnalysisResponse ocrResponse = analysisOcrService.callOcrService(analysisOcrRequest); // 修复:检查 招标解析算法服务 响应是否为 null if (Objects.isNull(ocrResponse)) { throw new RuntimeException("招标解析算法服务返回结果为空"); @@ -146,17 +167,49 @@ public class RabbitMQConsumerService { } } + public void performAnalysisRecognition2(RabbitMqMessage message,String folderPath){ + try { + List labelItemVoList = analysisService.getAnalysisLabels(message.getAnalysisLabelId(),message.getTemplateId()); + AnalysisOcrRequest analysisOcrRequest = buildOcrRequest2(folderPath, labelItemVoList); + AnalysisResponse ocrResponse2 = analysisOcrService.callOcrService(analysisOcrRequest); + // 修复:检查 招标解析算法服务 响应是否为 null + if (Objects.isNull(ocrResponse2)) { + throw new RuntimeException("招标解析算法服务返回结果为空"); + } + log.info("OCR识别成功 - 数据: {}", ocrResponse2.getData()); + } catch (IOException e) { + log.error("OCR识别失败", e); + throw new RuntimeException("OCR识别失败: " + e.getMessage(), e); + } + } + /** - * 构建招标解析算法服务请求 + * 构建招标解析算法服务请求 - 一次处理 * @param file * @return OcrRequest * @author cwchen * @date 2025/11/29 13:29 */ - private OcrRequest buildOcrRequest(File file) { - OcrRequest ocrRequest = new OcrRequest(); + private AnalysisOcrRequest buildOcrRequest(File file) { + AnalysisOcrRequest ocrRequest = new AnalysisOcrRequest(); ocrRequest.setFile(file); ocrRequest.setType(FileUtil.getMimeTypeByFilename(file.getName())); + ocrRequest.setAnalysisType("1"); + return ocrRequest; + } + + /** + * 构建招标解析算法服务请求 - 二次处理 + * @return OcrRequest + * @author cwchen + * @date 2025/11/29 13:29 + */ + private AnalysisOcrRequest buildOcrRequest2(String filePath,List list) { + AnalysisOcrRequest ocrRequest = new AnalysisOcrRequest(); + ocrRequest.setCover_keys(""); + ocrRequest.setExtraction_items(list); + ocrRequest.setDoc_folder_path(filePath); + ocrRequest.setAnalysisType("2"); return ocrRequest; } } \ No newline at end of file diff --git a/bonus-rabbitmq/src/main/java/com/bonus/rabbitmq/service/SendRabbitMqService.java b/bonus-rabbitmq/src/main/java/com/bonus/rabbitmq/service/SendRabbitMqService.java index bf1a113..f73389e 100644 --- a/bonus-rabbitmq/src/main/java/com/bonus/rabbitmq/service/SendRabbitMqService.java +++ b/bonus-rabbitmq/src/main/java/com/bonus/rabbitmq/service/SendRabbitMqService.java @@ -21,13 +21,26 @@ public class SendRabbitMqService { @Resource(name = "RabbitMQProducerService") private RabbitMQProducerService rabbitMQProducerService; + /** + * 招标解析mq + * @param list + * @return void + * @author cwchen + * @date 2025/11/29 14:04 + */ public void sendRabbitMq(List> list){ for (Map map : list) { String taskId = map.get("taskId").toString(); String uploadPath = map.get("uploadPath").toString(); + String analysisLabelId = map.get("analysisLabelId").toString(); + String businessId = map.get("businessId").toString(); + String templateId = map.get("templateId").toString(); RabbitMqMessage mqMessage = new RabbitMqMessage(); mqMessage.setMessageId(taskId); mqMessage.setUploadPath(uploadPath); + mqMessage.setBusinessId(Long.parseLong(businessId)); + mqMessage.setAnalysisLabelId(Long.parseLong(analysisLabelId)); + mqMessage.setTemplateId(Long.parseLong(templateId)); mqMessage.setTaskName("OCR_PROCESS"); rabbitMQProducerService.sendMessageSync(mqMessage); } diff --git a/bonus-system/src/main/resources/mapper/system/SelectMapper.xml b/bonus-system/src/main/resources/mapper/system/SelectMapper.xml index a858b47..4f72366 100644 --- a/bonus-system/src/main/resources/mapper/system/SelectMapper.xml +++ b/bonus-system/src/main/resources/mapper/system/SelectMapper.xml @@ -8,7 +8,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"