招标解析算法服务
This commit is contained in:
parent
ecfbcf43bc
commit
36e99617e3
|
|
@ -92,13 +92,21 @@ public class AnalysisController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "招标解析", notes = "删除项目数据")
|
@ApiOperation(value = "招标解析", notes = "删除项目数据")
|
||||||
@PostMapping("delBidData")
|
@PostMapping("delProData")
|
||||||
@SysLog(title = "招标解析", module = "招标解析->删除项目数据", businessType = OperaType.DELETE, details = "删除项目数据", logType = 1)
|
@SysLog(title = "招标解析", module = "招标解析->删除项目数据", businessType = OperaType.DELETE, details = "删除项目数据", logType = 1)
|
||||||
@RequiresPermissions("analysis:analysis:del")
|
@RequiresPermissions("analysis:analysis:del")
|
||||||
public AjaxResult delProData(@RequestBody AnalysisDto.TemplateDto dto) {
|
public AjaxResult delProData(@RequestBody AnalysisDto.TemplateDto dto) {
|
||||||
return analysisService.delProData(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异步消息")
|
@ApiOperation(value = "测试mq异步消息", notes = "测试mq异步消息")
|
||||||
@GetMapping("/testAsyncMq2")
|
@GetMapping("/testAsyncMq2")
|
||||||
public AjaxResult testAsyncMq2() {
|
public AjaxResult testAsyncMq2() {
|
||||||
|
|
|
||||||
|
|
@ -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.file.vo.SysFile;
|
||||||
import com.bonus.common.domain.ocr.dto.OcrRequest;
|
import com.bonus.common.domain.ocr.dto.OcrRequest;
|
||||||
import com.bonus.common.domain.ocr.vo.WordConvertPdfResponse;
|
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.Base64ToPdfConverter;
|
||||||
import com.bonus.common.utils.ValidatorsUtils;
|
import com.bonus.common.utils.ValidatorsUtils;
|
||||||
import com.bonus.file.service.FileUploadService;
|
import com.bonus.file.service.FileUploadService;
|
||||||
|
|
@ -120,7 +121,7 @@ public class AnalysisService {
|
||||||
map.put("uploadPath", uploadPath);
|
map.put("uploadPath", uploadPath);
|
||||||
list.add(map);
|
list.add(map);
|
||||||
}
|
}
|
||||||
AsyncManager.me().executeSendRabbitMqMessage(list);
|
// AsyncManager.me().executeSendRabbitMqMessage(list);
|
||||||
return AjaxResult.success();
|
return AjaxResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,7 +148,7 @@ public class AnalysisService {
|
||||||
public AjaxResult saveData(AnalysisDto.TemplateDto dto) {
|
public AjaxResult saveData(AnalysisDto.TemplateDto dto) {
|
||||||
try {
|
try {
|
||||||
// 异步任务集合
|
// 异步任务集合
|
||||||
List<Map<String,Object>> asyncTaskList = new ArrayList<>();
|
List<RabbitMqMessage> asyncTaskList = new ArrayList<>();
|
||||||
// 校验数据是否合法
|
// 校验数据是否合法
|
||||||
String validResult = validatorsUtils.valid(dto, AnalysisDto.TemplateDto.ADD.class);
|
String validResult = validatorsUtils.valid(dto, AnalysisDto.TemplateDto.ADD.class);
|
||||||
if (StringUtils.isNotBlank(validResult)) {
|
if (StringUtils.isNotBlank(validResult)) {
|
||||||
|
|
@ -169,14 +170,15 @@ public class AnalysisService {
|
||||||
dto.getFiles().get(i).setBusinessId(id);
|
dto.getFiles().get(i).setBusinessId(id);
|
||||||
dto.getFiles().get(i).setSourceTable(TableConstants.TB_PRO_COMPOSITION);
|
dto.getFiles().get(i).setSourceTable(TableConstants.TB_PRO_COMPOSITION);
|
||||||
// 添加异步任务数据
|
// 添加异步任务数据
|
||||||
Map<String, Object> map = new HashMap<>();
|
RabbitMqMessage msg = new RabbitMqMessage();
|
||||||
String taskId = UUID.randomUUID().toString();
|
String taskId = UUID.randomUUID().toString();
|
||||||
map.put("taskId", taskId);
|
msg.setMessageId(taskId);
|
||||||
map.put("uploadPath", dto.getFiles().get(i).getFilePath());
|
msg.setUploadPath(dto.getFiles().get(i).getFilePath());
|
||||||
map.put("businessId", dto.getProId());
|
msg.setProId(dto.getProId());
|
||||||
map.put("templateId",dto.getTemplateId());
|
msg.setTemplateId(dto.getTemplateId());
|
||||||
map.put("analysisLabelId",dto.getAnalysisLabelId());
|
msg.setAnalysisLabelId(dto.getAnalysisLabelId());
|
||||||
asyncTaskList.add(map);
|
msg.setTaskName("OCR_PROCESS");
|
||||||
|
asyncTaskList.add(msg);
|
||||||
}
|
}
|
||||||
sourceFileService.saveResourceFile(dto.getFiles());
|
sourceFileService.saveResourceFile(dto.getFiles());
|
||||||
// 执行异步任务
|
// 执行异步任务
|
||||||
|
|
@ -336,5 +338,57 @@ public class AnalysisService {
|
||||||
return AjaxResult.error();
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,8 +122,8 @@
|
||||||
<!--获取解析标签项-->
|
<!--获取解析标签项-->
|
||||||
<select id="getAnalysisLabels" resultType="com.bonus.common.domain.analysis.vo.AnalysisLabelItemOcrVo">
|
<select id="getAnalysisLabels" resultType="com.bonus.common.domain.analysis.vo.AnalysisLabelItemOcrVo">
|
||||||
SELECT tali.analysis_label_item_id AS id,
|
SELECT tali.analysis_label_item_id AS id,
|
||||||
tali.analysis_name AS searchKeyword,
|
tali.analysis_name AS search_keyword,
|
||||||
tali.analysis_code AS targetField,
|
tali.analysis_code AS target_field,
|
||||||
tali.parent_id AS parentId,
|
tali.parent_id AS parentId,
|
||||||
tali.analysis_level AS analysisLevel,
|
tali.analysis_level AS analysisLevel,
|
||||||
tali.analysis_sort AS analysisSort,
|
tali.analysis_sort AS analysisSort,
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,12 @@ public class AnalysisDto {
|
||||||
/**开标结束日期*/
|
/**开标结束日期*/
|
||||||
private String endDate;
|
private String endDate;
|
||||||
|
|
||||||
|
/**项目解析模板*/
|
||||||
private TemplateDto templateDto;
|
private TemplateDto templateDto;
|
||||||
|
|
||||||
|
/**标段解析模板*/
|
||||||
|
private TemplateBidDto templateBidDto;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class TemplateDto{
|
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 {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,12 @@ public class AnalysisLabelItemOcrVo {
|
||||||
/**
|
/**
|
||||||
* 解析名称
|
* 解析名称
|
||||||
*/
|
*/
|
||||||
private String searchKeyword;
|
private String search_keyword;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析编码
|
* 解析编码
|
||||||
*/
|
*/
|
||||||
private String targetField;
|
private String target_field;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 父节点
|
* 父节点
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,12 @@ public class RabbitMqMessage implements Serializable {
|
||||||
/**
|
/**
|
||||||
* 业务id
|
* 业务id
|
||||||
* */
|
* */
|
||||||
private Long businessId;
|
private Long proId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标段id
|
||||||
|
* */
|
||||||
|
private Long bidId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标签组id
|
* 标签组id
|
||||||
|
|
|
||||||
|
|
@ -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;
|
return fileName.isEmpty() ? "minio_file" : fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import java.util.TimerTask;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
import com.bonus.common.domain.file.po.ResourceFileRecordPo;
|
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.Threads;
|
||||||
import com.bonus.common.utils.spring.SpringUtils;
|
import com.bonus.common.utils.spring.SpringUtils;
|
||||||
import com.bonus.file.service.SourceFileService;
|
import com.bonus.file.service.SourceFileService;
|
||||||
|
|
@ -139,7 +140,7 @@ public class AsyncManager
|
||||||
* @author cwchen
|
* @author cwchen
|
||||||
* @date 2025/11/29 10:51
|
* @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>() {
|
Callable<Void> callable = new Callable<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void call() throws Exception {
|
public Void call() throws Exception {
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ public class AnalysisOcrService {
|
||||||
/**
|
/**
|
||||||
* 创建HTTP POST请求2
|
* 创建HTTP POST请求2
|
||||||
*/
|
*/
|
||||||
private HttpPost createHttpPost2(AnalysisOcrRequest analysisOcrRequest) {
|
/*private HttpPost createHttpPost2(AnalysisOcrRequest analysisOcrRequest) {
|
||||||
HttpPost httpPost = new HttpPost(extractInfoUrl);
|
HttpPost httpPost = new HttpPost(extractInfoUrl);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -165,6 +165,32 @@ public class AnalysisOcrService {
|
||||||
throw new RuntimeException("创建HTTP POST请求失败", e);
|
throw new RuntimeException("创建HTTP POST请求失败", e);
|
||||||
}
|
}
|
||||||
return httpPost;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ public class RabbitMQConsumerService {
|
||||||
*/
|
*/
|
||||||
private File getFileFromMinio(String uploadPath) {
|
private File getFileFromMinio(String uploadPath) {
|
||||||
try {
|
try {
|
||||||
File file = minioUtil.getFileFromMinio(minioConfig.getBucketName(), uploadPath);
|
File file = minioUtil.getFileFromMinio2(minioConfig.getBucketName(), uploadPath);
|
||||||
if (file == null || !file.exists()) {
|
if (file == null || !file.exists()) {
|
||||||
throw new RuntimeException("Minio文件不存在: " + uploadPath);
|
throw new RuntimeException("Minio文件不存在: " + uploadPath);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,21 +28,9 @@ public class SendRabbitMqService {
|
||||||
* @author cwchen
|
* @author cwchen
|
||||||
* @date 2025/11/29 14:04
|
* @date 2025/11/29 14:04
|
||||||
*/
|
*/
|
||||||
public void sendRabbitMq(List<Map<String,Object>> list){
|
public void sendRabbitMq(List<RabbitMqMessage> list){
|
||||||
for (Map<String,Object> map : list) {
|
for (RabbitMqMessage vo : list) {
|
||||||
String taskId = map.get("taskId").toString();
|
rabbitMQProducerService.sendMessageSync(vo);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue