You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
fu-hsi-service/src/main/java/com/supervision/police/service/impl/CaseEvidenceServiceImpl.java

817 lines
39 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.supervision.police.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.supervision.minio.domain.MinioFile;
import com.supervision.minio.service.MinioService;
import com.supervision.police.dto.*;
import com.supervision.police.service.*;
import com.supervision.police.domain.CaseEvidence;
import com.supervision.police.domain.ComDictionary;
import com.supervision.police.domain.EvidenceFile;
import com.supervision.common.constant.EvidenceConstants;
import com.supervision.police.domain.*;
import com.supervision.police.mapper.CaseEvidenceMapper;
import com.supervision.police.vo.EvidenceDirectoryReqVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor
public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, CaseEvidence> implements CaseEvidenceService {
private final EvidenceFileService evidenceFileService;
private final ComDictionaryService comDictionaryService;
private final CaseStatusManageService caseStatusManageService;
private final FileOcrProcessService fileOcrProcessService;
private final MinioService minioService;
private final ModelCaseService modelCaseService;
@Autowired
private OCREvidenceService ocrEvidenceService;
@Autowired
private LLMExtractService llmExtractService;
@Autowired
private EvidenceDirectoryService evidenceDirectoryService;
@Autowired
private EvidenceCategoryService evidenceCategoryService;
@Autowired
private NotePromptService notePromptService;
private final XxlJobService xxlJobService;
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public String saveEvidence(CaseEvidenceDTO caseEvidenceDTO) {
// 必填校验
caseEvidencePersistenceAssert(caseEvidenceDTO);
// 保存证据信息
CaseEvidence caseEvidence = caseEvidenceDTO.toCaseEvidence();
super.save(caseEvidence);
//保存文件关联信息
caseEvidenceDTO.getFileIdList().forEach(fileId -> {
EvidenceFile evidenceFile = new EvidenceFile();
evidenceFile.setFileId(fileId);
evidenceFile.setEvidenceId(caseEvidence.getId());
evidenceFileService.save(evidenceFile);
});
caseStatusManageService.whenUpdateEvidence(caseEvidence.getCaseId());
return caseEvidence.getId();
}
private void caseEvidencePersistenceAssert(CaseEvidenceDTO caseEvidenceDTO) {
Assert.notEmpty(caseEvidenceDTO.getCaseId(), "案件id不能为空");
Assert.notEmpty(caseEvidenceDTO.getEvidenceName(), "证据名称不能为空");
Assert.notEmpty(caseEvidenceDTO.getEvidenceType(), "证据类型不能为空");
//Assert.notEmpty(caseEvidenceDTO.getProvider(),"证据提供人不能为空");
Assert.notEmpty(caseEvidenceDTO.getFileIdList(), "文件id不能为空");
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public String updateEvidence(CaseEvidenceDTO caseEvidenceDTO) {
Assert.notEmpty(caseEvidenceDTO.getId(), "证据id不能为空");
caseEvidencePersistenceAssert(caseEvidenceDTO);
super.getOptById(caseEvidenceDTO.getId()).orElseThrow(() -> new IllegalArgumentException("证据信息不存在"));
// 更新证据信息
CaseEvidence caseEvidence = caseEvidenceDTO.toCaseEvidence();
super.updateById(caseEvidence);
// 更新文件关联信息
evidenceFileService.lambdaUpdate().eq(EvidenceFile::getEvidenceId, caseEvidence.getId()).remove();
caseEvidenceDTO.getFileIdList().forEach(fileId -> {
EvidenceFile evidenceFile = new EvidenceFile();
evidenceFile.setFileId(fileId);
evidenceFile.setEvidenceId(caseEvidence.getId());
evidenceFileService.save(evidenceFile);
});
caseStatusManageService.whenUpdateEvidence(caseEvidenceDTO.getCaseId());
// 更新证据属性信息
for (String fileId : caseEvidenceDTO.getFileIdList()) {
caseEvidenceDTO.setTitleProperty();
ocrEvidenceService.saveEvidenceProperty(caseEvidence.getId(), fileId, caseEvidenceDTO.getProperty());
}
return caseEvidenceDTO.getId();
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public boolean deleteEvidence(String evidenceId) {
CaseEvidence caseEvidence = super.getOptById(evidenceId).orElseThrow(() -> new IllegalArgumentException("证据信息不存在"));
boolean remove = super.lambdaUpdate().eq(CaseEvidence::getId, evidenceId).remove();
if (remove) {
evidenceFileService.lambdaUpdate().eq(EvidenceFile::getEvidenceId, evidenceId).remove();
caseStatusManageService.whenUpdateEvidence(caseEvidence.getCaseId());
}
return remove;
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public List<CaseEvidenceDetailDTO> queryEvidenceList(String caseId) {
return super.getBaseMapper().queryEvidenceList(caseId);
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public List<CaseEvidenceDetailDTO> queryEvidenceList(String caseId, String batchNo) {
List<CaseEvidenceDetailDTO> caseEvidenceDetailDTOS = queryEvidenceList(caseId);
if (StrUtil.isNotEmpty(batchNo)){
for (CaseEvidenceDetailDTO evidenceDetail : caseEvidenceDetailDTOS) {
List<EvidenceFileDTO> filter = evidenceDetail.getFileList().stream().filter(file -> StrUtil.equals(file.getBatchNo(), batchNo)).toList();
evidenceDetail.setFileList(filter);
}
}
return caseEvidenceDetailDTOS;
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public IPage<CaseEvidenceDetailDTO> pageListEvidence(String caseId, String directoryId,String evidenceName, Integer pageNum, Integer pageSize) {
Assert.notEmpty(caseId, "案件id不能为空");
Page<CaseEvidence> caseEvidencePage = super.lambdaQuery().eq(CaseEvidence::getCaseId, caseId)
.eq(StrUtil.isNotEmpty(directoryId), CaseEvidence::getDirectoryId, directoryId)
.like(StrUtil.isNotEmpty(evidenceName), CaseEvidence::getEvidenceName, evidenceName)
.orderBy(true, false, CaseEvidence::getUpdateTime)
.page(new Page<>(pageNum, pageSize));
if (caseEvidencePage.getTotal() == 0) {
return PageDTO.of(pageNum, pageSize, 0);
}
// 查询文件信息
List<String> evidenceIds = caseEvidencePage.getRecords().stream().map(CaseEvidence::getId).distinct().toList();
List<EvidenceFileDTO> fileInfoList = evidenceFileService.listFileInfo(evidenceIds);
Map<String, List<EvidenceFileDTO>> evidenceFileMap = fileInfoList.stream().collect(Collectors.groupingBy(EvidenceFileDTO::getEvidenceId));
List<RecordFileDTO> recordFileDTOS = fileOcrProcessService.queryFileList(fileInfoList.stream().map(EvidenceFileDTO::getFileId).toList());
List<EvidenceDirectoryDTO> evidenceDirectoryDTOS = listDirectoryTree(caseId);
// 转换分页结果
//查询字典
List<ComDictionary> evidenceTypeDic = comDictionaryService.lambdaQuery().eq(ComDictionary::getType, "evidence_type").list();
return caseEvidencePage.convert(caseEvidence -> {
CaseEvidenceDetailDTO caseEvidenceDetailDTO = new CaseEvidenceDetailDTO(caseEvidence, evidenceFileMap.get(caseEvidence.getId()));
caseEvidenceDetailDTO.setEvidenceTypeDesc(
comDictionaryService.getName(evidenceTypeDic, "evidence_type", caseEvidence.getEvidenceType()));
caseEvidenceDetailDTO.setContentTypeValue(recordFileDTOS);
EvidenceDirectoryDTO directory = evidenceDirectoryService.findDirectoryById(caseEvidence.getDirectoryId(), evidenceDirectoryDTOS);
caseEvidenceDetailDTO.setEvidenceFormatValue(directory);
return caseEvidenceDetailDTO;
});
}
@Override
public CaseEvidenceDetailDTO queryEvidenceDetail(String evidenceId) {
return super.getBaseMapper().queryEvidenceDetail(evidenceId);
}
@Override
public void evidenceAnalysis(String evidenceId) {
log.info("证据解析开始。证据ID:【{}】", evidenceId);
long start = System.currentTimeMillis();
LLMExtractDto llmExtractDto = new LLMExtractDto();
// 查出证据、文件、如果证据
CaseEvidence caseEvidence = getById(evidenceId);
if (caseEvidence == null) {
log.error("证据不存在");
return;
}
List<EvidenceFile> evidenceFiles = evidenceFileService.lambdaQuery().eq(EvidenceFile::getEvidenceId, evidenceId).list();
if (evidenceFiles.isEmpty()) {
log.error("证据文件不存在");
return;
}
try {
// 根据rank升序排序
evidenceFiles.sort(Comparator.comparing(EvidenceFile::getRank));
log.info("OCR识别开始。证据文件ID:【{}】", evidenceFiles.stream().map(EvidenceFile::getFileId).toList());
long ocrStart = System.currentTimeMillis();
List<FileOcrProcess> fileOcrProcesses = fileOcrProcessService.syncSubmitOCR(evidenceFiles.stream().map(EvidenceFile::getFileId).toList());
log.info("OCR识别完成。更新证据处理状态为【OCR识别完成】。耗时:【{}】ms", System.currentTimeMillis() - ocrStart);
caseEvidence.setProcessStatus(EvidenceConstants.PROCESS_STATUS_OCR_OK);
updateById(caseEvidence);
// 遍历OCR结果拼接ocrText并赋值给lLMExtractDto的text
StringBuilder ocrText = new StringBuilder();
fileOcrProcesses.forEach(fileOcrProcess -> {
if (StrUtil.isNotEmpty(fileOcrProcess.getReviseText())){
ocrText.append(fileOcrProcess.getReviseText());
}else {
ocrText.append(fileOcrProcess.getOcrText());
}
});
llmExtractDto.setText(ocrText.toString());
log.info("标题提取开始。");
long titleStart = System.currentTimeMillis();
llmExtractDto = llmExtractService.extractTitle(Collections.singletonList(llmExtractDto)).get(0);
log.info("标题提取完成。更新证据处理状态为【标题提取完成】。标题:【{}】。耗时:【{}】ms", llmExtractDto.getTitle(), System.currentTimeMillis() - titleStart);
caseEvidence.setProcessStatus(EvidenceConstants.PROCESS_STATUS_TITLE_EXTRACT_OK);
updateById(caseEvidence);
// 根据证据目录id查询提示词
EvidenceDirectory directory = evidenceDirectoryService.getById(caseEvidence.getDirectoryId());
EvidenceCategory category = evidenceCategoryService.getById(directory.getCategoryId());
NotePrompt notePrompt = notePromptService.getById(category.getPromptId());
if (notePrompt != null) {
log.info("属性提取开始。");
long attrStart = System.currentTimeMillis();
llmExtractDto.setPrompt(notePrompt.getPrompt());
llmExtractDto.setExtractAttributes(notePrompt.getExtractAttributes());
llmExtractDto = llmExtractService.extractAttribute(Collections.singletonList(llmExtractDto)).get(0);
Map<String, String> map = new HashMap<>();
llmExtractDto.getExtractAttributes().forEach(notePromptExtractAttribute -> map.put(notePromptExtractAttribute.getAttrName(), notePromptExtractAttribute.getAttrValue()));
caseEvidence.setProperty(map);
log.info("属性提取完成。更新证据处理状态为【属性提取完成】。属性:【{}】。耗时:【{}】", caseEvidence.getProperty(), System.currentTimeMillis() - attrStart);
caseEvidence.setProcessStatus(EvidenceConstants.PROCESS_STATUS_ATTR_EXTRACT_OK);
updateById(caseEvidence);
} else {
log.info("没有关联提示词,不提取属性");
}
log.info("证据解析完成。更新证据处理状态为【处理成功】。");
caseEvidence.setProcessStatus(EvidenceConstants.PROCESS_STATUS_SUCCESS);
updateById(caseEvidence);
} catch (Exception e) {
log.error("证据解析失败。更新证据处理状态为【处理失败】。", e);
caseEvidence.setProcessStatus(EvidenceConstants.PROCESS_STATUS_FAILED);
updateById(caseEvidence);
} finally {
log.info("证据解析完成。证据ID:【{}】耗时:【{}】ms", evidenceId, System.currentTimeMillis() - start);
}
}
@Override
public List<EvidenceCategoryDTO> listCategoryTree(String caseType) {
Assert.notEmpty(caseType,"案件类型不能为空!");
return evidenceCategoryService.listCategoryTree(caseType);
}
@Override
public List<EvidenceDirectoryDTO> listFileTree(String caseId) {
Assert.notEmpty(caseId,"案件ID不能为空!");
List<EvidenceDirectoryDTO> evidenceDirectoryDTOS = evidenceDirectoryService.listDirectoryTree(caseId);
evidenceDirectoryService.appendFile(evidenceDirectoryDTOS, evidenceFileService.listFileInfoByCaseId(caseId));
return evidenceDirectoryDTOS;
}
@Override
public List<EvidenceDirectoryDTO> listDirectoryTree(String caseId) {
Assert.notEmpty(caseId,"案件ID不能为空!");
return evidenceDirectoryService.listDirectoryTree(caseId);
}
@Override
public void initCaseEvidenceDirectory(String caseId, String caseType) {
List<EvidenceCategoryDTO> evidenceCategoryDTOS = evidenceCategoryService.listCategoryTree(caseType);
initCaseEvidenceDirectory(evidenceCategoryDTOS, caseId, null);
}
@Override
public Boolean updateDirectory(EvidenceDirectory evidenceDirectory) {
Assert.notEmpty(evidenceDirectory.getId(),"目录ID不能为空!");
Assert.notEmpty(evidenceDirectory.getParentId(),"父级目录id不能为空");
return evidenceDirectoryService.lambdaUpdate()
.set(EvidenceDirectory::getParentId, evidenceDirectory.getParentId())
.eq(EvidenceDirectory::getId, evidenceDirectory.getId()).update();
}
@Override
public Boolean moveFile(DirectoryFileDTO evidenceFileDTO) {
Assert.notEmpty(evidenceFileDTO.getFileIdList(), "文件id不能为空");
Assert.notEmpty(evidenceFileDTO.getCaseId(), "案件id不能为空");
Assert.notEmpty(evidenceFileDTO.getDirectoryId(), "目录id不能为空");
return evidenceFileService.lambdaUpdate()
.set(EvidenceFile::getDirectoryId, evidenceFileDTO.getDirectoryId())
.in(EvidenceFile::getFileId, evidenceFileDTO.getFileIdList())
.update();
}
@Override
public Boolean removeFile(DirectoryFileDTO evidenceFileDTO) {
Assert.notEmpty(evidenceFileDTO.getFileIdList(), "文件id不能为空");
Assert.notEmpty(evidenceFileDTO.getCaseId(), "案件id不能为空");
return evidenceFileService.lambdaUpdate()
.in(EvidenceFile::getFileId, evidenceFileDTO.getFileIdList())
.remove();
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public Boolean removeDirectory(List<String> directoryIdList) {
if (CollUtil.isEmpty(directoryIdList)){
return false;
}
boolean success = evidenceDirectoryService.removeBatchByIds(directoryIdList);
if (success){
// 删除目录,意味着证据也要被删除
super.lambdaUpdate().eq(CaseEvidence::getDirectoryId, directoryIdList).remove();
evidenceFileService.lambdaUpdate().in(EvidenceFile::getDirectoryId, directoryIdList).remove();
}
return success;
}
/**
* 提取证据信息
* 1. 只对证据文件进行新增操作,不删除已有的文件
* 2. 如果第三级目录下已经存在文件只新增证据文件对证据进行ocr识别但不对证据进行重新提取操作
* @param caseId
* @param evidenceFileDTOS 文件信息
*/
@Override
@Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
public String ocrAndExtract(String caseId, List<EvidenceDirectoryDTO> evidenceFileDTOS) {
List<CaseEvidenceDetailDTO> oldEvidences = this.queryEvidenceList(caseId);
List<EvidenceDirectoryDTO> evidenceDirectoryDTOS = listFileTree(caseId);
List<CaseEvidenceDetailDTO> newEvidences = toCaseCaseEvidenceDetailDTO(evidenceFileDTOS, evidenceDirectoryDTOS);
newEvidences.forEach(caseEvidenceDetailDTO -> caseEvidenceDetailDTO.setCaseId(caseId));
List<CaseEvidenceDetailDTO> operationalEvidence = findChangedEvidence(oldEvidences, newEvidences);
String batchId = updateCaseEvidence(operationalEvidence);
for (CaseEvidenceDetailDTO caseEvidenceDetailDTO : operationalEvidence) {
if (StrUtil.equalsAny(caseEvidenceDetailDTO.getUpdateStatus(),"-1","0")){
// 只需要识别即可
fileOcrProcessService.syncSubmitOCR(List.of(caseEvidenceDetailDTO.getId()));
// todo:是否需要提取标题
}
if (StrUtil.equals(caseEvidenceDetailDTO.getUpdateStatus(),"1")){
// 需要分析ocr识别+标题提取)
xxlJobService.executeTaskByJobHandler("evidenceAnalysis", caseEvidenceDetailDTO.getId());
}
}
return batchId;
}
@Override
@Transactional(transactionManager = "dataSourceTransactionManager",propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public String updateCaseEvidence(List<CaseEvidenceDetailDTO> caseEvidenceDetailDTOList) {
String batchNo = DateTime.now().toString("yyyyMMddHHmmss");
for (CaseEvidenceDetailDTO evidence : caseEvidenceDetailDTOList) {
if (evidence.getUpdateStatus().equals("1")){
// 新增
CaseEvidence caseEvidence = evidence.toCaseEvidence();
caseEvidence.setProcessStatus(EvidenceConstants.PROCESS_STATUS_UNPROCESSED);
this.save(caseEvidence);
for (EvidenceFileDTO evidenceFileDTO : evidence.getFileList()) {
if (evidenceFileDTO.getUpdateStatus().equals("1")){
// 新增
EvidenceFile evidenceFile = new EvidenceFile(caseEvidence.getId(), evidenceFileDTO.getFileId());
evidenceFile.setDirectoryId(evidence.getDirectoryId());
evidenceFile.setRank(evidenceFileDTO.getRank());
evidenceFile.setBatchNo(batchNo);
evidenceFileService.save(evidenceFile);
}/*else if (evidenceFileDTO.getUpdateStatus().equals("0")){
// 删除
evidenceFileService.lambdaUpdate()
.eq(EvidenceFile::getEvidenceId, evidenceFileDTO.getEvidenceId())
.eq(EvidenceFile::getFileId, evidenceFileDTO.getFileId()).remove();
}else if (evidenceFileDTO.getUpdateStatus().equals("2")){
evidenceFileService.lambdaUpdate()
.set(EvidenceFile::getRank, evidenceFileDTO.getRank())
.update();
}*/
}
}/*else if (evidence.getUpdateStatus().equals("0")){
// 删除
this.removeById(evidence.getId());
evidenceFileService.lambdaUpdate().eq(EvidenceFile::getEvidenceId, evidence.getId()).remove();
}*/
}
return batchNo;
}
@Override
public List<EvidenceProcessDTO> listOcrAndExtract(String caseId,String batchNo) {
Assert.notEmpty(caseId, "案件id不能为空");
ModelCase modelCase = modelCaseService.getById(caseId);
Assert.notNull(modelCase, "案件不存在");
List<CaseEvidenceDetailDTO> caseEvidenceDetailDTOS = this.queryEvidenceList(caseId,batchNo);
if (CollUtil.isEmpty(caseEvidenceDetailDTOS)){
return new ArrayList<>();
}
List<EvidenceProcessDTO> processDTOList = caseEvidenceDetailDTOS.stream().map(EvidenceProcessDTO::new).collect(Collectors.toList());
List<EvidenceDirectoryDTO> evidenceDirectoryDTOS = evidenceDirectoryService.listDirectoryTree(caseId);
List<EvidenceCategory> categoryList = evidenceCategoryService.lambdaQuery().eq(EvidenceCategory::getCaseType, modelCase.getCaseType()).list();
for (EvidenceProcessDTO evidenceProcessDTO : processDTOList) {
evidenceProcessDTO.setTemplateInfo(evidenceDirectoryDTOS, categoryList);
}
return processDTOList;
}
@Override
public void verifyEvidence(List<EvidenceVerifyDTO> evidenceVerifyDTOS,String caseId,String batchNo) {
Assert.notEmpty(caseId, "案件id不能为空");
if (CollUtil.isEmpty(evidenceVerifyDTOS)){
return;
}
List<CaseEvidenceDetailDTO> caseEvidenceDetailDTOS = queryEvidenceList(caseId,batchNo);
Map<String, List<EvidenceVerifyDTO>> evidenceMap = evidenceVerifyDTOS.stream().collect(Collectors.groupingBy(EvidenceVerifyDTO::getEvidenceId));
for (Map.Entry<String, List<EvidenceVerifyDTO>> entry : evidenceMap.entrySet()) {
String evidenceId = entry.getKey();
List<EvidenceVerifyDTO> value = entry.getValue();
// 更新证据属性
this.lambdaUpdate().eq(CaseEvidence::getId, evidenceId).set(CaseEvidence::getProperty, CollUtil.getFirst(value).getProperties());
// 修改ocr内容
for (EvidenceVerifyDTO verifyDTO : value) {
if (StrUtil.isNotEmpty(verifyDTO.getOcrText())){
fileOcrProcessService.lambdaUpdate()
.eq(FileOcrProcess::getFileId, verifyDTO.getFileId())
.set(FileOcrProcess::getReviseText, verifyDTO.getOcrText()).update();
}
}
// 调整顺序
CaseEvidenceDetailDTO evidenceDetail = findEvidenceDetail(evidenceId, caseEvidenceDetailDTOS);
if (evidenceDetail != null){
List<String> list = value.stream().map(EvidenceVerifyDTO::getFileId).toList();
for (EvidenceFileDTO evidenceFileDTO : evidenceDetail.getFileList()) {
evidenceFileDTO.setRank(findRank(list, evidenceFileDTO.getFileId()));
evidenceFileService.lambdaUpdate().eq(EvidenceFile::getFileId, evidenceFileDTO.getFileId())
.eq(EvidenceFile::getEvidenceId, evidenceFileDTO.getEvidenceId())
.set(EvidenceFile::getRank, evidenceFileDTO.getRank()).update();
}
}
}
}
@Override
public List<EvidenceDirectoryDTO> evidenceDetails(String caseId, String batchNo) {
List<EvidenceDirectoryDTO> evidenceDirectoryDTOS = listFileTree(caseId);
List<CaseEvidence> caseEvidenceList = this.lambdaQuery().eq(CaseEvidence::getCaseId, caseId).list();
List<CategoryPromptDTO> categoryPromptDTOS = evidenceDirectoryService.listCategoryPrompt(caseId);
Map<String, CaseEvidence> caseEvidenceMap = caseEvidenceList.stream().collect(Collectors.toMap(CaseEvidence::getId, Function.identity()));
Map<String, CategoryPromptDTO> categoryPromptMap = categoryPromptDTOS.stream().collect(Collectors.toMap(CategoryPromptDTO::getDirectoryId, Function.identity()));
for (EvidenceDirectoryDTO evidenceDirectoryDTO : evidenceDirectoryDTOS) {
if (CollUtil.isEmpty(evidenceDirectoryDTO.getFileInfoList())){
continue;
}
for (EvidenceFileDTO evidenceFileDTO : evidenceDirectoryDTO.getFileInfoList()) {
evidenceFileDTO.setPrompt(categoryPromptMap.get(evidenceFileDTO.getDirectoryId()));
evidenceFileDTO.setEvidenceInfo(caseEvidenceMap.get(evidenceFileDTO.getEvidenceId()));
}
}
return evidenceDirectoryDTOS;
}
@Override
public String generateDirectoryName(String caseId, String categoryId, String provider) {
Assert.notEmpty(caseId, "案件id不能为空");
Assert.notEmpty(categoryId, "目录id不能为空");
Assert.notEmpty(provider, "提供方不能为空");
EvidenceCategory category = evidenceCategoryService.getById(categoryId);
Assert.notNull(category, "目录不存在");
List<EvidenceDirectory> directoryList = evidenceDirectoryService.lambdaQuery()
.eq(EvidenceDirectory::getCaseId, caseId)
.eq(EvidenceDirectory::getCategoryId, categoryId).list();
String directoryName = category.getCategoryName() + provider;
long count = directoryList.stream().filter(d -> StrUtil.contains(d.getDirectoryName(), provider)).count();
if (count > 0){
directoryName = directoryName + count;
}
return directoryName;
}
@Override
public EvidenceDirectory createDirectory(EvidenceDirectoryReqVO evidenceDirectory) {
List<EvidenceDirectoryDTO> evidenceDirectoryDTOS = listDirectoryTree(evidenceDirectory.getCaseId());
List<String> directoryIdList = null;
for (EvidenceDirectoryDTO evidenceDirectoryDTO : evidenceDirectoryDTOS) {
directoryIdList = evidenceDirectoryDTO.findDirectoryIdList(evidenceDirectory.getCategoryId());
if (CollUtil.isNotEmpty(directoryIdList)){
break;
}
}
Assert.notEmpty(directoryIdList, "目录分类不存在");
EvidenceDirectoryDTO directory = null;
for (EvidenceDirectoryDTO evidenceDirectoryDTO : evidenceDirectoryDTOS) {
directory = evidenceDirectoryDTO.findDirectory(CollUtil.getFirst(directoryIdList));
if (null != directory){
break;
}
}
Assert.notNull(directory, "目录不存在");
long count = evidenceDirectoryService.lambdaQuery().eq(EvidenceDirectory::getParentId, directory.getId())
.list().stream()
.filter(d -> StrUtil.contains(d.getDirectoryName(), evidenceDirectory.getDirectoryName())).count();
if (count > 0){
evidenceDirectory.setDirectoryName(evidenceDirectory.getDirectoryName() + count + 1);
}
EvidenceDirectory directory1 = new EvidenceDirectory();
directory1.setCaseId(evidenceDirectory.getCaseId());
directory1.setCategoryId(evidenceDirectory.getCategoryId());
directory1.setDirectoryName(evidenceDirectory.getDirectoryName());
directory1.setParentId(directory.getId());
evidenceDirectoryService.save(directory1);
return directory1;
}
private CaseEvidenceDetailDTO findEvidenceDetail(String evidenceId, List<CaseEvidenceDetailDTO> caseEvidenceDetailDTOS) {
for (CaseEvidenceDetailDTO caseEvidenceDetailDTO : caseEvidenceDetailDTOS) {
if (StrUtil.equals(caseEvidenceDetailDTO.getId(), evidenceId)){
return caseEvidenceDetailDTO;
}
}
return null;
}
private List<CaseEvidenceDetailDTO> toCaseCaseEvidenceDetailDTO(List<EvidenceDirectoryDTO> newDirectoryDTOS,
List<EvidenceDirectoryDTO> evidenceDirectoryDTOS) {
if (CollUtil.isEmpty(newDirectoryDTOS)){
return new ArrayList<>();
}
List<String> fileIdList = newDirectoryDTOS.stream().flatMap(directoryDTO -> directoryDTO.listAllFileId().stream()).toList();
Map<String, MinioFile> fileMap = minioService.listMinioFile(fileIdList).stream()
.collect(Collectors.toMap(MinioFile::getId, Function.identity()));
List<EvidenceDirectoryDTO> floatNewDirectoryDTOS = newDirectoryDTOS.stream().flatMap(directoryDTO -> directoryDTO.listAllDirectory().stream()).toList();
List<CaseEvidenceDetailDTO> caseEvidenceDetailDTOS = new ArrayList<>();
for (EvidenceDirectoryDTO evidenceFile : floatNewDirectoryDTOS) {
String directoryId = evidenceFile.getId();
EvidenceDirectoryDTO directory = evidenceDirectoryService.findDirectoryById(directoryId, evidenceDirectoryDTOS);
if (null == directory){
log.warn("toCaseCaseEvidenceDetailDTO:目录id{}不存在对应的目录分类信息",directoryId);
continue;
}
if (directory.getLevel() == 2){
for (String fileId : evidenceFile.getFileIdList()) {
CaseEvidenceDetailDTO caseEvidenceDetailDTO = new CaseEvidenceDetailDTO();
if (null != fileMap.get(fileId)){
// 证据名为文件名
caseEvidenceDetailDTO.setEvidenceName(fileMap.get(fileId).getFilename());
}
caseEvidenceDetailDTO.setEvidenceType(directory.getCategoryId());
caseEvidenceDetailDTO.setDirectoryId(directoryId);
EvidenceFileDTO evidenceFileDTO = new EvidenceFileDTO();
evidenceFileDTO.setFileId(fileId);
caseEvidenceDetailDTO.setFileList(List.of(evidenceFileDTO));
caseEvidenceDetailDTOS.add(caseEvidenceDetailDTO);
}
}
if (directory.getLevel() == 3){
CaseEvidenceDetailDTO caseEvidenceDetailDTO = new CaseEvidenceDetailDTO();
// 证据名为目录名
caseEvidenceDetailDTO.setEvidenceName(evidenceFile.getDirectoryName());
caseEvidenceDetailDTO.setEvidenceType(directory.getCategoryId());
caseEvidenceDetailDTO.setDirectoryId(directoryId);
List<EvidenceFileDTO> evidenceFileDTOS = new ArrayList<>();
for (String fileId : evidenceFile.getFileIdList()) {
EvidenceFileDTO evidenceFileDTO = new EvidenceFileDTO();
evidenceFileDTO.setFileId(fileId);
evidenceFileDTOS.add(evidenceFileDTO);
}
caseEvidenceDetailDTO.setFileList(evidenceFileDTOS);
caseEvidenceDetailDTOS.add(caseEvidenceDetailDTO);
}
}
return caseEvidenceDetailDTOS;
}
/**
* 查找发生改变的证据
* @param oldEvidenceList 旧证据列表
* @param newEvidenceFileList 新证据列表
* @return 发生改变的证据
*/
private List<CaseEvidenceDetailDTO> findChangedEvidence(List<CaseEvidenceDetailDTO> oldEvidenceList,
List<CaseEvidenceDetailDTO> newEvidenceFileList) {
List<CaseEvidenceDetailDTO> caseEvidence2DTOList = new ArrayList<>();
if (CollUtil.isEmpty(oldEvidenceList) && CollUtil.isNotEmpty(newEvidenceFileList)){
// 数据库中不存在数据,则全部新增
for (CaseEvidenceDetailDTO evidenceDetailDTO : newEvidenceFileList) {
List<String> fileIds = evidenceDetailDTO.getFileList().stream().map(EvidenceFileDTO::getFileId).toList();
evidenceDetailDTO.setUpdateStatus("1");
for (EvidenceFileDTO evidenceFileDTO : evidenceDetailDTO.getFileList()) {
evidenceFileDTO.setUpdateStatus("1");
evidenceFileDTO.setRank(findRank(fileIds,evidenceFileDTO.getFileId()));
}
}
caseEvidence2DTOList.addAll(newEvidenceFileList);
}
if (CollUtil.isNotEmpty(oldEvidenceList) && CollUtil.isEmpty(newEvidenceFileList)){
// 数据库中存在数据,没有新增数据
for (CaseEvidenceDetailDTO evidenceDetailDTO : oldEvidenceList) {
evidenceDetailDTO.setUpdateStatus("0");
for (EvidenceFileDTO evidenceFileDTO : evidenceDetailDTO.getFileList()) {
evidenceFileDTO.setUpdateStatus("0");
}
}
caseEvidence2DTOList.addAll(oldEvidenceList);
}
if (CollUtil.isNotEmpty(oldEvidenceList) && CollUtil.isNotEmpty(newEvidenceFileList)){
// 数据库中和新数据都存在
for (CaseEvidenceDetailDTO oldEvidence : oldEvidenceList) {
boolean isFind = false;
for (CaseEvidenceDetailDTO newEvidence : newEvidenceFileList) {
if (StrUtil.equals(oldEvidence.getId(),newEvidence.getId())){
isFind = true;
oldEvidence.setUpdateStatus("-1");
List<String> oldFileIds = oldEvidence.getFileList().stream().map(EvidenceFileDTO::getFileId).toList();
List<String> newFileIds = newEvidence.getFileList().stream().map(EvidenceFileDTO::getFileId).toList();
TupleIdRecord tupleIdRecord = compareFileList(oldFileIds, newFileIds);
List<EvidenceFileDTO> updateFileList = new ArrayList<>();
// 新增的文件顺序排在原有文件的后面
int initOrder = oldFileIds.size() -1;
for (String addFileId : tupleIdRecord.addFileList) {
EvidenceFileDTO evidenceFileDTO = new EvidenceFileDTO();
evidenceFileDTO.setFileId(addFileId);
evidenceFileDTO.setUpdateStatus("1");
evidenceFileDTO.setRank(initOrder + findRank(newFileIds, addFileId));
updateFileList.add(evidenceFileDTO);
}
for (String deleteFileId : tupleIdRecord.deleteFileList) {
EvidenceFileDTO evidenceFileDTO = new EvidenceFileDTO();
evidenceFileDTO.setFileId(deleteFileId);
evidenceFileDTO.setUpdateStatus("0");
evidenceFileDTO.setRank(findRank(oldFileIds, deleteFileId));
updateFileList.add(evidenceFileDTO);
}
for (String updateFileId : tupleIdRecord.updateFileList) {
EvidenceFileDTO evidenceFileDTO = new EvidenceFileDTO();
evidenceFileDTO.setFileId(updateFileId);
evidenceFileDTO.setUpdateStatus("2");
evidenceFileDTO.setRank(findRank(oldFileIds, updateFileId));
updateFileList.add(evidenceFileDTO);
}
newEvidence.setFileList(updateFileList);
caseEvidence2DTOList.add(newEvidence);
}
}
if (!isFind){
oldEvidence.setUpdateStatus("0");
caseEvidence2DTOList.add(oldEvidence);
}
}
for (CaseEvidenceDetailDTO newEvidence : newEvidenceFileList) {
if (StrUtil.isEmpty(newEvidence.getId())){
newEvidence.setUpdateStatus("1");
List<String> newFileIds = newEvidence.getFileList().stream().map(EvidenceFileDTO::getFileId).toList();
for (EvidenceFileDTO evidenceFileDTO : newEvidence.getFileList()) {
evidenceFileDTO.setUpdateStatus("1");
evidenceFileDTO.setRank(findRank(newFileIds, evidenceFileDTO.getFileId()));
}
caseEvidence2DTOList.add(newEvidence);
}
}
}
return caseEvidence2DTOList;
}
private int findRank(List<String> newFileIds,String fileId){
for (int i = 0; i < newFileIds.size(); i++) {
if (newFileIds.get(i).equals(fileId)){
return i;
}
}
return -1;
}
/**
* 初始化案件证据目录
* @param evidenceCategoryDTOS 证据分类
* @param caseId 案件id
* @param parentId 父级目录id
*/
private void initCaseEvidenceDirectory(List<EvidenceCategoryDTO> evidenceCategoryDTOS, String caseId, String parentId) {
for (EvidenceCategoryDTO evidenceCategoryDTO : evidenceCategoryDTOS) {
EvidenceDirectory evidenceDirectory = new EvidenceDirectory();
evidenceDirectory.setCaseId(caseId);
evidenceDirectory.setDirectoryName(evidenceCategoryDTO.getCategoryName());
evidenceDirectory.setCategoryId(evidenceCategoryDTO.getId());
evidenceDirectory.setParentId(parentId);
evidenceDirectoryService.save(evidenceDirectory);
if (CollUtil.isNotEmpty(evidenceCategoryDTO.getChild())) {
initCaseEvidenceDirectory(evidenceCategoryDTO.getChild(), caseId, evidenceDirectory.getId());
}
}
}
/**
* left 新增 right 删除
* @param newFileIdList
* @param oldFileIdList
* @return
*/
private TupleIdRecord compareFileList(List<String> newFileIdList, List<String> oldFileIdList) {
List<String> addFileList = new ArrayList<>();
List<String> deleteFileList = new ArrayList<>();
List<String> updateFileList = new ArrayList<>();
if (CollUtil.isEmpty(oldFileIdList) && CollUtil.isNotEmpty(newFileIdList)){
addFileList = newFileIdList;
}
if (CollUtil.isNotEmpty(oldFileIdList) && CollUtil.isEmpty(newFileIdList)){
deleteFileList = oldFileIdList;
}
if (CollUtil.isNotEmpty(oldFileIdList) && CollUtil.isNotEmpty(newFileIdList)){
deleteFileList = oldFileIdList.stream().filter(fileId -> !newFileIdList.contains(fileId)).collect(Collectors.toList());
addFileList = newFileIdList.stream().filter(fileId -> !oldFileIdList.contains(fileId)).collect(Collectors.toList());
updateFileList = oldFileIdList.stream().filter(newFileIdList::contains).collect(Collectors.toList());
}
return new TupleIdRecord(addFileList,updateFileList, deleteFileList);
}
record TupleIdRecord(List<String> addFileList ,List<String> updateFileList, List<String> deleteFileList){}
}