1. 笔录图片识别功能开发

topo_dev
xueqingkun 8 months ago
parent 73f29f93fa
commit 7649a2bb59

@ -34,27 +34,61 @@ public class OCRRecordController {
}
/**
*
* @param recordId
* @return
*/
@GetMapping("/info")
public R<NoteRecordDTO> queryRecordInfo(@RequestParam("recordId") String recordId) {
NoteRecordDTO noteRecord = ocrRecordService.queryRecordInfo(recordId);
return R.ok(noteRecord);
}
/**
*
* @param recordId
* @return
*/
@GetMapping("/fileList")
public R<List<RecordFileDTO>> queryFileList(@RequestParam("recordId") String recordId) {
List<RecordFileDTO> recordFileDTOList = ocrRecordService.queryFileList(recordId);
return R.ok(recordFileDTOList);
}
/**
* OCR
* @param ocrId
* @return
*/
@GetMapping("/reOcr")
public R<Boolean> reOcr(@RequestParam("ocrId") String ocrId) {
Boolean success = ocrRecordService.reOcr(ocrId);
return R.ok(success);
}
/**
* OCR
* @param ocrTextDTOList
* @return
*/
@PostMapping("/reviseOcrText")
public R<Boolean> reviseOcrText(@RequestBody List<OCRTextDTO> ocrTextDTOList) {
Boolean success = ocrRecordService.reviseOcrText(ocrTextDTOList);
return R.ok(success);
}
/**
*
* @param recordId
* @return
*/
@GetMapping("/submitTask")
public R<Boolean> submitRecordTask(String recordId) {
Boolean success = ocrRecordService.submitRecordTask(recordId);
return R.ok(success);
}
}

@ -1,11 +1,13 @@
package com.supervision.police.dto;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.supervision.minio.domain.MinioFile;
import com.supervision.police.domain.CaseTaskRecord;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@ -32,6 +34,12 @@ public class NoteRecordDetailDTO {
*/
private String recordName;
@Schema(description = "笔录类型 0:文档 1:ocr图片识别")
private String recordType;
@Schema(description = "是否已提交 0:否 1:是")
private String submitted;
/**
*
*/
@ -155,4 +163,30 @@ public class NoteRecordDetailDTO {
}
}
}
public void setRecordTypeValue(List<RecordFileDTO> recordFileDTOS){
if (CollUtil.isEmpty(recordFileDTOS) || CollUtil.isEmpty(fileList)){
this.recordType = "0";
return;
}
for (RecordFileDTO recordFileDTO : recordFileDTOS) {
for (NoteRecordFileDTO noteRecordFileDTO : this.fileList) {
if (StrUtil.equals(recordFileDTO.getFileId(), noteRecordFileDTO.getFileId())){
this.recordType = "1";
return;
}
}
}
this.recordType = "0";
}
public void setSubmittedValue(CaseTaskRecord caseTaskRecord){
if (null == caseTaskRecord){
this.submitted = "0";
return;
}
this.submitted = StrUtil.equals(caseTaskRecord.getRecordId(), this.id) ? "1" : "0";
}
}

@ -4,6 +4,8 @@ import com.supervision.police.domain.CaseTaskRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author Administrator
* @description case_task_record()Mapper

@ -3,6 +3,8 @@ package com.supervision.police.service;
import com.supervision.police.domain.CaseTaskRecord;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @author Administrator
* @description case_task_record()Service

@ -34,4 +34,7 @@ public interface FileOcrProcessService extends IService<FileOcrProcess> {
List<RecordFileDTO> queryFileList(List<String> fileIdList);
List<RecordFileDTO> queryListByRecordId(String recordId);
}

@ -20,4 +20,6 @@ public interface OCRRecordService {
Boolean reviseOcrText(List<OCRTextDTO> ocrTextDTOList);
Boolean reOcr(String ocrId);
Boolean submitRecordTask(String recordId);
}

@ -8,4 +8,14 @@ import java.util.List;
public interface RecordSplitProcessService {
void process(List<ModelRecordType> allTypeList, List<NoteRecordSplit> splitList);
/**
*
*
* @param caseId
* @param recordId
* @return , true, , false
*/
boolean recordProcessTaskStatusCheck(String caseId, String recordId, Integer splitSize);
}

@ -1,17 +1,20 @@
package com.supervision.police.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.supervision.minio.domain.MinioFile;
import com.supervision.minio.service.MinioService;
import com.supervision.police.domain.FileOcrProcess;
import com.supervision.police.domain.NoteRecord;
import com.supervision.police.dto.OCRReqDTO;
import com.supervision.police.dto.OCRResDTO;
import com.supervision.police.dto.RecordFileDTO;
import com.supervision.police.service.FileOcrProcessService;
import com.supervision.police.mapper.FileOcrProcessMapper;
import com.supervision.police.service.NoteRecordService;
import com.supervision.police.service.OCRService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -21,7 +24,9 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@ -42,6 +47,8 @@ public class FileOcrProcessServiceImpl extends ServiceImpl<FileOcrProcessMapper,
private final MinioService minioService;
private final NoteRecordService noteRecordService;
@Override
@Transactional(transactionManager = "dataSourceTransactionManager",rollbackFor = Exception.class)
public List<FileOcrProcess> submitOCR(List<String> fileIdList) {
@ -138,6 +145,18 @@ public class FileOcrProcessServiceImpl extends ServiceImpl<FileOcrProcessMapper,
return super.baseMapper.queryFileList(fileIdList);
}
@Override
public List<RecordFileDTO> queryListByRecordId(String recordId) {
if (StrUtil.isEmpty(recordId)){
return new ArrayList<>(1);
}
NoteRecord noteRecord = noteRecordService.getById(recordId);
if (Objects.isNull(noteRecord) || StrUtil.isEmpty(noteRecord.getFileIds())){
return new ArrayList<>(1);
}
return queryFileList(Arrays.stream(noteRecord.getFileIds().split(",")).toList());
}
private List<OCRReqDTO> buildOCRReqDTO(List<String> fileIdList){
List<MinioFile> minioFiles = minioService.listMinioFile(fileIdList);

@ -19,6 +19,7 @@ import com.supervision.neo4j.service.Neo4jService;
import com.supervision.police.domain.*;
import com.supervision.police.dto.NoteRecordDTO;
import com.supervision.police.dto.NoteRecordFileDTO;
import com.supervision.police.dto.RecordFileDTO;
import com.supervision.police.vo.NoteRecordReqVO;
import com.supervision.police.dto.NoteRecordDetailDTO;
import com.supervision.police.mapper.NoteRecordSplitMapper;
@ -65,14 +66,14 @@ public class NoteRecordSplitServiceImpl extends ServiceImpl<NoteRecordSplitMappe
private final Neo4jService neo4jService;
private final LangChainChatService langChainChatService;
private final ModelCaseService modelCaseService;
private final ModelAtomicResultService modelAtomicResultService;
private final ComDictionaryService comDictionaryService;
private final FileOcrProcessService fileOcrProcessService;
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
@ -92,7 +93,7 @@ public class NoteRecordSplitServiceImpl extends ServiceImpl<NoteRecordSplitMappe
List<NoteRecordSplit> allNoteRecordSplits = records.getFileIdList().stream()
.flatMap(fileId -> batchSaveRecordSplit(record, fileId).stream()).toList();
boolean taskStatus = recordProcessTaskStatusCheck(record.getCaseId(), record.getId(), allNoteRecordSplits.size());
boolean taskStatus = recordSplitProcessService.recordProcessTaskStatusCheck(record.getCaseId(), record.getId(), allNoteRecordSplits.size());
// 如果校验结果为true,则说明需要进行分类以及三元组操作
if (taskStatus) {
// 对笔录进行分类,并对笔录进行提取三元组
@ -103,86 +104,6 @@ public class NoteRecordSplitServiceImpl extends ServiceImpl<NoteRecordSplitMappe
return record.getId();
}
/**
*
*
* @param caseId
* @param recordId
* @return , true, , false
*/
private boolean recordProcessTaskStatusCheck(String caseId, String recordId, Integer splitSize) {
// 首先查询是否存在任务,如果不存在,就新建
Optional<CaseTaskRecord> caseTaskRecordOpt = caseTaskRecordService.lambdaQuery()
.eq(CaseTaskRecord::getCaseId, caseId).eq(CaseTaskRecord::getRecordId, recordId).oneOpt();
if (caseTaskRecordOpt.isEmpty()) {
log.info("recordProcessTaskStatusCheck:recordId:{}未查询到任务记录, 新建任务记录...",recordId);
CaseTaskRecord newCaseTaskRecord = new CaseTaskRecord();
newCaseTaskRecord.setCaseId(caseId);
newCaseTaskRecord.setRecordId(recordId);
newCaseTaskRecord.setStatus(splitSize > 0 ? 1 : 2);
newCaseTaskRecord.setSubmitTime(LocalDateTime.now());
caseTaskRecordService.save(newCaseTaskRecord);
return newCaseTaskRecord.getStatus().equals(1);
}
if (0 == splitSize) {
// 如果笔录对为0,就直接不需要拆分,直接认为任务成功
CaseTaskRecord caseTaskRecord = caseTaskRecordOpt.get();
caseTaskRecord.setStatus(2);
caseTaskRecord.setSubmitTime(LocalDateTime.now());
caseTaskRecordService.saveOrUpdate(caseTaskRecord);
return false;
}
if (caseTaskRecordOpt.get().getStatus() == 2) {
return false;
}
// 如果存在,则校验时间是否已经超过1天,如果超过了1天还没有执行完毕,就重新提交这个任务
CaseTaskRecord caseTaskRecord = caseTaskRecordOpt.get();
// 如果未执行,则提交执行
if (caseTaskRecordOpt.get().getStatus() == 0) {
caseTaskRecord.setStatus(1);
caseTaskRecord.setSubmitTime(LocalDateTime.now());
caseTaskRecord.setTaskCount(0);
caseTaskRecord.setFinishCount(0);
caseTaskRecordService.updateById(caseTaskRecord);
return true;
}
if (caseTaskRecordOpt.get().getStatus() == 1 && LocalDateTime.now().isAfter(caseTaskRecord.getSubmitTime().plusDays(1))) {
// 如果已经超过1天,则重新提交任务
caseTaskRecord.setStatus(1);
caseTaskRecord.setTaskCount(0);
caseTaskRecord.setFinishCount(0);
caseTaskRecord.setSubmitTime(LocalDateTime.now());
caseTaskRecordService.updateById(caseTaskRecord);
return true;
}
if (caseTaskRecordOpt.get().getStatus() == 3) {
// 如果执行失败,就重新执行
caseTaskRecord.setStatus(1);
caseTaskRecord.setTaskCount(0);
caseTaskRecord.setFinishCount(0);
caseTaskRecord.setSubmitTime(LocalDateTime.now());
caseTaskRecordService.updateById(caseTaskRecord);
return true;
}
// 如果都不是就在跑一次
caseTaskRecord.setStatus(1);
caseTaskRecord.setTaskCount(0);
caseTaskRecord.setFinishCount(0);
caseTaskRecord.setSubmitTime(LocalDateTime.now());
caseTaskRecordService.updateById(caseTaskRecord);
return true;
}
@Override
public Map<String, Object> queryRecords(NoteRecord noteRecords, Integer page, Integer size) {
@ -372,13 +293,15 @@ public class NoteRecordSplitServiceImpl extends ServiceImpl<NoteRecordSplitMappe
List<CaseTaskRecord> taskList = caseTaskRecordService.lambdaQuery().eq(CaseTaskRecord::getCaseId, noteRecord.getCaseId()).list();
Map<String, CaseTaskRecord> taskRecordMap = taskList.stream().collect(Collectors.toMap(CaseTaskRecord::getRecordId, Function.identity(), (k1, k2) -> k1));
List<RecordFileDTO> recordFileDTOS = fileOcrProcessService.queryFileList(fileIdList);
setRecordDetailSerialNumber(noteRecordDetailDTOList);
for (NoteRecordDetailDTO recordDetailDTO : noteRecordDetailDTOList) {
// 获取文件的文件名称
Set<String> fileNameSet = recordDetailDTO.getFileList().stream().map(NoteRecordFileDTO::getFileName).collect(Collectors.toSet());
recordDetailDTO.setConfessionMaterial(CollUtil.join(fileNameSet, ";"));
recordDetailDTO.setPercentageValue(taskRecordMap.get(recordDetailDTO.getId()));
recordDetailDTO.setRecordTypeValue(recordFileDTOS);
recordDetailDTO.setSubmittedValue(taskRecordMap.get(recordDetailDTO.getId()));
}
noteRecordDetailDTOList.sort(Comparator.comparing(NoteRecordDetailDTO::getSerialNumber));

@ -3,24 +3,27 @@ package com.supervision.police.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.supervision.demo.dto.QARecordNodeDTO;
import com.supervision.minio.domain.MinioFile;
import com.supervision.minio.service.MinioService;
import com.supervision.police.domain.FileOcrProcess;
import com.supervision.police.domain.ModelRecordType;
import com.supervision.police.domain.NoteRecord;
import com.supervision.police.domain.NoteRecordSplit;
import com.supervision.police.dto.NoteRecordDTO;
import com.supervision.police.dto.OCRReqDTO;
import com.supervision.police.dto.OCRTextDTO;
import com.supervision.police.dto.RecordFileDTO;
import com.supervision.police.service.*;
import com.supervision.police.vo.NoteRecordReqVO;
import com.supervision.utils.RecordRegexUtil;
import com.supervision.utils.WordReadUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@ -31,6 +34,12 @@ public class OCRRecordServiceImpl implements OCRRecordService {
private final FileOcrProcessService fileOcrProcessService;
private final NoteRecordService noteRecordService;
private final RecordSplitProcessService recordSplitProcessService;
private final NoteRecordSplitService noteRecordSplitService;
private final ModelRecordTypeService modelRecordTypeService;
@Override
public String saveRecord(NoteRecordReqVO noteRecordReqVO) {
@ -108,6 +117,54 @@ public class OCRRecordServiceImpl implements OCRRecordService {
return null;
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public Boolean submitRecordTask(String recordId) {
Assert.notEmpty(recordId, "recordId不能为空");
NoteRecord noteRecord = noteRecordService.getById(recordId);
if (Objects.isNull(noteRecord) || StrUtil.isEmpty(noteRecord.getFileIds())){
log.info("submitRecordTask:笔录:{}对应的笔录文件为空...",recordId);
return false;
}
List<String> fileIdList = Arrays.stream(noteRecord.getFileIds().split(",")).toList();
List<RecordFileDTO> recordFileDTOS = fileOcrProcessService.queryFileList(fileIdList);
if (CollUtil.isEmpty(recordFileDTOS)){
log.info("submitRecordTask:笔录:{}对应的笔录文件为空...",recordId);
return false;
}
List<NoteRecordSplit> allNoteRecordSplits = recordFileDTOS.stream()
.flatMap(recordFileDTO -> batchSaveRecordSplit(noteRecord, recordFileDTO).stream()).toList();
boolean taskStatus = recordSplitProcessService.recordProcessTaskStatusCheck(noteRecord.getCaseId(), noteRecord.getId(), allNoteRecordSplits.size());
// 如果校验结果为true,则说明需要进行分类以及三元组操作
if (taskStatus) {
// 对笔录进行分类,并对笔录进行提取三元组
List<ModelRecordType> allTypeList = modelRecordTypeService.lambdaQuery().list();
recordSplitProcessService.process(allTypeList, allNoteRecordSplits);
}
return true;
}
public List<NoteRecordSplit> batchSaveRecordSplit(NoteRecord noteRecord, RecordFileDTO recordFileDTO) {
String ocrText = recordFileDTO.getOcrText();
String reviseText = recordFileDTO.getReviseText();
List<QARecordNodeDTO> qaList = RecordRegexUtil.recordRegex(
StrUtil.isEmpty(reviseText) ? ocrText : reviseText, noteRecord.getName());
log.info("文件:{}拆分问答对:{}",recordFileDTO.getFileName(), qaList.size());
List<NoteRecordSplit> splitList = new ArrayList<>();
for (QARecordNodeDTO qa : qaList) {
splitList.add(
noteRecordSplitService.saveRecordSplit(noteRecord,
recordFileDTO.getFileName(), qa.getQuestion(), qa.getAnswer())
);
}
return splitList;
}
private List<RecordFileDTO> sortByIdOrder(List<String> fileIdList,List<RecordFileDTO> recordFileDTOList){
if (CollUtil.size(fileIdList) < 2 || CollUtil.size(recordFileDTOList) < 2) {

@ -1,23 +1,104 @@
package com.supervision.police.service.impl;
import com.supervision.police.domain.CaseTaskRecord;
import com.supervision.police.domain.ModelRecordType;
import com.supervision.police.domain.NoteRecordSplit;
import com.supervision.police.service.CaseTaskRecordService;
import com.supervision.police.service.RecordSplitProcessService;
import com.supervision.police.service.RecordSplitClassifyService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
@Slf4j
@Service
@RequiredArgsConstructor
public class RecordSplitProcessServiceImpl implements RecordSplitProcessService {
private final RecordSplitClassifyService recordSplitClassifyService;
private final CaseTaskRecordService caseTaskRecordService;
@Override
public void process(List<ModelRecordType> allTypeList, List<NoteRecordSplit> splitList) {
// 通过异步的形式提交分类
recordSplitClassifyService.classify(allTypeList,splitList);
}
public boolean recordProcessTaskStatusCheck(String caseId, String recordId, Integer splitSize) {
// 首先查询是否存在任务,如果不存在,就新建
Optional<CaseTaskRecord> caseTaskRecordOpt = caseTaskRecordService.lambdaQuery()
.eq(CaseTaskRecord::getCaseId, caseId).eq(CaseTaskRecord::getRecordId, recordId).oneOpt();
if (caseTaskRecordOpt.isEmpty()) {
log.info("recordProcessTaskStatusCheck:recordId:{}未查询到任务记录, 新建任务记录...",recordId);
CaseTaskRecord newCaseTaskRecord = new CaseTaskRecord();
newCaseTaskRecord.setCaseId(caseId);
newCaseTaskRecord.setRecordId(recordId);
newCaseTaskRecord.setStatus(splitSize > 0 ? 1 : 2);
newCaseTaskRecord.setSubmitTime(LocalDateTime.now());
caseTaskRecordService.save(newCaseTaskRecord);
return newCaseTaskRecord.getStatus().equals(1);
}
if (0 == splitSize) {
// 如果笔录对为0,就直接不需要拆分,直接认为任务成功
CaseTaskRecord caseTaskRecord = caseTaskRecordOpt.get();
caseTaskRecord.setStatus(2);
caseTaskRecord.setSubmitTime(LocalDateTime.now());
caseTaskRecordService.saveOrUpdate(caseTaskRecord);
return false;
}
if (caseTaskRecordOpt.get().getStatus() == 2) {
return false;
}
// 如果存在,则校验时间是否已经超过1天,如果超过了1天还没有执行完毕,就重新提交这个任务
CaseTaskRecord caseTaskRecord = caseTaskRecordOpt.get();
// 如果未执行,则提交执行
if (caseTaskRecordOpt.get().getStatus() == 0) {
caseTaskRecord.setStatus(1);
caseTaskRecord.setSubmitTime(LocalDateTime.now());
caseTaskRecord.setTaskCount(0);
caseTaskRecord.setFinishCount(0);
caseTaskRecordService.updateById(caseTaskRecord);
return true;
}
if (caseTaskRecordOpt.get().getStatus() == 1 && LocalDateTime.now().isAfter(caseTaskRecord.getSubmitTime().plusDays(1))) {
// 如果已经超过1天,则重新提交任务
caseTaskRecord.setStatus(1);
caseTaskRecord.setTaskCount(0);
caseTaskRecord.setFinishCount(0);
caseTaskRecord.setSubmitTime(LocalDateTime.now());
caseTaskRecordService.updateById(caseTaskRecord);
return true;
}
if (caseTaskRecordOpt.get().getStatus() == 3) {
// 如果执行失败,就重新执行
caseTaskRecord.setStatus(1);
caseTaskRecord.setTaskCount(0);
caseTaskRecord.setFinishCount(0);
caseTaskRecord.setSubmitTime(LocalDateTime.now());
caseTaskRecordService.updateById(caseTaskRecord);
return true;
}
// 如果都不是就在跑一次
caseTaskRecord.setStatus(1);
caseTaskRecord.setTaskCount(0);
caseTaskRecord.setFinishCount(0);
caseTaskRecord.setSubmitTime(LocalDateTime.now());
caseTaskRecordService.updateById(caseTaskRecord);
return true;
}
}

Loading…
Cancel
Save