招标解析
This commit is contained in:
parent
783490fa2e
commit
8b8ba24e1c
|
|
@ -107,6 +107,14 @@ public class AnalysisController extends BaseController {
|
|||
return analysisService.saveBidData(dto);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "招标解析", notes = "查看解析数据")
|
||||
@GetMapping("getAnalysisData")
|
||||
@SysLog(title = "招标解析", module = "招标解析->查看解析数据", businessType = OperaType.QUERY, details = "查看解析数据", logType = 1)
|
||||
@RequiresPermissions("analysis:analysis:query")
|
||||
public AjaxResult getAnalysisData(AnalysisDto dto) {
|
||||
return analysisService.getAnalysisData(dto);
|
||||
}
|
||||
|
||||
@ApiOperation(value = "测试mq异步消息", notes = "测试mq异步消息")
|
||||
@GetMapping("/testAsyncMq2")
|
||||
public AjaxResult testAsyncMq2() {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ 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.AnalysisVo;
|
||||
import com.bonus.common.domain.analysis.vo.ProBidAnalysisResultVo;
|
||||
import com.bonus.common.domain.file.vo.ResourceFileVo;
|
||||
import com.bonus.common.domain.file.vo.SysFile;
|
||||
import com.bonus.common.domain.ocr.dto.OcrRequest;
|
||||
|
|
@ -24,6 +25,7 @@ import com.bonus.ocr.service.WordConvertPdfService;
|
|||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.checkerframework.checker.units.qual.A;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||
|
|
@ -33,6 +35,7 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -112,7 +115,7 @@ public class AnalysisService {
|
|||
})
|
||||
.join(); // 确保每个消息发送完成后再进行下一个
|
||||
}*/
|
||||
List<Map<String,Object>> list = new ArrayList<>();
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
for (int i = 0; i < 2; i++) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
String taskId = UUID.randomUUID().toString();
|
||||
|
|
@ -128,6 +131,7 @@ public class AnalysisService {
|
|||
|
||||
/**
|
||||
* 招标解析->查询列表
|
||||
*
|
||||
* @param dto
|
||||
* @return List<AnalysisVo>
|
||||
* @author cwchen
|
||||
|
|
@ -139,6 +143,7 @@ public class AnalysisService {
|
|||
|
||||
/**
|
||||
* 招标解析->新建项目
|
||||
*
|
||||
* @param dto
|
||||
* @return AjaxResult
|
||||
* @author cwchen
|
||||
|
|
@ -159,7 +164,7 @@ public class AnalysisService {
|
|||
List<ProComposition> compositions = new ArrayList<>();
|
||||
|
||||
for (String uploadType : dto.getUploadType()) {
|
||||
ProComposition vo = createVo(dto.getProId(), uploadType,"1");
|
||||
ProComposition vo = createVo(dto.getProId(), uploadType, "1");
|
||||
compositions.add(vo);
|
||||
}
|
||||
// 保存项目的文件组成数据
|
||||
|
|
@ -178,6 +183,7 @@ public class AnalysisService {
|
|||
msg.setProId(dto.getProId());
|
||||
msg.setTemplateId(dto.getTemplateId());
|
||||
msg.setAnalysisLabelId(dto.getAnalysisLabelId());
|
||||
msg.setProCompositionId(id);
|
||||
msg.setCompositionType(1);
|
||||
msg.setTaskName("OCR_PROCESS");
|
||||
asyncTaskList.add(msg);
|
||||
|
|
@ -187,13 +193,13 @@ public class AnalysisService {
|
|||
AsyncManager.me().executeSendRabbitMqMessage(asyncTaskList);
|
||||
return AjaxResult.success();
|
||||
} catch (Exception e) {
|
||||
log.error(e.toString(),e);
|
||||
log.error(e.toString(), e);
|
||||
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
||||
return AjaxResult.error();
|
||||
}
|
||||
}
|
||||
|
||||
public ProComposition createVo(Long proId,String value,String compositionType){
|
||||
public ProComposition createVo(Long proId, String value, String compositionType) {
|
||||
ProComposition proComposition = new ProComposition();
|
||||
proComposition.setProId(proId);
|
||||
proComposition.setCompositionFileName(value);
|
||||
|
|
@ -203,6 +209,7 @@ public class AnalysisService {
|
|||
|
||||
/**
|
||||
* 招标解析->查看详情
|
||||
*
|
||||
* @param dto
|
||||
* @return AjaxResult
|
||||
* @author cwchen
|
||||
|
|
@ -219,15 +226,16 @@ public class AnalysisService {
|
|||
try {
|
||||
WordConvertPdfResponse wordConvertPdfResponse = wordConvertPdfService.convertWordToPdf(ocrRequest);
|
||||
String pdfBase64 = wordConvertPdfResponse.getPdfBase64();
|
||||
Base64ToPdfConverter.convertToFile(pdfBase64,"C:\\Users\\10488\\Desktop\\test12121212.pdf");
|
||||
Base64ToPdfConverter.convertToFile(pdfBase64, "C:\\Users\\10488\\Desktop\\test12121212.pdf");
|
||||
} catch (IOException e) {
|
||||
log.error(e.toString(),e);
|
||||
log.error(e.toString(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 招标解析->查看项目详情
|
||||
*
|
||||
* @param dto
|
||||
* @return AjaxResult
|
||||
* @author cwchen
|
||||
|
|
@ -239,7 +247,7 @@ public class AnalysisService {
|
|||
List<String> bidCompositions = analysisService.getBidCompositionByBid(analysisVo);
|
||||
analysisVo.setBidCompositions(bidCompositions);
|
||||
// 查询类型为2时查询文件
|
||||
if(dto.getQueryType() == 2){
|
||||
if (dto.getQueryType() == 2) {
|
||||
// 查询项目组成文件
|
||||
dto.setCompositionType("1");
|
||||
List<ProComposition> compositions = analysisService.getProComposition(dto);
|
||||
|
|
@ -248,10 +256,10 @@ public class AnalysisService {
|
|||
for (ProComposition composition : compositions) {
|
||||
List<ResourceFileVo> fileVoList = sourceFileService.getFilesByTable(composition.getId(), TableConstants.TB_PRO_COMPOSITION);
|
||||
// 4.取minio中的文件访问路径
|
||||
if(CollectionUtils.isNotEmpty(fileVoList)){
|
||||
if (CollectionUtils.isNotEmpty(fileVoList)) {
|
||||
for (ResourceFileVo file : fileVoList) {
|
||||
SysFile sysFile = fileUploadService.getFile(file.getFilePath());
|
||||
if(Objects.nonNull(sysFile)){
|
||||
if (Objects.nonNull(sysFile)) {
|
||||
file.setLsFilePath(sysFile.getUrl());
|
||||
}
|
||||
}
|
||||
|
|
@ -265,6 +273,7 @@ public class AnalysisService {
|
|||
|
||||
/**
|
||||
* 招标解析->更新项目数据
|
||||
*
|
||||
* @param dto
|
||||
* @return AjaxResult
|
||||
* @author cwchen
|
||||
|
|
@ -282,7 +291,7 @@ public class AnalysisService {
|
|||
analysisService.editProData(dto);
|
||||
return AjaxResult.success();
|
||||
} catch (Exception e) {
|
||||
log.error(e.toString(),e);
|
||||
log.error(e.toString(), e);
|
||||
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
||||
return AjaxResult.error();
|
||||
}
|
||||
|
|
@ -300,7 +309,7 @@ public class AnalysisService {
|
|||
analysisService.editBidData(dto);
|
||||
return AjaxResult.success();
|
||||
} catch (Exception e) {
|
||||
log.error(e.toString(),e);
|
||||
log.error(e.toString(), e);
|
||||
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
||||
return AjaxResult.error();
|
||||
}
|
||||
|
|
@ -308,6 +317,7 @@ public class AnalysisService {
|
|||
|
||||
/**
|
||||
* 删除项目数据
|
||||
*
|
||||
* @param dto
|
||||
* @return AjaxResult
|
||||
* @author cwchen
|
||||
|
|
@ -327,9 +337,9 @@ public class AnalysisService {
|
|||
analysisService.delBidData(dto);
|
||||
// 删除项目组成文件
|
||||
List<ProComposition> compositions = analysisService.getProComposition(dto);
|
||||
if(CollectionUtils.isNotEmpty(compositions)){
|
||||
if (CollectionUtils.isNotEmpty(compositions)) {
|
||||
for (ProComposition composition : compositions) {
|
||||
sourceFileService.delResourceFileByTable(composition.getId(),TableConstants.TB_PRO_COMPOSITION);
|
||||
sourceFileService.delResourceFileByTable(composition.getId(), TableConstants.TB_PRO_COMPOSITION);
|
||||
}
|
||||
}
|
||||
// 删除模板组成数据
|
||||
|
|
@ -338,7 +348,7 @@ public class AnalysisService {
|
|||
analysisService.delProBidAnalysisResult(dto);
|
||||
return AjaxResult.success();
|
||||
} catch (Exception e) {
|
||||
log.error(e.toString(),e);
|
||||
log.error(e.toString(), e);
|
||||
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
||||
return AjaxResult.error();
|
||||
}
|
||||
|
|
@ -346,6 +356,7 @@ public class AnalysisService {
|
|||
|
||||
/**
|
||||
* 招标解析->标段提交文件解析
|
||||
*
|
||||
* @param dto
|
||||
* @return AjaxResult
|
||||
* @author cwchen
|
||||
|
|
@ -365,7 +376,7 @@ public class AnalysisService {
|
|||
List<ProComposition> compositions = new ArrayList<>();
|
||||
|
||||
for (String uploadType : dto.getUploadType()) {
|
||||
ProComposition vo = createVo(dto.getBidId(), uploadType,"2");
|
||||
ProComposition vo = createVo(dto.getBidId(), uploadType, "2");
|
||||
compositions.add(vo);
|
||||
}
|
||||
// 保存标段的文件组成数据
|
||||
|
|
@ -391,10 +402,106 @@ public class AnalysisService {
|
|||
AsyncManager.me().executeSendRabbitMqMessage(asyncTaskList);
|
||||
return AjaxResult.success();
|
||||
} catch (Exception e) {
|
||||
log.error(e.toString(),e);
|
||||
log.error(e.toString(), e);
|
||||
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
||||
return AjaxResult.error();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看标段解析数据
|
||||
*
|
||||
* @param dto
|
||||
* @return AjaxResult
|
||||
* @author cwchen
|
||||
* @date 2025/12/6 13:41
|
||||
*/
|
||||
public AjaxResult getAnalysisData(AnalysisDto dto) {
|
||||
// 查询工程和标段的解析数据
|
||||
List<ProBidAnalysisResultVo> proList = analysisService.getProBidAnalysisResult(dto, 1);
|
||||
List<ProBidAnalysisResultVo> bidList = analysisService.getProBidAnalysisResult(dto, 2);
|
||||
// 2. 判空处理,防止空指针
|
||||
/*if (CollectionUtils.isNotEmpty(proList) && CollectionUtils.isNotEmpty(bidList)) {
|
||||
// 3. 将 bidList 转换为 Map<ItemId, Content>
|
||||
// Key: analysisLabelItemId, Value: analysisContent
|
||||
// (v1, v2) -> v1 是为了防止 bidList 中有重复 ID 报错,取第一个找到的值
|
||||
Map<String, String> bidContentMap = bidList.stream()
|
||||
.filter(item -> item.getAnalysisLabelItemId() != null && item.getAnalysisContent() != null)
|
||||
.collect(Collectors.toMap(
|
||||
ProBidAnalysisResultVo::getAnalysisLabelItemId,
|
||||
ProBidAnalysisResultVo::getAnalysisContent,
|
||||
(v1, v2) -> v1
|
||||
));
|
||||
|
||||
// 4. 遍历 proList 进行合并
|
||||
for (ProBidAnalysisResultVo proItem : proList) {
|
||||
// 逻辑:如果 pro 的内容为空(null 或 空字符串),才去尝试合并
|
||||
if (proItem.getAnalysisContent() == null || proItem.getAnalysisContent().trim().isEmpty()) {
|
||||
// 根据 ID 从 Map 中获取内容
|
||||
String contentFromBid = bidContentMap.get(proItem.getAnalysisLabelItemId());
|
||||
// 如果 bid 中有值,则赋值
|
||||
if (contentFromBid != null) {
|
||||
proItem.setAnalysisContent(contentFromBid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
List<ProBidAnalysisResultVo> tree = buildTree(proList, "0");
|
||||
return AjaxResult.success("查询成功", tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将扁平 List 转换为树形结构,并按 analysisSort 排序。
|
||||
*
|
||||
* @param flatList 扁平的 ProBidAnalysisResultVo 列表
|
||||
* @param rootId 根节点的 parentId (通常是 null, "0", 或其他特定值)
|
||||
* @return 排序后的树形结构根节点列表
|
||||
*/
|
||||
public static List<ProBidAnalysisResultVo> buildTree(
|
||||
List<ProBidAnalysisResultVo> flatList,
|
||||
String rootId) {
|
||||
|
||||
if (flatList == null || flatList.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// 1. 按 parentId 分组:Map<String (parentId), List<ProBidAnalysisResultVo>>
|
||||
// 这一步是性能优化的关键,将 O(N^2) 降低到 O(N)
|
||||
Map<String, List<ProBidAnalysisResultVo>> map = flatList.stream()
|
||||
.filter(item -> item.getParentId() != null) // 过滤掉 parentId 为 null 的情况
|
||||
.collect(Collectors.groupingBy(ProBidAnalysisResultVo::getParentId));
|
||||
|
||||
// 2. 递归构建树
|
||||
return buildTreeRecursive(rootId, map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归构建树的核心逻辑
|
||||
*/
|
||||
private static List<ProBidAnalysisResultVo> buildTreeRecursive(
|
||||
String parentId,
|
||||
Map<String, List<ProBidAnalysisResultVo>> map) {
|
||||
|
||||
// 1. 从 Map 中取出当前 parentId 的所有子节点
|
||||
List<ProBidAnalysisResultVo> childrenList = map.getOrDefault(parentId, Collections.emptyList());
|
||||
|
||||
// 2. 对当前层级的子节点列表进行排序 (根据 analysisSort 升序)
|
||||
// 注意:analysisSort 可能是 Integer,需要处理 null 值,通常放在最后或最前
|
||||
childrenList.sort(Comparator.comparing(
|
||||
ProBidAnalysisResultVo::getAnalysisSort,
|
||||
Comparator.nullsLast(Comparator.naturalOrder())
|
||||
));
|
||||
|
||||
// 3. 递归处理每个子节点
|
||||
for (ProBidAnalysisResultVo node : childrenList) {
|
||||
// 递归调用,以当前节点的 analysisLabelItemId 作为新的 parentId
|
||||
List<ProBidAnalysisResultVo> grandChildren = buildTreeRecursive(node.getAnalysisLabelItemId(), map);
|
||||
|
||||
// 设置子节点
|
||||
node.setChildren(grandChildren);
|
||||
}
|
||||
// 4. 返回当前层级已排序且完成子节点挂载的列表
|
||||
return childrenList;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,11 @@ 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 com.bonus.common.domain.analysis.vo.ProBidAnalysisResultVo;
|
||||
import com.bonus.common.domain.ocr.vo.TwoAnalysisResponse;
|
||||
import com.bonus.common.domain.rabbitmq.dto.RabbitMqMessage;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.security.core.parameters.P;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -96,12 +99,12 @@ public interface IASAnalysisMapper {
|
|||
|
||||
/**
|
||||
* 获取解析标签项
|
||||
* @param analysisLabelId
|
||||
* @param message
|
||||
* @return List<AnalysisLabelItemVo>
|
||||
* @author cwchen
|
||||
* @date 2025/11/29 14:49
|
||||
*/
|
||||
List<AnalysisLabelItemOcrVo> getAnalysisLabels(@Param("analysisLabelId") Long analysisLabelId, @Param("templateId") Long templateId);
|
||||
List<AnalysisLabelItemOcrVo> getAnalysisLabels(RabbitMqMessage message);
|
||||
|
||||
/**
|
||||
* 删除项目数据
|
||||
|
|
@ -174,4 +177,52 @@ public interface IASAnalysisMapper {
|
|||
* @date 2025/11/30 15:03
|
||||
*/
|
||||
List<ProComposition> getProCompositionState(RabbitMqMessage message);
|
||||
|
||||
/**
|
||||
* isLabelExist
|
||||
* @param message
|
||||
* @return int
|
||||
* @author cwchen
|
||||
* @date 2025/12/6 11:07
|
||||
*/
|
||||
int isLabelExist(RabbitMqMessage message);
|
||||
|
||||
/**
|
||||
* 从解析内容中读取标签配置
|
||||
* @param message
|
||||
* @return List<AnalysisLabelItemOcrVo>
|
||||
* @author cwchen
|
||||
* @date 2025/12/6 11:13
|
||||
*/
|
||||
List<AnalysisLabelItemOcrVo> getAnalysisLabelsByProOrBid(RabbitMqMessage message);
|
||||
|
||||
/**
|
||||
* 保存解析标签数据
|
||||
* @param message
|
||||
* @param labelItemVoList
|
||||
* @return void
|
||||
* @author cwchen
|
||||
* @date 2025/12/6 12:26
|
||||
*/
|
||||
void saveProBidAnalysisData(@Param("params") RabbitMqMessage message, @Param("list") List<AnalysisLabelItemOcrVo> labelItemVoList);
|
||||
|
||||
/**
|
||||
* 更新解析标签数据
|
||||
* @param message
|
||||
* @param analysisDataList
|
||||
* @return void
|
||||
* @author cwchen
|
||||
* @date 2025/12/6 13:17
|
||||
*/
|
||||
void updateProBidAnalysisData(@Param("params") RabbitMqMessage message, @Param("list")List<TwoAnalysisResponse> analysisDataList);
|
||||
|
||||
/**
|
||||
* 查询工程和标段的解析数据
|
||||
* @param dto
|
||||
* @param type
|
||||
* @return List<ProBidAnalysisResultVo>
|
||||
* @author cwchen
|
||||
* @date 2025/12/6 13:47
|
||||
*/
|
||||
List<ProBidAnalysisResultVo> getProBidAnalysisResult(@Param("params") AnalysisDto dto,@Param("type") int type);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ 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 com.bonus.common.domain.analysis.vo.ProBidAnalysisResultVo;
|
||||
import com.bonus.common.domain.ocr.vo.TwoAnalysisResponse;
|
||||
import com.bonus.common.domain.rabbitmq.dto.RabbitMqMessage;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -22,6 +24,7 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 招标解析->查询列表
|
||||
*
|
||||
* @param dto
|
||||
* @return List<AnalysisVo>
|
||||
* @author cwchen
|
||||
|
|
@ -31,6 +34,7 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 保存项目数据
|
||||
*
|
||||
* @param dto
|
||||
* @return void
|
||||
* @author cwchen
|
||||
|
|
@ -40,6 +44,7 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 招标解析->查看详情
|
||||
*
|
||||
* @param dto
|
||||
* @return List<AnalysisBidVo>
|
||||
* @author cwchen
|
||||
|
|
@ -49,6 +54,7 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 招标解析->查看项目详情
|
||||
*
|
||||
* @param dto
|
||||
* @return AnalysisVo
|
||||
* @author cwchen
|
||||
|
|
@ -58,6 +64,7 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 更新项目数据
|
||||
*
|
||||
* @param dto
|
||||
* @return void
|
||||
* @author cwchen
|
||||
|
|
@ -67,6 +74,7 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 更新标段数据
|
||||
*
|
||||
* @param dto
|
||||
* @return void
|
||||
* @author cwchen
|
||||
|
|
@ -76,6 +84,7 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 保存项目的文件组成
|
||||
*
|
||||
* @param compositions
|
||||
* @return void
|
||||
* @author cwchen
|
||||
|
|
@ -85,6 +94,7 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 查询项目组成文件
|
||||
*
|
||||
* @return List<ProComposition>
|
||||
* @author cwchen
|
||||
* @date 2025/11/26 15:54
|
||||
|
|
@ -94,15 +104,17 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 获取解析标签项
|
||||
* @param analysisLabelId
|
||||
*
|
||||
* @param message
|
||||
* @return List<AnalysisLabelItemVo>
|
||||
* @author cwchen
|
||||
* @date 2025/11/29 14:48
|
||||
*/
|
||||
List<AnalysisLabelItemOcrVo> getAnalysisLabels(Long analysisLabelId, Long templateId);
|
||||
List<AnalysisLabelItemOcrVo> getAnalysisLabels(RabbitMqMessage message);
|
||||
|
||||
/**
|
||||
* 删除项目数据
|
||||
*
|
||||
* @param dto
|
||||
* @return void
|
||||
* @author cwchen
|
||||
|
|
@ -112,6 +124,7 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 删除标段数据
|
||||
*
|
||||
* @param dto
|
||||
* @return void
|
||||
* @author cwchen
|
||||
|
|
@ -121,6 +134,7 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 删除模板组成数据
|
||||
*
|
||||
* @param dto
|
||||
* @return void
|
||||
* @author cwchen
|
||||
|
|
@ -130,6 +144,7 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 删除项目/标段解析数据
|
||||
*
|
||||
* @param dto
|
||||
* @return void
|
||||
* @author cwchen
|
||||
|
|
@ -139,6 +154,7 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 查询标段文件的文件组成
|
||||
*
|
||||
* @param analysisVo
|
||||
* @return List<ProComposition>
|
||||
* @author cwchen
|
||||
|
|
@ -148,6 +164,7 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 更新项目或者标段的文件组成的解析状态
|
||||
*
|
||||
* @param message
|
||||
* @return void
|
||||
* @author cwchen
|
||||
|
|
@ -157,6 +174,7 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 更新项目或者标段的解析状态
|
||||
*
|
||||
* @param message
|
||||
* @return void
|
||||
* @author cwchen
|
||||
|
|
@ -166,10 +184,61 @@ public interface IASAnalysisService {
|
|||
|
||||
/**
|
||||
* 查询项目或标段的组成文件的解析状态
|
||||
*
|
||||
* @param message
|
||||
* @return List<ProComposition>
|
||||
* @author cwchen
|
||||
* @date 2025/11/30 15:02
|
||||
*/
|
||||
List<ProComposition> getProCompositionState(RabbitMqMessage message);
|
||||
|
||||
/**
|
||||
* 查询项目标签是否已经保存
|
||||
*
|
||||
* @param message
|
||||
* @return int
|
||||
* @author cwchen
|
||||
* @date 2025/12/6 11:06
|
||||
*/
|
||||
int isLabelExist(RabbitMqMessage message);
|
||||
|
||||
/**
|
||||
* 从解析结果中读取标签项配置
|
||||
*
|
||||
* @param message
|
||||
* @return List<AnalysisLabelItemOcrVo>
|
||||
* @author cwchen
|
||||
* @date 2025/12/6 11:11
|
||||
*/
|
||||
List<AnalysisLabelItemOcrVo> getAnalysisLabelsByProOrBid(RabbitMqMessage message);
|
||||
|
||||
/**
|
||||
* 保存解析标签数据
|
||||
* @param message
|
||||
* @param labelItemVoList
|
||||
* @return void
|
||||
* @author cwchen
|
||||
* @date 2025/12/6 12:26
|
||||
*/
|
||||
void saveProBidAnalysisData(RabbitMqMessage message, List<AnalysisLabelItemOcrVo> labelItemVoList);
|
||||
|
||||
/**
|
||||
* 更新解析标签数据
|
||||
* @param message
|
||||
* @param analysisDataList
|
||||
* @return void
|
||||
* @author cwchen
|
||||
* @date 2025/12/6 13:16
|
||||
*/
|
||||
void updateProBidAnalysisData(RabbitMqMessage message, List<TwoAnalysisResponse> analysisDataList);
|
||||
|
||||
/**
|
||||
* 查询工程和标段的解析数据
|
||||
* @param dto
|
||||
* @param type
|
||||
* @return List<ProBidAnalysisResultVo>
|
||||
* @author cwchen
|
||||
* @date 2025/12/6 13:46
|
||||
*/
|
||||
List<ProBidAnalysisResultVo> getProBidAnalysisResult(AnalysisDto dto, int type);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ 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 com.bonus.common.domain.analysis.vo.ProBidAnalysisResultVo;
|
||||
import com.bonus.common.domain.ocr.vo.TwoAnalysisResponse;
|
||||
import com.bonus.common.domain.rabbitmq.dto.RabbitMqMessage;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
|
@ -82,9 +84,9 @@ public class ASAnalysisServiceImpl implements IASAnalysisService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<AnalysisLabelItemOcrVo> getAnalysisLabels(Long analysisLabelId, Long templateId) {
|
||||
public List<AnalysisLabelItemOcrVo> getAnalysisLabels(RabbitMqMessage message) {
|
||||
try {
|
||||
return Optional.ofNullable(analysisMapper.getAnalysisLabels(analysisLabelId,templateId)).orElse(new ArrayList());
|
||||
return Optional.ofNullable(analysisMapper.getAnalysisLabels(message)).orElse(new ArrayList());
|
||||
} catch (Exception e) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
|
@ -135,4 +137,29 @@ public class ASAnalysisServiceImpl implements IASAnalysisService {
|
|||
public List<ProComposition> getProCompositionState(RabbitMqMessage message) {
|
||||
return analysisMapper.getProCompositionState(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int isLabelExist(RabbitMqMessage message) {
|
||||
return analysisMapper.isLabelExist(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AnalysisLabelItemOcrVo> getAnalysisLabelsByProOrBid(RabbitMqMessage message) {
|
||||
return analysisMapper.getAnalysisLabelsByProOrBid(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveProBidAnalysisData(RabbitMqMessage message, List<AnalysisLabelItemOcrVo> labelItemVoList) {
|
||||
analysisMapper.saveProBidAnalysisData(message,labelItemVoList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProBidAnalysisData(RabbitMqMessage message, List<TwoAnalysisResponse> analysisDataList) {
|
||||
analysisMapper.updateProBidAnalysisData(message,analysisDataList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProBidAnalysisResultVo> getProBidAnalysisResult(AnalysisDto dto, int type) {
|
||||
return analysisMapper.getProBidAnalysisResult(dto,type);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,6 +112,34 @@
|
|||
)
|
||||
</foreach>
|
||||
</insert>
|
||||
<!--保存解析标签数据-->
|
||||
<insert id="saveProBidAnalysisData">
|
||||
INSERT INTO tb_pro_bid_analysis_result
|
||||
(id,pro_id,analysis_label_item_id,analysis_name,
|
||||
analysis_code,parent_id,analysis_level,analysis_sort,
|
||||
extract_content,analysis_type
|
||||
)
|
||||
VALUES
|
||||
<foreach collection="list" item="item" separator=",">
|
||||
(
|
||||
<if test="params.compositionType == 1">
|
||||
#{params.proId},
|
||||
</if>
|
||||
<if test="params.compositionType == 2">
|
||||
#{params.bidId},
|
||||
</if>
|
||||
#{params.proId},
|
||||
#{item.id},
|
||||
#{item.searchKeyword},
|
||||
#{item.targetField},
|
||||
#{item.parentId},
|
||||
#{item.analysisLevel},
|
||||
#{item.analysisSort},
|
||||
#{item.description},
|
||||
#{params.compositionType}
|
||||
)
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<!--查询项目文件组成详情-->
|
||||
<select id="getProComposition" resultType="com.bonus.common.domain.analysis.po.ProComposition">
|
||||
|
|
@ -151,7 +179,56 @@
|
|||
AND pro_id = #{bidId}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<!--查询标签是否已经保存-->
|
||||
<select id="isLabelExist" resultType="java.lang.Integer">
|
||||
SELECT COUNT(*) FROM tb_pro_bid_analysis_result
|
||||
<where>
|
||||
<if test="compositionType == 1">
|
||||
id = #{proId} AND analysis_type = '1'
|
||||
</if>
|
||||
<if test="compositionType == 2">
|
||||
AND id = #{bidId} AND analysis_type = '2'
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
<!--从解析内容中读取标签配置-->
|
||||
<select id="getAnalysisLabelsByProOrBid" resultType="com.bonus.common.domain.analysis.vo.AnalysisLabelItemOcrVo">
|
||||
SELECT tpbar.analysis_label_item_id AS id,
|
||||
tpbar.analysis_name AS searchKeyword,
|
||||
tpbar.analysis_code AS analysisCode,
|
||||
tpbar.parent_id AS parentId,
|
||||
tpbar.analysis_level AS analysisLevel,
|
||||
tpbar.analysis_sort AS analysisSort,
|
||||
tpbar.extract_content AS description
|
||||
FROM tb_pro_bid_analysis_result tpbar
|
||||
<where>
|
||||
<if test="compositionType == 1">
|
||||
tpbar.id = #{proId} AND tpbar.analysis_type = '1'
|
||||
</if>
|
||||
<if test="compositionType == 2">
|
||||
AND tpbar.id = #{bidId} AND tpbar.analysis_type = '2'
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
<!--查询工程和标段的解析数据-->
|
||||
<select id="getProBidAnalysisResult" resultType="com.bonus.common.domain.analysis.vo.ProBidAnalysisResultVo">
|
||||
SELECT analysis_label_item_id AS analysisLabelItemId,
|
||||
analysis_name AS analysisName,
|
||||
analysis_code AS analysisCode,
|
||||
IFNULL(parent_id,'0') AS parentId,
|
||||
analysis_level AS analysisLevel,
|
||||
analysis_sort AS analysisSort,
|
||||
analysis_content AS analysisContent
|
||||
FROM tb_pro_bid_analysis_result
|
||||
<where>
|
||||
<if test="type == 1">
|
||||
AND id = #{params.proId}
|
||||
</if>
|
||||
<if test="type == 2">
|
||||
AND id = #{params.bidId}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
|
||||
<!--删除项目数据-->
|
||||
|
|
@ -175,12 +252,7 @@
|
|||
</update>
|
||||
<!--更新项目或者标段的文件组成的解析状态-->
|
||||
<update id="updateProCompositionState">
|
||||
<if test="compositionType == 1">
|
||||
UPDATE tb_pro_composition SET analysis_state = #{analysisState} WHERE pro_id = #{proId} AND composition_type = '1'
|
||||
</if>
|
||||
<if test="compositionType == 2">
|
||||
UPDATE tb_pro_composition SET analysis_state = #{analysisState} WHERE pro_id = #{bidId} AND composition_type = '2'
|
||||
</if>
|
||||
UPDATE tb_pro_composition SET analysis_state = #{analysisState} WHERE id = #{proCompositionId}
|
||||
</update>
|
||||
<!--更新项目或者标段的解析状态-->
|
||||
<update id="updateProOrBidState">
|
||||
|
|
@ -191,4 +263,16 @@
|
|||
UPDATE tb_pro_bid SET parsing_state = #{analysisState} WHERE bid_id = #{bidId}
|
||||
</if>
|
||||
</update>
|
||||
<!--更新解析标签数据-->
|
||||
<update id="updateProBidAnalysisData">
|
||||
<foreach collection="list" item="item" separator=";">
|
||||
UPDATE tb_pro_bid_analysis_result SET analysis_content = #{item.jsonStr} WHERE analysis_label_item_id = #{item.id}
|
||||
<if test="params.compositionType == 1">
|
||||
AND id = #{params.proId}
|
||||
</if>
|
||||
<if test="params.compositionType == 2">
|
||||
AND id = #{params.bidId}
|
||||
</if>
|
||||
</foreach>
|
||||
</update>
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
package com.bonus.common.domain.analysis.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @className:ProBidAnalysisResultVo
|
||||
* @author:cwchen
|
||||
* @date:2025-12-06-13:43
|
||||
* @version:1.0
|
||||
* @description:
|
||||
*/
|
||||
@Data
|
||||
public class ProBidAnalysisResultVo {
|
||||
|
||||
/**
|
||||
* 标段id / 项目id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
private Long proId;
|
||||
|
||||
/**
|
||||
* 配置id
|
||||
*/
|
||||
private String analysisLabelItemId;
|
||||
|
||||
/**
|
||||
* 解析名称
|
||||
*/
|
||||
private String analysisName;
|
||||
|
||||
/**
|
||||
* 解析编码
|
||||
*/
|
||||
private String analysisCode;
|
||||
|
||||
/**
|
||||
* 父节点
|
||||
*/
|
||||
private String parentId;
|
||||
|
||||
/**
|
||||
* 层级
|
||||
*/
|
||||
private Integer analysisLevel;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer analysisSort;
|
||||
|
||||
/**
|
||||
* 解析内容
|
||||
*/
|
||||
private String analysisContent;
|
||||
|
||||
private List<ProBidAnalysisResultVo> children;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.bonus.common.domain.ocr.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @className:OcrResponse
|
||||
* @author:cwchen
|
||||
* @date:2025-10-16-9:53
|
||||
* @version:1.0
|
||||
* @description: 招标解析响应结果
|
||||
*/
|
||||
@Data
|
||||
public class TwoAnalysisResponse {
|
||||
|
||||
private Long id;
|
||||
|
||||
private String jsonStr;
|
||||
}
|
||||
|
|
@ -16,7 +16,7 @@ public class RabbitMqMessage implements Serializable {
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 业务id
|
||||
* 项目id
|
||||
* */
|
||||
private Long proId;
|
||||
|
||||
|
|
@ -25,6 +25,11 @@ public class RabbitMqMessage implements Serializable {
|
|||
* */
|
||||
private Long bidId;
|
||||
|
||||
/**
|
||||
* 文件组成id
|
||||
* */
|
||||
private Long proCompositionId;
|
||||
|
||||
/**
|
||||
* 标签组id
|
||||
* */
|
||||
|
|
@ -70,4 +75,6 @@ public class RabbitMqMessage implements Serializable {
|
|||
* */
|
||||
private String analysisState;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,10 +153,6 @@ public class AnalysisOcrService {
|
|||
// 将请求对象转换为JSON字符串
|
||||
String jsonRequest = convertToJson(analysisOcrRequest);
|
||||
|
||||
// 打印请求参数
|
||||
log.info("OCR请求URL: {}", extractInfoUrl);
|
||||
log.info("OCR请求参数: {}", jsonRequest);
|
||||
|
||||
// 设置请求体为JSON
|
||||
StringEntity entity = new StringEntity(jsonRequest, ContentType.APPLICATION_JSON);
|
||||
httpPost.setEntity(entity);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.bonus.common.domain.analysis.po.ProComposition;
|
|||
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.ocr.vo.TwoAnalysisResponse;
|
||||
import com.bonus.common.domain.rabbitmq.dto.RabbitMqMessage;
|
||||
import com.bonus.common.utils.FileUtil;
|
||||
import com.bonus.file.config.MinioConfig;
|
||||
|
|
@ -17,14 +18,16 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||
|
||||
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;
|
||||
import java.sql.Array;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @className:RabbitMQConsumerService
|
||||
|
|
@ -52,7 +55,6 @@ public class RabbitMQConsumerService {
|
|||
private IASAnalysisService analysisService;
|
||||
|
||||
|
||||
|
||||
@RabbitListener(
|
||||
queues = "myQueue",
|
||||
containerFactory = "multiConsumerFactory" // 使用上面配置的工厂,保证按顺序消费
|
||||
|
|
@ -102,41 +104,188 @@ public class RabbitMQConsumerService {
|
|||
|
||||
/**
|
||||
* 处理招标解析算法服务业务
|
||||
*
|
||||
* @param message
|
||||
* @return void
|
||||
* @author cwchen
|
||||
* @date 2025/11/29 13:25
|
||||
*/
|
||||
private void processBusiness(RabbitMqMessage message) {
|
||||
// 更新项目或者标段的解析状态
|
||||
message.setAnalysisState("0");
|
||||
analysisService.updateProOrBidState(message);
|
||||
// 更新项目或者标段的文件组成的解析状态
|
||||
message.setAnalysisState("0");
|
||||
analysisService.updateProCompositionState(message);
|
||||
// 查询项目或标段的组成文件的解析状态
|
||||
List<ProComposition> proCompositionList = analysisService.getProCompositionState(message);
|
||||
// 招标解析执行一次处理
|
||||
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{
|
||||
// 解析失败
|
||||
public void processBusiness(RabbitMqMessage message) {
|
||||
try {
|
||||
// 开始解析 更新项目或者标段的解析状态 && 项目或者标段的文件组成的解析状态
|
||||
message.setAnalysisState("0");
|
||||
analysisService.updateProOrBidState(message);
|
||||
analysisService.updateProCompositionState(message);
|
||||
|
||||
// 招标解析执行一次处理
|
||||
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);
|
||||
// 更新文件组成的解析状态
|
||||
message.setAnalysisState("1");
|
||||
analysisService.updateProCompositionState(message);
|
||||
// 查询项目或标段的组成文件的解析状态
|
||||
List<ProComposition> proCompositionList = analysisService.getProCompositionState(message);
|
||||
Integer analysisState = determineAnalysisState(proCompositionList);
|
||||
if (analysisState != null) {
|
||||
message.setAnalysisState(analysisState.toString());
|
||||
analysisService.updateProOrBidState(message);
|
||||
}
|
||||
} else {
|
||||
// 第一次解析失败
|
||||
message.setAnalysisState("2");
|
||||
analysisService.updateProOrBidState(message);
|
||||
analysisService.updateProCompositionState(message);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
message.setAnalysisState("2");
|
||||
analysisService.updateProOrBidState(message);
|
||||
analysisService.updateProCompositionState(message);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解析一次处理
|
||||
*
|
||||
* @param file
|
||||
* @return AnalysisResponse
|
||||
* @author cwchen
|
||||
* @date 2025/11/29 13:30
|
||||
*/
|
||||
private AnalysisResponse performAnalysisRecognition(File file) {
|
||||
try {
|
||||
AnalysisOcrRequest analysisOcrRequest = buildOcrRequest(file);
|
||||
AnalysisResponse ocrResponse = analysisOcrService.callOcrService(analysisOcrRequest);
|
||||
// 修复:检查 招标解析算法服务 响应是否为 null
|
||||
if (Objects.isNull(ocrResponse)) {
|
||||
throw new RuntimeException("招标解析算法服务返回结果为空");
|
||||
}
|
||||
log.info("OCR识别成功 - 数据: {}", ocrResponse.getData());
|
||||
return ocrResponse;
|
||||
} catch (Exception e) {
|
||||
log.error("OCR识别失败", e);
|
||||
throw new RuntimeException("OCR识别失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析二次处理
|
||||
*
|
||||
* @param message
|
||||
* @param folderPath
|
||||
* @return void
|
||||
* @author cwchen
|
||||
* @date 2025/12/6 13:21
|
||||
*/
|
||||
public boolean performAnalysisRecognition2(RabbitMqMessage message, String folderPath) {
|
||||
try {
|
||||
// 查询项目/标段解析标签是否已经保存,未保存则从配置中读取 已保存则从项目/标段解析结果中读取
|
||||
int result = analysisService.isLabelExist(message);
|
||||
List<AnalysisLabelItemOcrVo> labelItemVoList = null;
|
||||
if (result == 0) {
|
||||
// 保存解析标签数据
|
||||
labelItemVoList = analysisService.getAnalysisLabels(message);
|
||||
analysisService.saveProBidAnalysisData(message, labelItemVoList);
|
||||
} else {
|
||||
labelItemVoList = analysisService.getAnalysisLabelsByProOrBid(message);
|
||||
}
|
||||
AnalysisOcrRequest analysisOcrRequest = buildOcrRequest2(folderPath, labelItemVoList);
|
||||
AnalysisResponse ocrResponse2 = analysisOcrService.callOcrService(analysisOcrRequest);
|
||||
// 修复:检查 招标解析算法服务 响应是否为 null
|
||||
if (Objects.isNull(ocrResponse2)) {
|
||||
throw new RuntimeException("招标解析算法服务返回结果为空");
|
||||
}
|
||||
log.info("OCR识别成功 - 数据: {}", ocrResponse2.getData());
|
||||
Map<String, Object> data = ocrResponse2.getData();
|
||||
List<TwoAnalysisResponse> analysisDataList = new ArrayList<>();
|
||||
// 更新解析标签数据
|
||||
analysisService.updateProBidAnalysisData(message, analysisDataList);
|
||||
return true;
|
||||
} 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 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<AnalysisLabelItemOcrVo> list) {
|
||||
AnalysisOcrRequest ocrRequest = new AnalysisOcrRequest();
|
||||
ocrRequest.setExtraction_items(list);
|
||||
ocrRequest.setDoc_folder_path(filePath);
|
||||
ocrRequest.setAnalysisType("2");
|
||||
return ocrRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理数据
|
||||
*
|
||||
* @param proCompositionList
|
||||
* @return Integer
|
||||
* @author cwchen
|
||||
* @date 2025/12/6 12:59
|
||||
*/
|
||||
public Integer determineAnalysisState(List<ProComposition> proCompositionList) {
|
||||
// 1. 判空处理
|
||||
if (proCompositionList == null || proCompositionList.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 2. 提取所有的 analysisState 并过滤掉 null
|
||||
List<String> states = proCompositionList.stream()
|
||||
.map(ProComposition::getAnalysisState)
|
||||
.filter(Objects::nonNull) // 需要 import java.util.Objects;
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 3. 根据规则判断
|
||||
if (states.isEmpty()) {
|
||||
return null; // 规则: 都是 null (或列表为空)
|
||||
}
|
||||
if (states.contains("2")) {
|
||||
return 2; // 规则: 存在一个 2
|
||||
}
|
||||
if (states.contains("0")) {
|
||||
return 0; // 规则: 存在至少一个 0 (且不存在 2)
|
||||
}
|
||||
|
||||
return 1; // 规则: 剩下的情况也就是都是 1 了
|
||||
}
|
||||
|
||||
/**
|
||||
* 从minio中获取文件
|
||||
*
|
||||
* @param uploadPath
|
||||
* @return File
|
||||
* @author cwchen
|
||||
|
|
@ -153,81 +302,4 @@ public class RabbitMQConsumerService {
|
|||
throw new RuntimeException("获取Minio文件失败: " + uploadPath, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用算法服务
|
||||
* @param file
|
||||
* @return AnalysisResponse
|
||||
* @author cwchen
|
||||
* @date 2025/11/29 13:30
|
||||
*/
|
||||
private AnalysisResponse performAnalysisRecognition(File file) {
|
||||
try {
|
||||
AnalysisOcrRequest analysisOcrRequest = buildOcrRequest(file);
|
||||
AnalysisResponse ocrResponse = analysisOcrService.callOcrService(analysisOcrRequest);
|
||||
// 修复:检查 招标解析算法服务 响应是否为 null
|
||||
if (Objects.isNull(ocrResponse)) {
|
||||
throw new RuntimeException("招标解析算法服务返回结果为空");
|
||||
}
|
||||
log.info("OCR识别成功 - 数据: {}", ocrResponse.getData());
|
||||
return ocrResponse;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("OCR识别失败", e);
|
||||
throw new RuntimeException("OCR识别失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void performAnalysisRecognition2(RabbitMqMessage message,String folderPath){
|
||||
try {
|
||||
|
||||
if(message.getBidId() == null){
|
||||
// 1.项目解析
|
||||
|
||||
}else {
|
||||
// 2.标段解析
|
||||
}
|
||||
|
||||
List<AnalysisLabelItemOcrVo> 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 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<AnalysisLabelItemOcrVo> list) {
|
||||
AnalysisOcrRequest ocrRequest = new AnalysisOcrRequest();
|
||||
ocrRequest.setExtraction_items(list);
|
||||
ocrRequest.setDoc_folder_path(filePath);
|
||||
ocrRequest.setAnalysisType("2");
|
||||
return ocrRequest;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue