1. ocr识别功能阶段性提交

topo_dev
xueqingkun 8 months ago
parent bb01706466
commit 3cf5df6def

@ -4,8 +4,10 @@ import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableAsync
@EnableScheduling
@MapperScan(basePackages = {"com.supervision.**.mapper"})
@SpringBootApplication(scanBasePackages = {"com.supervision.**"})
public class FuHsiApplication {

@ -1,54 +0,0 @@
//package com.supervision.config;
//
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.BeansException;
//import org.springframework.beans.factory.config.BeanPostProcessor;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.util.ReflectionUtils;
//import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
//import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
//import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
//
//import java.lang.reflect.Field;
//import java.util.List;
//import java.util.stream.Collectors;
//
//@Slf4j
//@Configuration
//public class BeanPostProcessorConfig {
//
// @Bean
// public BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {
// return new BeanPostProcessor() {
// @Override
// public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {
// customizeSpringfoxHandlerMappings(getHandlerMappings(bean));
// }
// return bean;
// }
//
// private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {
// List<T> copy = mappings.stream()
// .filter(mapping -> mapping.getPatternParser() == null)
// .collect(Collectors.toList());
// mappings.clear();
// mappings.addAll(copy);
// }
//
// @SuppressWarnings("unchecked")
// private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {
// try {
// Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
// field.setAccessible(true);
// return (List<RequestMappingInfoHandlerMapping>) field.get(bean);
// } catch (IllegalArgumentException | IllegalAccessException e) {
// throw new IllegalStateException(e);
// }
// }
// };
// }
//
//}
//

@ -0,0 +1,28 @@
package com.supervision.config;
import com.supervision.police.service.OCRService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.support.RestTemplateAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;
import org.springframework.web.util.DefaultUriBuilderFactory;
@Configuration
public class OCRServiceConfig {
@Value("${ocr.url}")
private String ocrUrl;
@Bean
public OCRService ocrService() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(ocrUrl));
RestTemplateAdapter adapter = RestTemplateAdapter.create(restTemplate);
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
return factory.createClient(OCRService.class);
}
}

@ -40,7 +40,7 @@ public class MinioServiceImpl implements MinioService {
minioFile.setSize(in.available());
int i = minioFileMapper.insert(minioFile);
if (i > 0) {
minioTemplate.putObject(bucketName, minioFile.getId(), null, in, in.available(), null);
minioTemplate.putObject(bucketName, minioFile.getId(), null, in, in.available(), file.getContentType());
return minioFile.getId();
} else {
return null;

@ -0,0 +1,60 @@
package com.supervision.police.controller;
import com.supervision.common.domain.R;
import com.supervision.police.domain.FileOcrProcess;
import com.supervision.police.domain.NoteRecord;
import com.supervision.police.dto.NoteRecordDTO;
import com.supervision.police.dto.OCRTextDTO;
import com.supervision.police.dto.RecordFileDTO;
import com.supervision.police.service.OCRRecordService;
import com.supervision.police.vo.NoteRecordReqVO;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@Slf4j
@RequestMapping("/ocr/record")
@ApiOperation(value = "OCR笔录接口")
@RequiredArgsConstructor
public class OCRRecordController {
private final OCRRecordService ocrRecordService;
/**
*
*/
@PostMapping("/saveRecord")
public R<String> saveRecord(@RequestBody NoteRecordReqVO noteRecordReqVO) {
String recordId = ocrRecordService.saveRecord(noteRecordReqVO);
return R.ok(recordId);
}
@GetMapping("/info")
public R<NoteRecordDTO> queryRecordInfo(@RequestParam("recordId") String recordId) {
NoteRecordDTO noteRecord = ocrRecordService.queryRecordInfo(recordId);
return R.ok(noteRecord);
}
@GetMapping("/fileList")
public R<List<RecordFileDTO>> queryFileList(@RequestParam("recordId") String recordId) {
List<RecordFileDTO> recordFileDTOList = ocrRecordService.queryFileList(recordId);
return R.ok(recordFileDTOList);
}
@GetMapping("/reOcr")
public R<Boolean> reOcr(@RequestParam("ocrId") String ocrId) {
Boolean success = ocrRecordService.reOcr(ocrId);
return R.ok(success);
}
@PostMapping("/reviseOcrText")
public R<Boolean> reviseOcrText(@RequestBody List<OCRTextDTO> ocrTextDTOList) {
Boolean success = ocrRecordService.reviseOcrText(ocrTextDTOList);
return R.ok(success);
}
}

@ -6,6 +6,7 @@ import java.io.Serializable;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.supervision.police.dto.OCRResDTO;
import lombok.Data;
/**
@ -27,7 +28,7 @@ public class FileOcrProcess implements Serializable {
private String fileId;
/**
* 0 1 2
* -1: 0 1 2
*/
private Integer status;
@ -72,4 +73,19 @@ public class FileOcrProcess implements Serializable {
@TableField(exist = false)
private static final long serialVersionUID = 1L;
public FileOcrProcess() {
}
public FileOcrProcess(String fileId,Integer status) {
this.fileId = fileId;
this.status = status;
}
public FileOcrProcess(OCRResDTO ocrResDTO){
this.fileId = ocrResDTO.getFile_id();
this.drawImgId = ocrResDTO.getDraw_img_id();
this.ocrText = ocrResDTO.getOcr_text();
this.status = ocrResDTO.getStatus();
}
}

@ -0,0 +1,47 @@
package com.supervision.police.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
public class OCRRecordDTO {
@Schema(description = "笔录id")
private String id;
@Schema(description = "案件id")
private String caseId;
@Schema(description = "姓名")
private String name;
@Schema(description = "笔录名称/供述材料")
private String recordName;
@Schema(description = "询问人")
private String lawAsker;
@Schema(description = "供述开始时间")
private String confessionStartTime;
@Schema(description = " 供述结束时间")
private String confessionEndTime;
private List<String> fileIdList;
}

@ -0,0 +1,25 @@
package com.supervision.police.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
@Data
public class OCRReqDTO {
@Schema(description = "文件id")
private List<String> file_ids = new ArrayList<>();
@Schema(description = "文件后缀")
private String suffix;
public OCRReqDTO() {
}
public OCRReqDTO(List<String> file_ids, String suffix) {
this.file_ids = file_ids;
this.suffix = suffix;
}
}

@ -0,0 +1,23 @@
package com.supervision.police.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class OCRResDTO {
@Schema(description = "文件id")
private String file_id;
@Schema(description = "图片id")
private String draw_img_id;
@Schema(description = "文件后缀")
private String ocr_text;
@Schema(description = "识别状态 0 成功 1正在识别 2识别失败")
private Integer status;
@Schema(description = "错误信息")
private String error_msg;
}

@ -0,0 +1,11 @@
package com.supervision.police.dto;
import lombok.Data;
@Data
public class OCRTextDTO {
private String ocrId;
private String reviseText;
}

@ -0,0 +1,48 @@
package com.supervision.police.dto;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.unit.DataSizeUtil;
import cn.hutool.core.util.NumberUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class RecordFileDTO {
@Schema(description = "笔录文件id")
private String fileId;
@Schema(description = "文件ocr识别id")
private String ocrId;
@Schema(description = "证据类型")
private String evidenceType;
@Schema(description = "证据类型描述")
private String evidenceTypeDesc;
@Schema(description = "文件名称")
private String fileName;
@Schema(description = "文件大小")
private String fileSize;
@Schema(description = "文件识别状态 -1:未识别 0正在识别 1识别成功 2识别失败")
private String ocrStatus;
@Schema(description = "文件识别内容")
private String ocrText;
@Schema(description = "文件识别内容修改后")
private String reviseText;
@Schema(description = "文件预览图id")
private String drawImgId;
public void setDefaultEvidenceTypeDesc() {
this.evidenceTypeDesc = "书证";
}
public void formatFileSize() {
fileSize=DataSizeUtil.format(NumberUtil.parseInt(this.fileSize));
}
}

@ -2,6 +2,10 @@ package com.supervision.police.mapper;
import com.supervision.police.domain.FileOcrProcess;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.supervision.police.dto.RecordFileDTO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author Administrator
@ -11,6 +15,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
*/
public interface FileOcrProcessMapper extends BaseMapper<FileOcrProcess> {
List<RecordFileDTO> queryFileList(@Param("fileIdList") List<String> fileIdList);
}

@ -2,6 +2,11 @@ package com.supervision.police.service;
import com.supervision.police.domain.FileOcrProcess;
import com.baomidou.mybatisplus.extension.service.IService;
import com.supervision.police.dto.OCRReqDTO;
import com.supervision.police.dto.OCRResDTO;
import com.supervision.police.dto.RecordFileDTO;
import java.util.List;
/**
* @author Administrator
@ -10,4 +15,23 @@ import com.baomidou.mybatisplus.extension.service.IService;
*/
public interface FileOcrProcessService extends IService<FileOcrProcess> {
List<FileOcrProcess> submitOCR(List<String> fileIdList);
void doOCRTask(List<FileOcrProcess> fileOcrProcesses);
void doAllOCRTask();
List<FileOcrProcess> pageListByStatus(Integer status,Integer size);
Integer countByStatus(Integer status);
Boolean updateOCrStatus(List<String> ocrIdList, Integer ocrStatus);
Boolean updateByOcrRes(OCRResDTO ocrResDTO);
List<RecordFileDTO> queryFileList(List<String> fileIdList);
}

@ -0,0 +1,23 @@
package com.supervision.police.service;
import com.supervision.police.domain.NoteRecord;
import com.supervision.police.dto.NoteRecordDTO;
import com.supervision.police.dto.OCRTextDTO;
import com.supervision.police.dto.RecordFileDTO;
import com.supervision.police.vo.NoteRecordReqVO;
import java.util.List;
public interface OCRRecordService {
String saveRecord(NoteRecordReqVO noteRecordReqVO);
NoteRecordDTO queryRecordInfo(String recordId);
List<RecordFileDTO> queryFileList(String recordId);
Boolean reviseOcrText(String fileId,String reviseText);
Boolean reviseOcrText(List<OCRTextDTO> ocrTextDTOList);
Boolean reOcr(String ocrId);
}

@ -0,0 +1,17 @@
package com.supervision.police.service;
import com.supervision.police.dto.OCRReqDTO;
import com.supervision.police.dto.OCRResDTO;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.service.annotation.HttpExchange;
import org.springframework.web.service.annotation.PostExchange;
import java.util.List;
@HttpExchange
public interface OCRService {
@PostExchange(url = "/ocr", contentType = MediaType.APPLICATION_JSON_VALUE)
List<OCRResDTO> ocr(@RequestBody OCRReqDTO ocrReqDTO);
}

@ -1,20 +1,153 @@
package com.supervision.police.service.impl;
import cn.hutool.core.collection.CollUtil;
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.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.OCRService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
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.stream.Collectors;
/**
* @author Administrator
* @description file_ocr_process(ocr)Service
* @createDate 2024-08-30 17:35:23
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class FileOcrProcessServiceImpl extends ServiceImpl<FileOcrProcessMapper, FileOcrProcess>
implements FileOcrProcessService{
@Value("${ocr.pool.max-size:20}")
private Integer poolMaxSize;
private final OCRService ocrService;
private final MinioService minioService;
@Override
@Transactional(transactionManager = "dataSourceTransactionManager",rollbackFor = Exception.class)
public List<FileOcrProcess> submitOCR(List<String> fileIdList) {
if (CollUtil.isEmpty(fileIdList)){
log.info("submitOCR:fileIds为空。提交ocr任务...");
return new ArrayList<>(1);
}
List<FileOcrProcess> processList = new ArrayList<>();
for (String fileId : fileIdList) {
FileOcrProcess fileOcrProcess = new FileOcrProcess(fileId, -1);
super.save(fileOcrProcess);
processList.add(fileOcrProcess);
}
doOCRTask(processList);
return processList;
}
@Async
@Override
public synchronized void doOCRTask(List<FileOcrProcess> fileOcrProcesses) {
if (CollUtil.isEmpty(fileOcrProcesses)){
log.info("asyncOcr:当前暂无识别的任务,结束...");
return;
}
List<List<FileOcrProcess>> ocrTaskList = CollUtil.split(fileOcrProcesses, poolMaxSize);
for (List<FileOcrProcess> ocrProcesses : ocrTaskList) {
List<String> fileIdList = ocrProcesses.stream().map(FileOcrProcess::getFileId).collect(Collectors.toList());
List<OCRReqDTO> ocrReqDTOS = buildOCRReqDTO(fileIdList);
for (OCRReqDTO ocrReqDTO : ocrReqDTOS) {
log.info("ocr:开始识别文件:{}", JSONUtil.toJsonStr(ocrReqDTO));
this.updateOCrStatus(ocrReqDTO.getFile_ids(),0);
try {
List<OCRResDTO> ocrRes = ocrService.ocr(ocrReqDTO);
log.info("ocr:识别结果:{}", JSONUtil.toJsonStr(ocrRes));
if (CollUtil.isNotEmpty(ocrRes)){
for (OCRResDTO ocrRe : ocrRes) {
if (Integer.valueOf(2).equals(ocrRe.getStatus())){
log.info("ocr:文件{}识别失败,原因:{}", ocrRe.getFile_id(), ocrRe.getError_msg());
}
}
}
ocrRes.forEach(this::updateByOcrRes);
} catch (Exception e) {
log.error("远程调用ocr识别接口失败",e);
this.updateOCrStatus(ocrReqDTO.getFile_ids(),2);
}
}
}
}
@Override
public void doAllOCRTask() {
List<FileOcrProcess> allFileOcrProcesses = pageListByStatus(-1, 99999);
doOCRTask(allFileOcrProcesses);
}
@Override
public List<FileOcrProcess> pageListByStatus(Integer status, Integer size) {
return super.lambdaQuery().eq(FileOcrProcess::getStatus, status).page(new Page<>(1, size)).getRecords();
}
@Override
public Integer countByStatus(Integer status) {
return Math.toIntExact(super.lambdaQuery().eq(FileOcrProcess::getStatus, status).count());
}
@Override
public Boolean updateOCrStatus(List<String> ocrIdList, Integer ocrStatus) {
return super.lambdaUpdate().in(FileOcrProcess::getFileId, ocrIdList)
.set(FileOcrProcess::getStatus, ocrStatus).update();
}
@Override
public Boolean updateByOcrRes(OCRResDTO ocrResDTO) {
return super.lambdaUpdate().eq(FileOcrProcess::getFileId, ocrResDTO.getFile_id())
.set(FileOcrProcess::getOcrText, ocrResDTO.getOcr_text())
.set(FileOcrProcess::getStatus, ocrResDTO.getStatus())
.set(FileOcrProcess::getDrawImgId, ocrResDTO.getDraw_img_id())
.update();
}
@Override
public List<RecordFileDTO> queryFileList(List<String> fileIdList) {
if (CollUtil.isEmpty(fileIdList)){
return new ArrayList<>(1);
}
return super.baseMapper.queryFileList(fileIdList);
}
private List<OCRReqDTO> buildOCRReqDTO(List<String> fileIdList){
List<MinioFile> minioFiles = minioService.listMinioFile(fileIdList);
return minioFiles.stream().collect(Collectors.groupingBy(MinioFile::getFileType))
.entrySet().stream().map(entry ->
new OCRReqDTO(entry.getValue().stream().map(MinioFile::getId).collect(Collectors.toList()),entry.getKey()))
.collect(Collectors.toList());
}
}

@ -0,0 +1,121 @@
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.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.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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor
public class OCRRecordServiceImpl implements OCRRecordService {
private final FileOcrProcessService fileOcrProcessService;
private final NoteRecordService noteRecordService;
@Override
public String saveRecord(NoteRecordReqVO noteRecordReqVO) {
noteRecordReqVO.saveValidate();
NoteRecord record = noteRecordReqVO.toNoteRecord();
String recordId = noteRecordService.saveOrUpdRecord(record);
if (CollUtil.isEmpty(noteRecordReqVO.getFileIdList())){
log.info("uploadRecords:文件内容为空...不进行笔录分析操作...");
return recordId;
}
// 识别文件信息
fileOcrProcessService.submitOCR(noteRecordReqVO.getFileIdList());
return recordId;
}
@Override
public NoteRecordDTO queryRecordInfo(String recordId) {
NoteRecord noteRecord = new NoteRecord();
noteRecord.setId(recordId);
List<NoteRecordDTO> noteRecordDTOS = noteRecordService.selectNoteRecordDTOList(noteRecord);
if (CollUtil.isEmpty(noteRecordDTOS)){
return new NoteRecordDTO();
}
return CollUtil.getFirst(noteRecordDTOS);
}
@Override
public List<RecordFileDTO> queryFileList(String recordId) {
NoteRecord noteRecord = noteRecordService.getById(recordId);
String fileIds = noteRecord.getFileIds();
if (StrUtil.isEmpty(fileIds)){
log.info("queryFileList:笔录:{}对应的fileIds为空...",recordId);
return CollUtil.newArrayList();
}
List<String> fileIdList = Arrays.stream(fileIds.split(",")).toList();
List<RecordFileDTO> recordFileDTOS = fileOcrProcessService.queryFileList(fileIdList);
recordFileDTOS = sortByIdOrder(fileIdList, recordFileDTOS);
recordFileDTOS.forEach(record->{
record.formatFileSize();
record.setDefaultEvidenceTypeDesc();
});
return recordFileDTOS;
}
@Override
public Boolean reviseOcrText(String id,String reviseText) {
Assert.notEmpty(id, "id不能为空");
Assert.notEmpty(reviseText, "reviseText不能为空");
return fileOcrProcessService.lambdaUpdate()
.eq(FileOcrProcess::getId, id)
.set(FileOcrProcess::getReviseText, reviseText).update();
}
@Override
public Boolean reviseOcrText(List<OCRTextDTO> ocrTextDTOList) {
if (CollUtil.isEmpty(ocrTextDTOList)){
return false;
}
ocrTextDTOList.forEach(ocrTextDTO -> this.reviseOcrText(ocrTextDTO.getOcrId(), ocrTextDTO.getReviseText()));
return true;
}
@Override
public Boolean reOcr(String ocrId) {
FileOcrProcess fileOcrProcess = fileOcrProcessService.getById(ocrId);
Assert.notNull(fileOcrProcess, "ocrId:{}对应的ocr信息不存在", ocrId);
fileOcrProcessService.doOCRTask(CollUtil.newArrayList(fileOcrProcess));
return null;
}
private List<RecordFileDTO> sortByIdOrder(List<String> fileIdList,List<RecordFileDTO> recordFileDTOList){
if (CollUtil.size(fileIdList) < 2 || CollUtil.size(recordFileDTOList) < 2) {
return recordFileDTOList;
}
Map<String, RecordFileDTO> recordFileDTOMap = recordFileDTOList.stream()
.collect(Collectors.toMap(RecordFileDTO::getFileId,recordFileDTO -> recordFileDTO, (k1, k2) -> k1));
return fileIdList.stream().map(recordFileDTOMap::get).filter(Objects::nonNull).collect(Collectors.toList());
}
}

@ -1,6 +1,7 @@
package com.supervision.police.vo;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.supervision.police.domain.NoteRecord;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -10,30 +11,22 @@ import java.util.List;
@Data
public class NoteRecordReqVO {
@Schema(description = "笔录id")
private String id;
/**
* id
*/
@Schema(description = "案件id")
private String caseId;
/**
*
*/
@Schema(description = "笔录名称")
private String recordName;
/**
* id
*/
@Schema(description = "笔录文件id集合")
private List<String> fileIdList;
@Schema(description = "笔录人员id")
private String personId;
/**
*
*/
@Schema(description = "姓名")
private String name;
/**
@ -46,19 +39,17 @@ public class NoteRecordReqVO {
*/
private String confessionMaterial;
/**
*
*/
@Schema(description = "询问人")
private String lawAsker;
/**
*
*/
@Schema(description = "供述开始时间")
private String confessionStartTime;
/**
*
*/
@Schema(description = "供述结束时间")
private String confessionEndTime;
public NoteRecord toNoteRecord(){
@ -79,5 +70,16 @@ public class NoteRecordReqVO {
return noteRecord;
}
// 校验
public void saveValidate() {
Assert.notBlank(personId, "笔录人员不能为空");
Assert.notBlank(lawAsker, "询问人不能为空");
Assert.notEmpty(fileIdList, "笔录文件id集合不能为空");
Assert.notBlank(confessionStartTime, "供述开始时间不能为空");
Assert.notBlank(confessionEndTime, " 供述结束时间不能为空");
Assert.notBlank(recordName, "笔录名称不能为空");
}
}

@ -0,0 +1,29 @@
package com.supervision.task;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.supervision.police.service.FileOcrProcessService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
@Slf4j
@Configuration
@RequiredArgsConstructor
public class ScheduleTask {
private final FileOcrProcessService fileOcrProcessService;
/**
* 30OCR
*/
// @Scheduled(initialDelay = 60*1000,fixedDelay = 30* 1000)
public void doAllOCRTask() {
log.info("定时任务:doOCRTask: 开始执行。当前时间:{}", DateUtil.date());
DateTime start = DateUtil.date();
fileOcrProcessService.doAllOCRTask();
log.info("定时任务:doOCRTask: 执行完毕。耗时:{}秒", DateUtil.between(start, DateUtil.date(), DateUnit.SECOND));
}
}

@ -72,3 +72,8 @@ logging:
langChain-chat:
url: http://113.128.242.110:7861
ocr:
url: http://192.168.10.42:8000/
pool:
max-size: 20

@ -68,6 +68,9 @@ logging:
langChain-chat:
url:
ocr:
url: http://192.168.10.137:8866/
springdoc:
swagger-ui:
enabled: false

@ -0,0 +1,83 @@
spring:
application:
name: fu-hsi-server
ai:
# 文档地址 https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/api/chat/ollama-chat.html
ollama:
# base-url: http://113.128.242.110:11434
base-url: http://192.168.10.70:11434
#base-url: http://112.81.86.50:11434
chat:
enabled: true
options:
#model: qwen2:72b
model: llama3-chinese:8b
# model: qwen2:72b
# 控制模型在请求后加载到内存中的时间(稍微长一点的时间,避免重复加载浪费性能,加快处理速度)
keep_alive: 30m
# 例如0.3
temperature: 0.8
format: json
# 减少产生废话的可能性。较高的值例如100将给出更多样化的答案而较低的值例如10将更加保守。
top-k: 90
# 与top-k一起工作。较高的值例如0.95将导致更加多样化的文本而较低的值例如0.5)将生成更加集中和保守的文本。
top-p: 0.95
# 随机数种子,用于控制模型输出的随机性。
seed: 1
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:15415/nx_llm?useUnicode=true&characterEncoding=utf-8&useSSL=true&nullCatalogMeansCurrent=true&serverTimezone=GMT%2B8
#url: jdbc:mysql://113.128.242.110:3306/nx_llm?useUnicode=true&characterEncoding=utf-8&useSSL=true&nullCatalogMeansCurrent=true&serverTimezone=GMT%2B8
username: root
password: 'llm@984573~!eda'
initial-size: 5 # 初始化大小
min-idle: 10 # 最小连接数
max-active: 20 # 最大连接数
max-wait: 60000 # 获取连接时的最大等待时间
min-evictable-idle-time-millis: 300000 # 一个连接在池中最小生存的时间,单位是毫秒
time-between-eviction-runs-millis: 60000 # 多久才进行一次检测需要关闭的空闲连接,单位是毫秒
filters: stat,wall # 配置扩展插件stat-监控统计log4j-日志wall-防火墙防止SQL注入去掉后监控界面的sql无法统计
validation-query: SELECT 1 # 检测连接是否有效的 SQL语句为空时以下三个配置均无效
test-on-borrow: true # 申请连接时执行validationQuery检测连接是否有效默认true开启后会降低性能
test-on-return: true # 归还连接时执行validationQuery检测连接是否有效默认false开启后会降低性能
test-while-idle: true # 申请连接时如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效默认false建议开启不影响性能
stat-view-servlet:
enabled: false # 是否开启 StatViewServlet
filter:
stat:
enabled: true # 是否开启 FilterStat默认true
log-slow-sql: true # 是否开启 慢SQL 记录默认false
slow-sql-millis: 5000 # 慢 SQL 的标准,默认 3000单位毫秒
merge-sql: false # 合并多个连接池的监控数据默认false
data:
neo4j:
database: neo4j
# neo4j:
# uri: bolt://113.128.242.110:7687
# authentication:
# username: neo4j
# password: Sushengtian@sdjn2023
neo4j:
uri: bolt://127.0.0.1:17666
authentication:
username: neo4j
password: llm@984neoda
minio:
endpoint: http:127.0.0.1:19020
accessKey: admin
secretKey: llm@984573~!die
bucketName: nxfuhsi
logging:
level:
org.springframework.ai: TRACE
langChain-chat:
url: http://113.128.242.110:7861
ocr:
url: http://192.168.10.137:8866/

@ -66,4 +66,7 @@ logging:
org.springframework.ai: TRACE
langChain-chat:
url: http://113.128.242.110:7861
url: http://113.128.242.110:7861
ocr:
url: http://192.168.10.137:8866/

@ -23,4 +23,21 @@
create_user_id,create_time,update_user_id,
update_time
</sql>
<select id="queryFileList" resultType="com.supervision.police.dto.RecordFileDTO">
select
mf.id as fileId,
mf.filename as fileName,
mf.size as fileSize,
op.id as ocrId,
op.status as ocrStatus,
op.ocr_text as ocrText,
op.revise_text as reviseText,
op.draw_img_id as drawImgId
from minio_file mf
left join file_ocr_process op on op.file_id = mf.id
where mf.id in
<foreach collection="fileIdList" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
</mapper>

@ -22,6 +22,9 @@
from note_record r
left join case_person p on r.case_person_id = p.id
where r.data_status = '1'
<if test="id != null and id != ''">
and r.id = #{id}
</if>
<if test="caseId != null and caseId != ''">
and r.case_id = #{caseId}
</if>

Loading…
Cancel
Save