招标解析算法服务

This commit is contained in:
cwchen 2025-11-29 16:57:05 +08:00
parent ecfbcf43bc
commit 36e99617e3
11 changed files with 180 additions and 33 deletions

View File

@ -92,13 +92,21 @@ public class AnalysisController extends BaseController {
}
@ApiOperation(value = "招标解析", notes = "删除项目数据")
@PostMapping("delBidData")
@PostMapping("delProData")
@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 = "招标解析", notes = "标段提交文件解析")
@PostMapping("saveBidData")
@SysLog(title = "招标解析", module = "招标解析->标段提交文件解析", businessType = OperaType.INSERT, details = "标段提交文件解析", logType = 1)
@RequiresPermissions("analysis:analysis:add")
public AjaxResult saveBidData(@RequestBody AnalysisDto.TemplateBidDto dto) {
return analysisService.saveBidData(dto);
}
@ApiOperation(value = "测试mq异步消息", notes = "测试mq异步消息")
@GetMapping("/testAsyncMq2")
public AjaxResult testAsyncMq2() {

View File

@ -14,6 +14,7 @@ import com.bonus.common.domain.file.vo.ResourceFileVo;
import com.bonus.common.domain.file.vo.SysFile;
import com.bonus.common.domain.ocr.dto.OcrRequest;
import com.bonus.common.domain.ocr.vo.WordConvertPdfResponse;
import com.bonus.common.domain.rabbitmq.dto.RabbitMqMessage;
import com.bonus.common.utils.Base64ToPdfConverter;
import com.bonus.common.utils.ValidatorsUtils;
import com.bonus.file.service.FileUploadService;
@ -120,7 +121,7 @@ public class AnalysisService {
map.put("uploadPath", uploadPath);
list.add(map);
}
AsyncManager.me().executeSendRabbitMqMessage(list);
// AsyncManager.me().executeSendRabbitMqMessage(list);
return AjaxResult.success();
}
@ -147,7 +148,7 @@ public class AnalysisService {
public AjaxResult saveData(AnalysisDto.TemplateDto dto) {
try {
// 异步任务集合
List<Map<String,Object>> asyncTaskList = new ArrayList<>();
List<RabbitMqMessage> asyncTaskList = new ArrayList<>();
// 校验数据是否合法
String validResult = validatorsUtils.valid(dto, AnalysisDto.TemplateDto.ADD.class);
if (StringUtils.isNotBlank(validResult)) {
@ -169,14 +170,15 @@ public class AnalysisService {
dto.getFiles().get(i).setBusinessId(id);
dto.getFiles().get(i).setSourceTable(TableConstants.TB_PRO_COMPOSITION);
// 添加异步任务数据
Map<String, Object> map = new HashMap<>();
RabbitMqMessage msg = new RabbitMqMessage();
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);
msg.setMessageId(taskId);
msg.setUploadPath(dto.getFiles().get(i).getFilePath());
msg.setProId(dto.getProId());
msg.setTemplateId(dto.getTemplateId());
msg.setAnalysisLabelId(dto.getAnalysisLabelId());
msg.setTaskName("OCR_PROCESS");
asyncTaskList.add(msg);
}
sourceFileService.saveResourceFile(dto.getFiles());
// 执行异步任务
@ -336,5 +338,57 @@ public class AnalysisService {
return AjaxResult.error();
}
}
/**
* 招标解析->标段提交文件解析
* @param dto
* @return AjaxResult
* @author cwchen
* @date 2025/11/29 16:17
*/
@Transactional(rollbackFor = Exception.class)
public AjaxResult saveBidData(AnalysisDto.TemplateBidDto dto) {
try {
// 异步任务集合
List<RabbitMqMessage> asyncTaskList = new ArrayList<>();
// 校验数据是否合法
String validResult = validatorsUtils.valid(dto, AnalysisDto.TemplateBidDto.ADD.class);
if (StringUtils.isNotBlank(validResult)) {
return AjaxResult.error(validResult);
}
List<ProComposition> compositions = new ArrayList<>();
for (String uploadType : dto.getUploadType()) {
ProComposition vo = createVo(dto.getBidId(), uploadType,"2");
compositions.add(vo);
}
// 保存标段的文件组成数据
analysisService.addProCompositionData(compositions);
// 添加文件
for (int i = 0; i < compositions.size(); i++) {
Long id = compositions.get(i).getId();
dto.getFiles().get(i).setBusinessId(id);
dto.getFiles().get(i).setSourceTable(TableConstants.TB_PRO_COMPOSITION);
// 添加异步任务数据
RabbitMqMessage msg = new RabbitMqMessage();
String taskId = UUID.randomUUID().toString();
msg.setMessageId(taskId);
msg.setUploadPath(dto.getFiles().get(i).getFilePath());
msg.setProId(dto.getProId());
msg.setBidId(dto.getBidId());
msg.setTaskName("OCR_PROCESS");
asyncTaskList.add(msg);
}
sourceFileService.saveResourceFile(dto.getFiles());
// 执行异步任务
AsyncManager.me().executeSendRabbitMqMessage(asyncTaskList);
return AjaxResult.success();
} catch (Exception e) {
log.error(e.toString(),e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return AjaxResult.error();
}
}
}

View File

@ -122,8 +122,8 @@
<!--获取解析标签项-->
<select id="getAnalysisLabels" resultType="com.bonus.common.domain.analysis.vo.AnalysisLabelItemOcrVo">
SELECT tali.analysis_label_item_id AS id,
tali.analysis_name AS searchKeyword,
tali.analysis_code AS targetField,
tali.analysis_name AS search_keyword,
tali.analysis_code AS target_field,
tali.parent_id AS parentId,
tali.analysis_level AS analysisLevel,
tali.analysis_sort AS analysisSort,

View File

@ -42,8 +42,12 @@ public class AnalysisDto {
/**开标结束日期*/
private String endDate;
/**项目解析模板*/
private TemplateDto templateDto;
/**标段解析模板*/
private TemplateBidDto templateBidDto;
@Data
public static class TemplateDto{
@ -119,4 +123,38 @@ public class AnalysisDto {
}
}
@Data
public static class TemplateBidDto{
/**
* 项目id
* */
@NotNull(message = "项目ID不能为空", groups = {ADD.class})
private Long proId;
@NotNull(message = "标段id不能为空", groups = {ADD.class})
private Long bidId;
/**文件组成名称*/
private String[] uploadType;
/**模板组成类型 1.项目文件 2.标段/标包文件*/
private String compositionType = "2";
/**
* 资源文件
*/
@NotEmpty(message = "文件不能为空", groups = {ADD.class})
private List<ResourceFilePo> files;
/**
* 新增条件限制
*/
public interface ADD {
}
}
}

View File

@ -23,12 +23,12 @@ public class AnalysisLabelItemOcrVo {
/**
* 解析名称
*/
private String searchKeyword;
private String search_keyword;
/**
* 解析编码
*/
private String targetField;
private String target_field;
/**
* 父节点

View File

@ -18,7 +18,12 @@ public class RabbitMqMessage implements Serializable {
/**
* 业务id
* */
private Long businessId;
private Long proId;
/**
* 标段id
* */
private Long bidId;
/**
* 标签组id

View File

@ -528,6 +528,32 @@ public class MinioUtil {
}
}
public File getFileFromMinio2(String bucketName, String objectName) throws Exception {
Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"), "minio_downloads");
Files.createDirectories(tempDir);
// 处理各种路径分隔符
String normalizedPath = objectName.replace('\\', '/');
// 获取文件名包含后缀
String safeFileName = normalizedPath.substring(normalizedPath.lastIndexOf('/') + 1);
// String fileName = "minio_" + System.currentTimeMillis() + "_" + safeFileName;
String fileName = "minio_" + "_" + safeFileName;
Path tempFilePath = tempDir.resolve(fileName);
try (InputStream stream = minioClient.getObject(
GetObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build())) {
Files.copy(stream, tempFilePath, StandardCopyOption.REPLACE_EXISTING);
return tempFilePath.toFile();
} catch (Exception e) {
Files.deleteIfExists(tempFilePath);
throw e;
}
}
/**
* 获取安全的文件名移除路径和非法字符
*/
@ -558,4 +584,5 @@ public class MinioUtil {
return fileName.isEmpty() ? "minio_file" : fileName;
}
}

View File

@ -7,6 +7,7 @@ import java.util.TimerTask;
import java.util.concurrent.*;
import com.bonus.common.domain.file.po.ResourceFileRecordPo;
import com.bonus.common.domain.rabbitmq.dto.RabbitMqMessage;
import com.bonus.common.utils.Threads;
import com.bonus.common.utils.spring.SpringUtils;
import com.bonus.file.service.SourceFileService;
@ -139,7 +140,7 @@ public class AsyncManager
* @author cwchen
* @date 2025/11/29 10:51
*/
public Future<Void> executeSendRabbitMqMessage(List<Map<String,Object>> list) {
public Future<Void> executeSendRabbitMqMessage(List<RabbitMqMessage> list) {
Callable<Void> callable = new Callable<Void>() {
@Override
public Void call() throws Exception {

View File

@ -149,7 +149,7 @@ public class AnalysisOcrService {
/**
* 创建HTTP POST请求2
*/
private HttpPost createHttpPost2(AnalysisOcrRequest analysisOcrRequest) {
/*private HttpPost createHttpPost2(AnalysisOcrRequest analysisOcrRequest) {
HttpPost httpPost = new HttpPost(extractInfoUrl);
try {
@ -165,6 +165,32 @@ public class AnalysisOcrService {
throw new RuntimeException("创建HTTP POST请求失败", e);
}
return httpPost;
}*/
private HttpPost createHttpPost2(AnalysisOcrRequest analysisOcrRequest) {
HttpPost httpPost = new HttpPost(extractInfoUrl);
try {
// 将请求对象转换为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);
// 设置请求头
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-Type", "application/json; charset=UTF-8");
} catch (Exception e) {
log.error("创建HTTP POST请求失败请求参数: {}", analysisOcrRequest, e);
throw new RuntimeException("创建HTTP POST请求失败", e);
}
return httpPost;
}
/**

View File

@ -133,7 +133,7 @@ public class RabbitMQConsumerService {
*/
private File getFileFromMinio(String uploadPath) {
try {
File file = minioUtil.getFileFromMinio(minioConfig.getBucketName(), uploadPath);
File file = minioUtil.getFileFromMinio2(minioConfig.getBucketName(), uploadPath);
if (file == null || !file.exists()) {
throw new RuntimeException("Minio文件不存在: " + uploadPath);
}

View File

@ -28,21 +28,9 @@ public class SendRabbitMqService {
* @author cwchen
* @date 2025/11/29 14:04
*/
public void sendRabbitMq(List<Map<String,Object>> list){
for (Map<String,Object> 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);
public void sendRabbitMq(List<RabbitMqMessage> list){
for (RabbitMqMessage vo : list) {
rabbitMQProducerService.sendMessageSync(vo);
}
}
}