1. 添加证据ocr识别功能
parent
cc9c24a92f
commit
2879916e97
@ -0,0 +1,51 @@
|
||||
package com.supervision.constant;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
public enum EvidencePropertyName {
|
||||
|
||||
TITLE("title", "标题", "String");
|
||||
|
||||
private final String name;
|
||||
|
||||
private final String description;
|
||||
|
||||
private final String type;
|
||||
|
||||
EvidencePropertyName(String name, String description, String type) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static List<EvidencePropertyName> getByNames(Map<String,String> propertyMap){
|
||||
ArrayList<EvidencePropertyName> evidencePropertyNames = new ArrayList<>();
|
||||
if (CollUtil.isEmpty(propertyMap)){
|
||||
return evidencePropertyNames;
|
||||
}
|
||||
|
||||
for (String key : propertyMap.keySet()) {
|
||||
EvidencePropertyName evidencePropertyName = getByName(key);
|
||||
if (evidencePropertyName != null){
|
||||
evidencePropertyNames.add(evidencePropertyName);
|
||||
}
|
||||
}
|
||||
|
||||
return evidencePropertyNames;
|
||||
}
|
||||
|
||||
public static EvidencePropertyName getByName(String name){
|
||||
for (EvidencePropertyName value : values()) {
|
||||
if (value.getName().equals(name)){
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.supervision.police.controller;
|
||||
|
||||
import com.supervision.common.domain.R;
|
||||
import com.supervision.police.dto.EvidenceFileOCRDTO;
|
||||
import com.supervision.police.service.OCREvidenceService;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ocr证据接口
|
||||
*/
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequestMapping("/ocr/evidence")
|
||||
@ApiOperation(value = "OCR笔录接口")
|
||||
@RequiredArgsConstructor
|
||||
public class OCREvidenceController {
|
||||
|
||||
private final OCREvidenceService ocrEvidenceService;
|
||||
@GetMapping("/submitOrcTask")
|
||||
public R<Boolean> submitOrcTask(@RequestParam("fileId") String fileId) {
|
||||
Boolean success = ocrEvidenceService.submitOrcTask(fileId);
|
||||
return R.ok(success);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/preview")
|
||||
public R<List<EvidenceFileOCRDTO>> preview(@RequestBody List<String> fileIdList) {
|
||||
List<EvidenceFileOCRDTO> evidenceFileOCRDTOList = ocrEvidenceService.previewEvidence(fileIdList);
|
||||
return R.ok(evidenceFileOCRDTOList);
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package com.supervision.police.dto;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class EvidenceFileOCRDTO {
|
||||
|
||||
@Schema(description = "案件证据id")
|
||||
private String evidenceId;
|
||||
|
||||
@Schema(description = "案件id")
|
||||
private String caseId;
|
||||
|
||||
@Schema(description = "案件证据名称")
|
||||
private String evidenceName;
|
||||
|
||||
@Schema(description = "案件证据类型")
|
||||
private String evidenceType;
|
||||
|
||||
@Schema(description = "文件id")
|
||||
private String fileId;
|
||||
|
||||
@Schema(description = "文件预览图id")
|
||||
private String drawImgId;
|
||||
|
||||
@Schema(description = "文件识别内容")
|
||||
private String ocrText;
|
||||
|
||||
@Schema(description = "文件属性")
|
||||
private Map<String,String> property= new HashMap<>();
|
||||
|
||||
public EvidenceFileOCRDTO() {
|
||||
}
|
||||
|
||||
public EvidenceFileOCRDTO(List<OCREvidencePropertyDTO> properties) {
|
||||
if (CollUtil.isEmpty(properties)){
|
||||
return;
|
||||
}
|
||||
OCREvidencePropertyDTO first = CollUtil.getFirst(properties);
|
||||
this.evidenceId = first.getEvidenceId();
|
||||
this.fileId = first.getFileId();
|
||||
this.drawImgId = first.getDrawImgId();
|
||||
properties.forEach(propertyDTO ->
|
||||
this.property.put(propertyDTO.getPropertyName(),propertyDTO.getPropertyValue()));
|
||||
}
|
||||
|
||||
public CaseEvidenceDTO toCaseEvidenceDTO(){
|
||||
CaseEvidenceDTO caseEvidenceDTO = new CaseEvidenceDTO();
|
||||
caseEvidenceDTO.setCaseId(this.caseId);
|
||||
caseEvidenceDTO.setEvidenceName(this.evidenceName);
|
||||
caseEvidenceDTO.setEvidenceType(this.evidenceType);
|
||||
caseEvidenceDTO.setId(this.evidenceId);
|
||||
return caseEvidenceDTO;
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package com.supervision.police.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class OCREvidencePropertyDTO {
|
||||
|
||||
@Schema(description = "案件证据id")
|
||||
private String evidenceId;
|
||||
|
||||
@Schema(description = "文件id")
|
||||
private String fileId;
|
||||
|
||||
@Schema(description = "属性名称")
|
||||
private String propertyName;
|
||||
|
||||
@Schema(description = "属性值")
|
||||
private String propertyValue;
|
||||
|
||||
@Schema(description = "预览图id")
|
||||
private String drawImgId;
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.supervision.police.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RetrieveReqDTO {
|
||||
|
||||
/**
|
||||
* 要从中提取标题的文本
|
||||
*/
|
||||
private String text;
|
||||
|
||||
public RetrieveReqDTO() {
|
||||
}
|
||||
|
||||
public RetrieveReqDTO(String text) {
|
||||
this.text = text;
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.supervision.police.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class RetrieveResDTO {
|
||||
|
||||
@Schema(description = "标题")
|
||||
private String title;
|
||||
|
||||
@Schema(description = "状态码 0:成功 2:失败")
|
||||
private int status;
|
||||
|
||||
@Schema(description = "错误信息")
|
||||
private String error_msg;
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.supervision.police.mapper;
|
||||
|
||||
import com.supervision.police.domain.EvidenceProperty;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @description 针对表【evidence_property】的数据库操作Mapper
|
||||
* @createDate 2024-09-04 11:20:37
|
||||
* @Entity com.supervision.police.domain.EvidenceProperty
|
||||
*/
|
||||
public interface EvidencePropertyMapper extends BaseMapper<EvidenceProperty> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,22 @@
|
||||
package com.supervision.police.mapper;
|
||||
|
||||
import com.supervision.police.domain.FileEvidenceProperty;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.supervision.police.dto.OCREvidencePropertyDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @description 针对表【file_evidence_property】的数据库操作Mapper
|
||||
* @createDate 2024-09-04 15:10:13
|
||||
* @Entity com.supervision.police.domain.EvidenceProperty
|
||||
*/
|
||||
public interface FileEvidencePropertyMapper extends BaseMapper<FileEvidenceProperty> {
|
||||
|
||||
List<OCREvidencePropertyDTO> listPrewByFileIdList(List<String> fileIdList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,13 +0,0 @@
|
||||
package com.supervision.police.service;
|
||||
|
||||
import com.supervision.police.domain.EvidenceProperty;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @description 针对表【evidence_property】的数据库操作Service
|
||||
* @createDate 2024-09-04 11:20:37
|
||||
*/
|
||||
public interface EvidencePropertyService extends IService<EvidenceProperty> {
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.supervision.police.service;
|
||||
|
||||
import com.supervision.police.domain.FileEvidenceProperty;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.supervision.police.dto.OCREvidencePropertyDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @description 针对表【file_evidence_property】的数据库操作Service
|
||||
* @createDate 2024-09-04 15:10:13
|
||||
*/
|
||||
public interface FileEvidencePropertyService extends IService<FileEvidenceProperty> {
|
||||
|
||||
List<OCREvidencePropertyDTO> listPrewByFileIdList(List<String> fileIdList);
|
||||
|
||||
void removeByEvidenceAndFileId(String evidenceId, String fileId);
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package com.supervision.police.service;
|
||||
|
||||
import com.supervision.police.domain.FileEvidenceProperty;
|
||||
import com.supervision.police.dto.EvidenceFileOCRDTO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface OCREvidenceService {
|
||||
Boolean submitOrcTask(String fileId);
|
||||
|
||||
List<FileEvidenceProperty> doOrcTask(String evidenceId,String fileId);
|
||||
|
||||
void asyncDoOrcTask(String evidenceId,String fileId);
|
||||
|
||||
|
||||
/**
|
||||
* 保存证据属性统一入口
|
||||
* @param evidenceId 证据id
|
||||
* @param fileId 文件id
|
||||
* @param propertyMap 属性map
|
||||
* @return
|
||||
*/
|
||||
List<FileEvidenceProperty> saveEvidenceProperty(String evidenceId, String fileId, Map<String,String> propertyMap);
|
||||
|
||||
List<EvidenceFileOCRDTO> previewEvidence(List<String> fileIdList);
|
||||
|
||||
String saveEvidence(EvidenceFileOCRDTO evidenceFileOCRDTO);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package com.supervision.police.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.supervision.police.domain.EvidenceProperty;
|
||||
import com.supervision.police.service.EvidencePropertyService;
|
||||
import com.supervision.police.mapper.EvidencePropertyMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @description 针对表【evidence_property】的数据库操作Service实现
|
||||
* @createDate 2024-09-04 11:20:37
|
||||
*/
|
||||
@Service
|
||||
public class EvidencePropertyServiceImpl extends ServiceImpl<EvidencePropertyMapper, EvidenceProperty>
|
||||
implements EvidencePropertyService{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,40 @@
|
||||
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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.supervision.police.domain.FileEvidenceProperty;
|
||||
import com.supervision.police.dto.OCREvidencePropertyDTO;
|
||||
import com.supervision.police.service.FileEvidencePropertyService;
|
||||
import com.supervision.police.mapper.FileEvidencePropertyMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Administrator
|
||||
* @description 针对表【file_evidence_property】的数据库操作Service实现
|
||||
* @createDate 2024-09-04 15:10:13
|
||||
*/
|
||||
@Service
|
||||
public class FileEvidencePropertyServiceImpl extends ServiceImpl<FileEvidencePropertyMapper, FileEvidenceProperty>
|
||||
implements FileEvidencePropertyService {
|
||||
|
||||
@Override
|
||||
public List<OCREvidencePropertyDTO> listPrewByFileIdList(List<String> fileIdList) {
|
||||
return super.getBaseMapper().listPrewByFileIdList(fileIdList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeByEvidenceAndFileId(String evidenceId, String fileId) {
|
||||
Assert.isFalse(StrUtil.isAllEmpty(evidenceId,fileId), "案件id和文件id不能全为空");
|
||||
|
||||
super.lambdaUpdate().eq(StrUtil.isNotEmpty(evidenceId),FileEvidenceProperty::getEvidenceId, evidenceId)
|
||||
.eq(StrUtil.isNotEmpty(fileId),FileEvidenceProperty::getFileId, fileId).remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,170 @@
|
||||
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 cn.hutool.json.JSONUtil;
|
||||
import com.supervision.constant.EvidencePropertyName;
|
||||
import com.supervision.police.domain.EvidenceFile;
|
||||
import com.supervision.police.domain.FileEvidenceProperty;
|
||||
import com.supervision.police.domain.FileOcrProcess;
|
||||
import com.supervision.police.dto.*;
|
||||
import com.supervision.police.service.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class OCREvidenceServiceImpl implements OCREvidenceService {
|
||||
|
||||
private final FileOcrProcessService ocrProcessService;
|
||||
|
||||
private final OCRService ocrService;
|
||||
|
||||
private final FileEvidencePropertyService fileEvidencePropertyService;
|
||||
|
||||
private final EvidenceFileService evidenceFileService;
|
||||
|
||||
private final CaseEvidenceService caseEvidenceService;
|
||||
@Override
|
||||
public Boolean submitOrcTask(String fileId) {
|
||||
Assert.notEmpty(fileId, "文件id不能为空");
|
||||
|
||||
asyncDoOrcTask(null, fileId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class,transactionManager = "dataSourceTransactionManager")
|
||||
public List<FileEvidenceProperty> doOrcTask(String evidenceId,String fileId) {
|
||||
|
||||
List<FileEvidenceProperty> evidencePropertyList = new ArrayList<>();
|
||||
// 识别文件信息
|
||||
List<FileOcrProcess> fileOcrProcesses = ocrProcessService.syncSubmitOCR(CollUtil.newArrayList(fileId));
|
||||
|
||||
if (CollUtil.isEmpty(fileOcrProcesses)){
|
||||
log.warn("subOrcTask:文件id:{} 识别失败", fileId);
|
||||
return evidencePropertyList;
|
||||
}
|
||||
|
||||
for (FileOcrProcess fileOcrProcess : fileOcrProcesses) {
|
||||
|
||||
// 调用提取属性接口
|
||||
log.info("subOrcTask:文件id:{} 识别结果:{}", fileId, JSONUtil.toJsonStr(fileOcrProcess));
|
||||
RetrieveResDTO retrieve = ocrService.retrieve(new RetrieveReqDTO(fileOcrProcess.getOcrText()));
|
||||
log.info("subOrcTask:文件id:{} 识别结果:{}", fileId, JSONUtil.toJsonStr(retrieve));
|
||||
|
||||
if (Integer.valueOf(0).equals(retrieve.getStatus())){
|
||||
// 保存属性信息
|
||||
String title = retrieve.getTitle();
|
||||
if (StrUtil.isNotEmpty(title)){
|
||||
|
||||
evidencePropertyList.addAll(this.saveEvidenceProperty(evidenceId, fileId,
|
||||
Map.of(EvidencePropertyName.TITLE.getName(), retrieve.getTitle())));
|
||||
|
||||
if (StrUtil.isNotEmpty(evidenceId)){
|
||||
evidenceFileService.save(new EvidenceFile(evidenceId,fileId));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return evidencePropertyList;
|
||||
}
|
||||
|
||||
@Async
|
||||
@Override
|
||||
public void asyncDoOrcTask(String evidenceId, String fileId) {
|
||||
doOrcTask(evidenceId, fileId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class,transactionManager = "dataSourceTransactionManager")
|
||||
public List<FileEvidenceProperty> saveEvidenceProperty(String evidenceId,String fileId ,Map<String, String> propertyMap) {
|
||||
|
||||
// 先清空数据
|
||||
fileEvidencePropertyService.removeByEvidenceAndFileId(evidenceId,fileId);
|
||||
|
||||
List<FileEvidenceProperty> fileEvidence = toFileEvidence(evidenceId, fileId, propertyMap);
|
||||
fileEvidencePropertyService.saveBatch(fileEvidence);
|
||||
|
||||
return fileEvidence;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EvidenceFileOCRDTO> previewEvidence(List<String> fileIdList) {
|
||||
|
||||
if (CollUtil.isEmpty(fileIdList)){
|
||||
return new ArrayList<>(1);
|
||||
}
|
||||
List<OCREvidencePropertyDTO> ocrEvidencePropertyDTOS = fileEvidencePropertyService.listPrewByFileIdList(fileIdList);
|
||||
|
||||
List<EvidenceFileOCRDTO> collect = ocrEvidencePropertyDTOS.stream()
|
||||
.collect(Collectors.groupingBy(OCREvidencePropertyDTO::getFileId))
|
||||
.values().stream()
|
||||
.map(EvidenceFileOCRDTO::new)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return sortByIdOrder(fileIdList, collect);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class,transactionManager = "dataSourceTransactionManager")
|
||||
public String saveEvidence(EvidenceFileOCRDTO evidenceFileOCRDTO) {
|
||||
Assert.notEmpty(evidenceFileOCRDTO.getFileId(), "文件id不能为空");
|
||||
Assert.notEmpty(evidenceFileOCRDTO.getCaseId(), "案件id不能为空");
|
||||
Assert.notEmpty(evidenceFileOCRDTO.getEvidenceName(), "案件证据名称不能为空");
|
||||
Assert.notEmpty(evidenceFileOCRDTO.getEvidenceType(), "案件证据类型不能为空");
|
||||
|
||||
//保存证据信息
|
||||
String evidenceId = caseEvidenceService.saveEvidence(evidenceFileOCRDTO.toCaseEvidenceDTO());
|
||||
|
||||
//保存证据文件关联信息
|
||||
evidenceFileService.save(new EvidenceFile(evidenceId, evidenceFileOCRDTO.getFileId()));
|
||||
|
||||
// 保存证据属性
|
||||
List<FileEvidenceProperty> evidencePropertyList = saveEvidenceProperty(evidenceFileOCRDTO.getEvidenceId(),
|
||||
evidenceFileOCRDTO.getFileId(), evidenceFileOCRDTO.getProperty());
|
||||
|
||||
if (CollUtil.isEmpty(evidencePropertyList)){
|
||||
return null;
|
||||
}
|
||||
return CollUtil.getFirst(evidencePropertyList).getEvidenceId();
|
||||
}
|
||||
|
||||
|
||||
private List<EvidenceFileOCRDTO> sortByIdOrder(List<String> fileIdList, List<EvidenceFileOCRDTO> evidenceFileOCRDTOS){
|
||||
|
||||
if (CollUtil.size(fileIdList) < 2 || CollUtil.size(evidenceFileOCRDTOS) < 2) {
|
||||
return evidenceFileOCRDTOS;
|
||||
}
|
||||
|
||||
Map<String, EvidenceFileOCRDTO> fileOCRDTOMap = evidenceFileOCRDTOS.stream()
|
||||
.collect(Collectors.toMap(EvidenceFileOCRDTO::getFileId, recordFileDTO -> recordFileDTO, (k1, k2) -> k1));
|
||||
return fileIdList.stream().map(fileOCRDTOMap::get).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<FileEvidenceProperty> toFileEvidence(String evidenceId,String fileId ,Map<String, String> propertyMap){
|
||||
|
||||
if (StrUtil.isAllEmpty(evidenceId,fileId) || CollUtil.isEmpty(propertyMap)){
|
||||
log.warn("saveEvidenceProperty:参数为空");
|
||||
return new ArrayList<>(1);
|
||||
}
|
||||
|
||||
return EvidencePropertyName.getByNames(propertyMap)
|
||||
.stream().map(evidence ->
|
||||
new FileEvidenceProperty(evidenceId, fileId, evidence.getName(), propertyMap.get(evidence.getName())))
|
||||
.toList();
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue