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 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 queryEvidenceList(String caseId) { return super.getBaseMapper().queryEvidenceList(caseId); } @Override @Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class) public List queryEvidenceList(String caseId, String batchNo) { List caseEvidenceDetailDTOS = queryEvidenceList(caseId); if (StrUtil.isNotEmpty(batchNo)){ for (CaseEvidenceDetailDTO evidenceDetail : caseEvidenceDetailDTOS) { List 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 pageListEvidence(String caseId, String directoryId,String evidenceName, Integer pageNum, Integer pageSize) { Assert.notEmpty(caseId, "案件id不能为空"); Page 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 evidenceIds = caseEvidencePage.getRecords().stream().map(CaseEvidence::getId).distinct().toList(); List fileInfoList = evidenceFileService.listFileInfo(evidenceIds); Map> evidenceFileMap = fileInfoList.stream().collect(Collectors.groupingBy(EvidenceFileDTO::getEvidenceId)); List recordFileDTOS = fileOcrProcessService.queryFileList(fileInfoList.stream().map(EvidenceFileDTO::getFileId).toList()); List evidenceDirectoryDTOS = listDirectoryTree(caseId); // 转换分页结果 //查询字典 List 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 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 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 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("证据解析失败。更新证据处理状态为【处理失败】。"); caseEvidence.setProcessStatus(EvidenceConstants.PROCESS_STATUS_FAILED); updateById(caseEvidence); } finally { log.info("证据解析完成。证据ID:【{}】耗时:【{}】ms", evidenceId, System.currentTimeMillis() - start); } } @Override public List listCategoryTree(String caseType) { Assert.notEmpty(caseType,"案件类型不能为空!"); return evidenceCategoryService.listCategoryTree(caseType); } @Override public List listFileTree(String caseId) { Assert.notEmpty(caseId,"案件ID不能为空!"); List evidenceDirectoryDTOS = evidenceDirectoryService.listDirectoryTree(caseId); evidenceDirectoryService.appendFile(evidenceDirectoryDTOS, evidenceFileService.listFileInfoByCaseId(caseId)); return evidenceDirectoryDTOS; } @Override public List listDirectoryTree(String caseId) { Assert.notEmpty(caseId,"案件ID不能为空!"); return evidenceDirectoryService.listDirectoryTree(caseId); } @Override public void initCaseEvidenceDirectory(String caseId, String caseType) { List 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 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 evidenceFileDTOS) { List oldEvidences = this.queryEvidenceList(caseId); List evidenceDirectoryDTOS = listFileTree(caseId); List newEvidences = toCaseCaseEvidenceDetailDTO(evidenceFileDTOS, evidenceDirectoryDTOS); newEvidences.forEach(caseEvidenceDetailDTO -> caseEvidenceDetailDTO.setCaseId(caseId)); List 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 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 listOcrAndExtract(String caseId,String batchNo) { Assert.notEmpty(caseId, "案件id不能为空"); ModelCase modelCase = modelCaseService.getById(caseId); Assert.notNull(modelCase, "案件不存在"); List caseEvidenceDetailDTOS = this.queryEvidenceList(caseId,batchNo); if (CollUtil.isEmpty(caseEvidenceDetailDTOS)){ return new ArrayList<>(); } List processDTOList = caseEvidenceDetailDTOS.stream().map(EvidenceProcessDTO::new).collect(Collectors.toList()); List evidenceDirectoryDTOS = evidenceDirectoryService.listDirectoryTree(caseId); List categoryList = evidenceCategoryService.lambdaQuery().eq(EvidenceCategory::getCaseType, modelCase.getCaseType()).list(); for (EvidenceProcessDTO evidenceProcessDTO : processDTOList) { evidenceProcessDTO.setTemplateInfo(evidenceDirectoryDTOS, categoryList); } return processDTOList; } @Override public void verifyEvidence(List evidenceVerifyDTOS,String caseId,String batchNo) { Assert.notEmpty(caseId, "案件id不能为空"); if (CollUtil.isEmpty(evidenceVerifyDTOS)){ return; } List caseEvidenceDetailDTOS = queryEvidenceList(caseId,batchNo); Map> evidenceMap = evidenceVerifyDTOS.stream().collect(Collectors.groupingBy(EvidenceVerifyDTO::getEvidenceId)); for (Map.Entry> entry : evidenceMap.entrySet()) { String evidenceId = entry.getKey(); List 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 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 evidenceDetails(String caseId, String batchNo) { List evidenceDirectoryDTOS = listFileTree(caseId); List caseEvidenceList = this.lambdaQuery().eq(CaseEvidence::getCaseId, caseId).list(); List categoryPromptDTOS = evidenceDirectoryService.listCategoryPrompt(caseId); Map caseEvidenceMap = caseEvidenceList.stream().collect(Collectors.toMap(CaseEvidence::getId, Function.identity())); Map 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 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 evidenceDirectoryDTOS = listDirectoryTree(evidenceDirectory.getCaseId()); List 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 caseEvidenceDetailDTOS) { for (CaseEvidenceDetailDTO caseEvidenceDetailDTO : caseEvidenceDetailDTOS) { if (StrUtil.equals(caseEvidenceDetailDTO.getId(), evidenceId)){ return caseEvidenceDetailDTO; } } return null; } private List toCaseCaseEvidenceDetailDTO(List newDirectoryDTOS, List evidenceDirectoryDTOS) { if (CollUtil.isEmpty(newDirectoryDTOS)){ return new ArrayList<>(); } List fileIdList = newDirectoryDTOS.stream().flatMap(directoryDTO -> directoryDTO.listAllFileId().stream()).toList(); Map fileMap = minioService.listMinioFile(fileIdList).stream() .collect(Collectors.toMap(MinioFile::getId, Function.identity())); List floatNewDirectoryDTOS = newDirectoryDTOS.stream().flatMap(directoryDTO -> directoryDTO.listAllDirectory().stream()).toList(); List 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 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 findChangedEvidence(List oldEvidenceList, List newEvidenceFileList) { List caseEvidence2DTOList = new ArrayList<>(); if (CollUtil.isEmpty(oldEvidenceList) && CollUtil.isNotEmpty(newEvidenceFileList)){ // 数据库中不存在数据,则全部新增 for (CaseEvidenceDetailDTO evidenceDetailDTO : newEvidenceFileList) { List 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 oldFileIds = oldEvidence.getFileList().stream().map(EvidenceFileDTO::getFileId).toList(); List newFileIds = newEvidence.getFileList().stream().map(EvidenceFileDTO::getFileId).toList(); TupleIdRecord tupleIdRecord = compareFileList(oldFileIds, newFileIds); List 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 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 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 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 newFileIdList, List oldFileIdList) { List addFileList = new ArrayList<>(); List deleteFileList = new ArrayList<>(); List 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 addFileList ,List updateFileList, List deleteFileList){} }