diff --git a/src/main/java/com/supervision/police/controller/CaseEvidenceController.java b/src/main/java/com/supervision/police/controller/CaseEvidenceController.java
index ab7d153..20be9dd 100644
--- a/src/main/java/com/supervision/police/controller/CaseEvidenceController.java
+++ b/src/main/java/com/supervision/police/controller/CaseEvidenceController.java
@@ -12,6 +12,7 @@ import com.supervision.police.vo.VerifyEvidenceReqVO;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.servlet.http.HttpServletResponse;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
@@ -193,4 +194,9 @@ public class CaseEvidenceController {
         return R.ok("success");
     }
 
+    @GetMapping("/downloadEvidence")
+    public void downloadEvidence(@RequestParam String evidenceId, HttpServletResponse response) {
+        caseEvidenceService.downloadEvidence(evidenceId, response);
+    }
+
 }
diff --git a/src/main/java/com/supervision/police/service/CaseEvidenceService.java b/src/main/java/com/supervision/police/service/CaseEvidenceService.java
index 7c7749a..31ac6ab 100644
--- a/src/main/java/com/supervision/police/service/CaseEvidenceService.java
+++ b/src/main/java/com/supervision/police/service/CaseEvidenceService.java
@@ -10,6 +10,7 @@ import com.supervision.police.dto.*;
 import com.supervision.police.vo.EvidenceDirectoryReqVO;
 import com.supervision.police.vo.VerifyEvidenceReqVO;
 
+import jakarta.servlet.http.HttpServletResponse;
 import java.util.List;
 import java.util.Map;
 
@@ -163,4 +164,6 @@ public interface CaseEvidenceService  extends IService<CaseEvidence> {
     void updateEvidenceAppendProcessingNewTransaction(String evidenceId, String status,String appendProcessing);
 
     void redoExtractAttributes(String caseId, List<CaseEvidence> caseEvidences);
+
+    void downloadEvidence(String evidenceId, HttpServletResponse response);
 }
diff --git a/src/main/java/com/supervision/police/service/impl/CaseEvidenceServiceImpl.java b/src/main/java/com/supervision/police/service/impl/CaseEvidenceServiceImpl.java
index 586f19f..23f481c 100644
--- a/src/main/java/com/supervision/police/service/impl/CaseEvidenceServiceImpl.java
+++ b/src/main/java/com/supervision/police/service/impl/CaseEvidenceServiceImpl.java
@@ -23,6 +23,8 @@ import com.supervision.police.mapper.CaseEvidenceMapper;
 import com.supervision.police.service.*;
 import com.supervision.police.vo.EvidenceDirectoryReqVO;
 import com.supervision.police.vo.VerifyEvidenceReqVO;
+import com.supervision.utils.ZipFileUtil;
+import jakarta.servlet.http.HttpServletResponse;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.aop.framework.AopContext;
@@ -32,6 +34,8 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;
 import java.util.*;
@@ -45,17 +49,11 @@ import java.util.stream.Stream;
 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 LLMExtractService llmExtractService;
     @Autowired
@@ -79,11 +77,11 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
         CaseEvidence caseEvidence = caseEvidenceDTO.toCaseEvidence();
         super.save(caseEvidence);
 
-        if (CollUtil.isNotEmpty(caseEvidence.getProperty())){
+        if (CollUtil.isNotEmpty(caseEvidence.getProperty())) {
             // 同时保存证据属性值
             EvidenceDirectoryDTO rootDirectory = new EvidenceDirectoryDTO(evidenceDirectoryService.listDirectoryTree(caseEvidence.getCaseId()));
             EvidenceDirectoryDTO directory = rootDirectory.findDirectory(caseEvidence.getDirectoryId());
-            caseEvidencePropertyService.saveEvidenceProperty(caseEvidence.getId(),directory.getCategoryId(),caseEvidence.getProperty());
+            caseEvidencePropertyService.saveEvidenceProperty(caseEvidence.getId(), directory.getCategoryId(), caseEvidence.getProperty());
         }
 
 
@@ -121,11 +119,11 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
         // 更新证据属性
         EvidenceDirectoryDTO rootDirectory = new EvidenceDirectoryDTO(evidenceDirectoryService.listDirectoryTree(caseEvidence.getCaseId()));
         EvidenceDirectoryDTO directory = rootDirectory.findDirectory(caseEvidence.getDirectoryId());
-        if (null != directory && StrUtil.isNotEmpty(directory.getCategoryId())){
-            if (CollUtil.isNotEmpty(caseEvidence.getProperty())){
-                caseEvidencePropertyService.updateEvidenceProperty(caseEvidence.getId(),directory.getCategoryId(),caseEvidence.getProperty());
-            }else {
-                caseEvidencePropertyService.deleteEvidenceProperty(caseEvidence.getId(),directory.getCategoryId());
+        if (null != directory && StrUtil.isNotEmpty(directory.getCategoryId())) {
+            if (CollUtil.isNotEmpty(caseEvidence.getProperty())) {
+                caseEvidencePropertyService.updateEvidenceProperty(caseEvidence.getId(), directory.getCategoryId(), caseEvidence.getProperty());
+            } else {
+                caseEvidencePropertyService.deleteEvidenceProperty(caseEvidence.getId(), directory.getCategoryId());
             }
         }
 
@@ -178,7 +176,7 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
     @Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class)
     public boolean batchDeleteEvidence(List<EvidenceIdWrapper> wrappers) {
 
-        if (CollUtil.isEmpty(wrappers)){
+        if (CollUtil.isEmpty(wrappers)) {
             return true;
         }
         List<String> evidenceIds = wrappers.stream().map(EvidenceIdWrapper::getEvidenceId).toList();
@@ -250,7 +248,7 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
             caseEvidenceDetailDTO.setContentTypeValue(recordFileDTOS);
             EvidenceDirectoryDTO directory = rootDirectory.findDirectory(caseEvidence.getDirectoryId());
             caseEvidenceDetailDTO.setEvidenceFormatValue(directory);
-            if (null != queryDirectory && queryDirectory.getLevel() == 3 && StrUtil.isNotEmpty(caseEvidence.getFileName())){
+            if (null != queryDirectory && queryDirectory.getLevel() == 3 && StrUtil.isNotEmpty(caseEvidence.getFileName())) {
                 caseEvidenceDetailDTO.setEvidenceName(caseEvidence.getFileName().split("\\.")[0]);
             }
             caseEvidenceDetailDTO.setDirectoryNamePath(StrUtil.join("/", rootDirectory.getDirectoryPath(caseEvidence.getDirectoryId())));
@@ -370,7 +368,7 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
             caseEvidence.setProcessStatus(EvidenceConstants.PROCESS_STATUS_SUCCESS);
             updateById(caseEvidence);
         } catch (Exception e) {
-            log.error("证据:【{}】解析失败。更新证据处理状态为【处理失败】。",evidenceId, e);
+            log.error("证据:【{}】解析失败。更新证据处理状态为【处理失败】。", evidenceId, e);
             caseEvidence.setProcessStatus(EvidenceConstants.PROCESS_STATUS_FAILED);
             updateById(caseEvidence);
         } finally {
@@ -380,20 +378,21 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
 
     /**
      * 校验属性值格式是否正确
+     *
      * @param extract 属性信息
      * @return 校验结果
      */
-    private boolean checkExtractAttributes(NotePromptExtractAttributesDto extract){
-        if (null ==  extract){
+    private boolean checkExtractAttributes(NotePromptExtractAttributesDto extract) {
+        if (null == extract) {
             return false;
         }
         String attrValueType = extract.getAttrValueType();
-        if (StrUtil.equals(attrValueType, IndexRuleConstants.VALUE_TYPE_DATE)){ // 日期
+        if (StrUtil.equals(attrValueType, IndexRuleConstants.VALUE_TYPE_DATE)) { // 日期
             try {
                 new SimpleDateFormat("yyyy-MM-dd").parse(extract.getAttrValue());
                 return true;
             } catch (Exception e) {
-                log.error("属性:{},日期:{}格式错误", extract.getAttrName(),extract.getAttrValue(),e);
+                log.error("属性:{},日期:{}格式错误", extract.getAttrName(), extract.getAttrValue(), e);
                 return false;
             }
         }
@@ -462,7 +461,7 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
         List<EvidenceCategoryDTO> evidenceCategoryTree = evidenceCategoryService.listCategoryTree(caseType);
         List<EvidenceDirectoryDTO> evidenceDirectoryTree = evidenceDirectoryService.listDirectoryTree(caseId);
 
-        initCaseEvidenceDirectory(evidenceCategoryTree,evidenceDirectoryTree,caseId, null);
+        initCaseEvidenceDirectory(evidenceCategoryTree, evidenceDirectoryTree, caseId, null);
     }
 
     @Override
@@ -495,17 +494,17 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
                 ((CaseEvidenceService) AopContext.currentProxy()).doReplaceEvidence(modelCase, allEvidence, catagroyMap, allFile);
                 successCount++;
             } catch (Exception e) {
-                log.error("案件{}的目录初始化失败。案件id:{}", modelCase.getCaseName(), modelCase.getId(),e);
+                log.error("案件{}的目录初始化失败。案件id:{}", modelCase.getCaseName(), modelCase.getId(), e);
                 errorCount++;
             }
             index += 1;
-            log.info("案件【{}】的目录初始化完成。耗时:{}秒,占总体进度:{}%", modelCase.getCaseName(),interval.intervalSecond(modelCase.getId()),index/(list.size()*1.0)*100);
+            log.info("案件【{}】的目录初始化完成。耗时:{}秒,占总体进度:{}%", modelCase.getCaseName(), interval.intervalSecond(modelCase.getId()), index / (list.size() * 1.0) * 100);
         }
-        log.info("<<<<=======初始化案件的证据目录完成。案件总条数:{},总耗时:{}秒,成功个数:{},失败个数:{}", list.size(),interval.intervalSecond(),successCount,errorCount);
+        log.info("<<<<=======初始化案件的证据目录完成。案件总条数:{},总耗时:{}秒,成功个数:{},失败个数:{}", list.size(), interval.intervalSecond(), successCount, errorCount);
 
     }
 
-    @Transactional(rollbackFor = Exception.class, transactionManager = "dataSourceTransactionManager",propagation = Propagation.REQUIRES_NEW)
+    @Transactional(rollbackFor = Exception.class, transactionManager = "dataSourceTransactionManager", propagation = Propagation.REQUIRES_NEW)
     public void doReplaceEvidence(ModelCase modelCase, List<CaseEvidence> allEvidence, Map<String, String> catagroyMap, List<EvidenceFile> allFile) {
         String caseType = modelCase.getCaseType();
         String id = modelCase.getId();
@@ -517,28 +516,28 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
         log.info("案件{}证据总数:{}", modelCase.getCaseName(), evidenceList.size());
         for (CaseEvidence caseEvidence : evidenceList) {
             String directoryId = caseEvidence.getDirectoryId();
-            if (StrUtil.isNotEmpty(directoryId)){
-                log.warn("证据id:{},证据名:{},已经存在目录id:{},不进行目录绑定操作",caseEvidence.getId(),caseEvidence.getEvidenceName(),directoryId);
+            if (StrUtil.isNotEmpty(directoryId)) {
+                log.warn("证据id:{},证据名:{},已经存在目录id:{},不进行目录绑定操作", caseEvidence.getId(), caseEvidence.getEvidenceName(), directoryId);
                 continue;
             }
 
-            if (StrUtil.equalsAny(caseEvidence.getEvidenceType(), "3","6")){
-                log.warn("证据id:{},证据名:{},证据类型为【{}】,清除无用数据",caseEvidence.getId(),caseEvidence.getEvidenceName(),caseEvidence.getEvidenceType());
+            if (StrUtil.equalsAny(caseEvidence.getEvidenceType(), "3", "6")) {
+                log.warn("证据id:{},证据名:{},证据类型为【{}】,清除无用数据", caseEvidence.getId(), caseEvidence.getEvidenceName(), caseEvidence.getEvidenceType());
                 super.removeById(caseEvidence.getId());
                 continue;
             }
-            if (!catagroyMap.containsKey(caseEvidence.getEvidenceType())){
-                log.warn("证据id:{},证据名:{},证据类型为【{}】,没有对应的目录,请检查目录配置",caseEvidence.getId(),caseEvidence.getEvidenceName(),caseEvidence.getEvidenceType());
+            if (!catagroyMap.containsKey(caseEvidence.getEvidenceType())) {
+                log.warn("证据id:{},证据名:{},证据类型为【{}】,没有对应的目录,请检查目录配置", caseEvidence.getId(), caseEvidence.getEvidenceName(), caseEvidence.getEvidenceType());
                 continue;
             }
 
-            if (StrUtil.isEmpty(caseEvidence.getEvidenceType())){
-                log.warn("证据id:{},证据名:{},证据类型不能为空,默认为书证",caseEvidence.getId(),caseEvidence.getEvidenceName());
+            if (StrUtil.isEmpty(caseEvidence.getEvidenceType())) {
+                log.warn("证据id:{},证据名:{},证据类型不能为空,默认为书证", caseEvidence.getId(), caseEvidence.getEvidenceName());
                 caseEvidence.setEvidenceType("1");
             }
             EvidenceDirectoryDTO topDirectory = findTopDirectory(rootDirectory, catagroyMap.get(caseEvidence.getEvidenceType()));
-            if (null == topDirectory){
-                log.warn("证据id:{},证据名:{},证据类型为【{}】,在根目录下没有对应的目录,请检查目录配置",caseEvidence.getId(),caseEvidence.getEvidenceName(),caseEvidence.getEvidenceType());
+            if (null == topDirectory) {
+                log.warn("证据id:{},证据名:{},证据类型为【{}】,在根目录下没有对应的目录,请检查目录配置", caseEvidence.getId(), caseEvidence.getEvidenceName(), caseEvidence.getEvidenceType());
                 continue;
             }
             caseEvidence.setDirectoryId(topDirectory.getId());
@@ -550,24 +549,24 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
             for (EvidenceFile file : files) {
                 evidenceFileService.updateById(file);
                 MinioFile minioFile = minioFileMap.get(file.getFileId());
-                if (null == minioFile){
-                    log.warn("证据id:{},证据名:{},文件id:{}不存在minio上传信息", caseEvidence.getId(),caseEvidence.getEvidenceName(),file.getFileId());
+                if (null == minioFile) {
+                    log.warn("证据id:{},证据名:{},文件id:{}不存在minio上传信息", caseEvidence.getId(), caseEvidence.getEvidenceName(), file.getFileId());
                     continue;
                 }
-                fileOcrProcessService.multipleTypeOcrProcess(List.of(file.getFileId()),minioFile.getFileType());
+                fileOcrProcessService.multipleTypeOcrProcess(List.of(file.getFileId()), minioFile.getFileType());
             }
 
         }
     }
 
     private EvidenceDirectoryDTO findTopDirectory(EvidenceDirectoryDTO rootDirectory, String categoryId) {
-        if (StrUtil.equals(rootDirectory.getCategoryId(), categoryId)){
+        if (StrUtil.equals(rootDirectory.getCategoryId(), categoryId)) {
             return rootDirectory;
         }
-        if (CollUtil.isNotEmpty(rootDirectory.getChild())){
+        if (CollUtil.isNotEmpty(rootDirectory.getChild())) {
             for (EvidenceDirectoryDTO child : rootDirectory.getChild()) {
                 EvidenceDirectoryDTO directory = findTopDirectory(child, categoryId);
-                if (directory != null){
+                if (directory != null) {
                     return directory;
                 }
             }
@@ -664,11 +663,11 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
     public void syncEvidenceAnalysis(List<CaseEvidenceDetailDTO> evidenceList) {
 
         List<EvidenceFileDTO> ocrFileDTOList = evidenceList.stream().filter(
-                // 当前证据下不是所有文件都是新增
-                        evidenceDetail-> !evidenceDetail.getFileList().stream().allMatch(file -> StrUtil.equalsAny(file.getUpdateStatus(), "1", "-1"))
+                        // 当前证据下不是所有文件都是新增
+                        evidenceDetail -> !evidenceDetail.getFileList().stream().allMatch(file -> StrUtil.equalsAny(file.getUpdateStatus(), "1", "-1"))
                 )
                 .flatMap(evidenceDetailDTO -> evidenceDetailDTO.getFileList().stream().filter(file -> StrUtil.equals(file.getUpdateStatus(), "1"))).toList();
-        if (CollUtil.isNotEmpty(ocrFileDTOList)){
+        if (CollUtil.isNotEmpty(ocrFileDTOList)) {
             // 在已经存在的目录下追加文件,只需要重新及进行ocr识别
             log.info("ocrAndExtract:开始只进行文件内容识别...");
             Map<String, List<EvidenceFileDTO>> evidenceMap = ocrFileDTOList.stream().collect(Collectors.groupingBy(EvidenceFileDTO::getEvidenceId));
@@ -678,17 +677,17 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
                 // 首先统一更新为正在处理
                 CaseEvidence one = this.lambdaQuery().eq(CaseEvidence::getId, evidenceId).one();
 
-                updateEvidenceAppendProcessingNewTransaction(evidenceId,one.getProcessStatus(),"1");
+                updateEvidenceAppendProcessingNewTransaction(evidenceId, one.getProcessStatus(), "1");
             }
             for (Map.Entry<String, List<EvidenceFileDTO>> entry : evidenceMap.entrySet()) {
 
                 String evidenceId = entry.getKey();
                 List<EvidenceFileDTO> value = entry.getValue();
                 for (EvidenceFileDTO evidenceFileDTO : value) {
-                    fileOcrProcessService.multipleTypeOcrProcess(List.of(evidenceFileDTO.getFileId()),evidenceFileDTO.getFileType());
+                    fileOcrProcessService.multipleTypeOcrProcess(List.of(evidenceFileDTO.getFileId()), evidenceFileDTO.getFileType());
                 }
                 log.info("ocrAndExtract:证据:{} 文件内容识别完成", evidenceId);
-                updateEvidenceAppendProcessingNewTransaction(evidenceId,EvidenceConstants.PROCESS_STATUS_SUCCESS,"0");
+                updateEvidenceAppendProcessingNewTransaction(evidenceId, EvidenceConstants.PROCESS_STATUS_SUCCESS, "0");
             }
         }
 
@@ -707,10 +706,10 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
     }
 
     @Override
-    @Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
-    public void updateEvidenceAppendProcessingNewTransaction(String evidenceId, String status,String appendProcessing) {
+    @Transactional(transactionManager = "dataSourceTransactionManager", rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
+    public void updateEvidenceAppendProcessingNewTransaction(String evidenceId, String status, String appendProcessing) {
         this.lambdaUpdate().eq(CaseEvidence::getId, evidenceId)
-                .set(StrUtil.isNotEmpty(status),CaseEvidence::getProcessStatus, status)
+                .set(StrUtil.isNotEmpty(status), CaseEvidence::getProcessStatus, status)
                 .set(CaseEvidence::getAppendProcessing, appendProcessing)
                 .set(CaseEvidence::getUpdateTime, LocalDateTime.now()).update();
     }
@@ -829,10 +828,10 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
             // 同时更新证据属性值
             String categoryId = rootDirectory.findDirectory(CollUtil.getFirst(value).getDirectoryId()).getCategoryId();
             Map<String, List<NotePromptExtractAttributesDto>> map = caseEvidencePropertyService.listEvidenceProperty(categoryId, Collections.singletonList(evidenceId));
-            if (CollUtil.isEmpty(map.get(categoryId))){
-                caseEvidencePropertyService.saveEvidenceProperty(evidenceId, categoryId,CollUtil.getFirst(value).getProperties());
-            }else {
-                caseEvidencePropertyService.updateEvidenceProperty(evidenceId, categoryId,CollUtil.getFirst(value).getProperties());
+            if (CollUtil.isEmpty(map.get(categoryId))) {
+                caseEvidencePropertyService.saveEvidenceProperty(evidenceId, categoryId, CollUtil.getFirst(value).getProperties());
+            } else {
+                caseEvidencePropertyService.updateEvidenceProperty(evidenceId, categoryId, CollUtil.getFirst(value).getProperties());
             }
 
 
@@ -850,7 +849,7 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
             if (evidenceDetail != null) {
                 List<EvidenceFileDTO> fileList = evidenceDetail.getFileList();
                 int initOrder = 0;
-                if (StrUtil.isNotEmpty(batchNo) && !CollUtil.isNotEmpty(fileList)){
+                if (StrUtil.isNotEmpty(batchNo) && !CollUtil.isNotEmpty(fileList)) {
                     // 如果批次不为空,则只对当前批次的文件进行排序
                     initOrder = fileList.size();
                 }
@@ -913,7 +912,7 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
         rebuildEvidenceProperties(rootDirectory, caseEvidenceList);
 
         List<CategoryPromptDTO> categoryPromptDTOS = evidenceDirectoryService.listCategoryPrompt(caseId);
-        Map<String, CaseEvidenceDTO> caseEvidenceMap = caseEvidenceList.stream().map(CaseEvidenceDTO::new).peek(e->e.setDirectoryNamePathValue(rootDirectory)).collect(Collectors.toMap(CaseEvidenceDTO::getId, Function.identity()));
+        Map<String, CaseEvidenceDTO> caseEvidenceMap = caseEvidenceList.stream().map(CaseEvidenceDTO::new).peek(e -> e.setDirectoryNamePathValue(rootDirectory)).collect(Collectors.toMap(CaseEvidenceDTO::getId, Function.identity()));
         Map<String, CategoryPromptDTO> categoryPromptMap = categoryPromptDTOS.stream().collect(Collectors.toMap(CategoryPromptDTO::getDirectoryId, k -> k, (v1, v2) -> v1));
 
         Iterator<EvidenceDirectoryDTO> iterator = evidenceDirectoryDTOS.iterator();
@@ -936,7 +935,7 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
         Map<String, List<String>> categoryMapEvidence = new HashMap<>();
         for (CaseEvidence caseEvidence : caseEvidences) {
             EvidenceDirectoryDTO directory = rootDirectory.findDirectory(caseEvidence.getDirectoryId());
-            if (null != directory && StrUtil.isNotEmpty(directory.getCategoryId())){
+            if (null != directory && StrUtil.isNotEmpty(directory.getCategoryId())) {
                 List<String> evidenceIds = categoryMapEvidence.getOrDefault(directory.getCategoryId(), new ArrayList<>());
                 evidenceIds.add(caseEvidence.getId());
                 categoryMapEvidence.put(directory.getCategoryId(), evidenceIds);
@@ -950,15 +949,33 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
         for (CaseEvidence caseEvidence : caseEvidences) {
             List<NotePromptExtractAttributesDto> attributesDtos = map.get(caseEvidence.getId());
             // 兼容老数据
-            if (CollUtil.isNotEmpty(attributesDtos)){
+            if (CollUtil.isNotEmpty(attributesDtos)) {
                 caseEvidence.setProperty(attributesDtos);
             }
         }
     }
 
+    @Override
+    public void downloadEvidence(String evidenceId, HttpServletResponse response) {
+        List<EvidenceFileDTO> evidenceFileDTOList = evidenceFileService.listFileInfo(List.of(evidenceId));
+        Map<String, InputStream> fileInputStreamMap = new HashMap<>();
+        evidenceFileDTOList.forEach(evidenceFileDTO -> {
+            MinioFile minioFile = minioService.getMinioFile(evidenceFileDTO.getFileId());
+            if (null != minioFile) {
+                fileInputStreamMap.put(minioFile.getFilename(), minioService.getObjectInputStream(minioFile));
+            }
+        });
+        try {
+            ZipFileUtil.createZipAndDownload(response, getById(evidenceId).getEvidenceName(), fileInputStreamMap);
+        } catch (IOException e) {
+            log.error("下载证据文件失败", e);
+        }
+    }
+
     /**
      * 重新构建证据属性数据
-     * @param rootDirectory 根目录
+     *
+     * @param rootDirectory    根目录
      * @param caseEvidenceList 案件证据列表
      */
     private void rebuildEvidenceProperties(EvidenceDirectoryDTO rootDirectory, List<CaseEvidence> caseEvidenceList) {
@@ -966,33 +983,33 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
         Map<String, String> directoryIdMapCategoryId = caseEvidenceList.stream()
                 .filter(e -> StrUtil.isNotEmpty(e.getDirectoryId()) && null != rootDirectory.findDirectory(e.getDirectoryId()))
                 .map(CaseEvidence::getDirectoryId).distinct().collect(
-                        Collectors.toMap(directoryId -> directoryId,di-> rootDirectory.findDirectory(di).getCategoryId()));
+                        Collectors.toMap(directoryId -> directoryId, di -> rootDirectory.findDirectory(di).getCategoryId()));
 
         Map<String, List<NotePromptExtractAttributesDto>> categoryIdMapExtractAttributes = new HashMap<>();
         for (CaseEvidence caseEvidence : caseEvidenceList) {
             EvidenceDirectoryDTO directory = rootDirectory.findDirectory(caseEvidence.getDirectoryId());
-            if (null == directory || StrUtil.isEmpty(directory.getCategoryId())){
+            if (null == directory || StrUtil.isEmpty(directory.getCategoryId())) {
                 continue;
             }
             String categoryId = directory.getCategoryId();
-            if (!categoryIdMapExtractAttributes.containsKey(categoryId)){
+            if (!categoryIdMapExtractAttributes.containsKey(categoryId)) {
                 categoryIdMapExtractAttributes.put(categoryId, caseEvidencePropertyService.findExtractAttributes(categoryId));
             }
         }
 
 
         for (CaseEvidence caseEvidence : caseEvidenceList) {
-            if (StrUtil.isEmpty(caseEvidence.getDirectoryId())){
+            if (StrUtil.isEmpty(caseEvidence.getDirectoryId())) {
                 continue;
             }
             String categoryId = directoryIdMapCategoryId.get(caseEvidence.getDirectoryId());
-            if (StrUtil.isEmpty(categoryId)){
+            if (StrUtil.isEmpty(categoryId)) {
                 continue;
             }
 
             List<NotePromptExtractAttributesDto> merged = mergeExtractAttributes(caseEvidence.getProperty(), categoryIdMapExtractAttributes.get(categoryId));
 
-            if (null != merged){
+            if (null != merged) {
                 merged = merged.stream().filter(Objects::nonNull).peek(e -> {
                     if (!checkExtractAttributes(e)) {
                         e.setAttrValue(null);
@@ -1006,13 +1023,13 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
     }
 
     private List<NotePromptExtractAttributesDto> mergeExtractAttributes(List<NotePromptExtractAttributesDto> property, List<NotePromptExtractAttributesDto> attributesTemplates) {
-        if (CollUtil.isEmpty(attributesTemplates) || CollUtil.isEmpty(property)){
+        if (CollUtil.isEmpty(attributesTemplates) || CollUtil.isEmpty(property)) {
             return attributesTemplates;
         }
         for (NotePromptExtractAttributesDto attributesTemplate : attributesTemplates) {
             String attrName = attributesTemplate.getAttrName();
             for (NotePromptExtractAttributesDto attributesDto : property) {
-                if (StrUtil.equals(attributesDto.getAttrName(), attrName)){
+                if (StrUtil.equals(attributesDto.getAttrName(), attrName)) {
                     attributesTemplate.setAttrValue(attributesDto.getAttrValue());
                     break;
                 }
@@ -1184,7 +1201,7 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
     /**
      * 查找发生改变的证据
      *
-     * @param oldEvidenceList     旧证据列表
+     * @param oldEvidenceList 旧证据列表
      * @param newEvidenceList 新证据列表
      * @return 发生改变的证据
      */
@@ -1321,18 +1338,19 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
      */
     /**
      * 初始化案件证据目录
-     * @param evidenceCategoryTree 证据分类树
-     * @param evidenceDirectoryTree  父级目录树
-     * @param caseId  案件id
-     * @param parentId 父目录id
+     *
+     * @param evidenceCategoryTree  证据分类树
+     * @param evidenceDirectoryTree 父级目录树
+     * @param caseId                案件id
+     * @param parentId              父目录id
      */
-    private void initCaseEvidenceDirectory(List<EvidenceCategoryDTO> evidenceCategoryTree, List<EvidenceDirectoryDTO> evidenceDirectoryTree,String caseId,String parentId) {
-        if (null == evidenceDirectoryTree){
+    private void initCaseEvidenceDirectory(List<EvidenceCategoryDTO> evidenceCategoryTree, List<EvidenceDirectoryDTO> evidenceDirectoryTree, String caseId, String parentId) {
+        if (null == evidenceDirectoryTree) {
             evidenceDirectoryTree = new ArrayList<>(1);
         }
         for (EvidenceCategoryDTO evidenceCategoryDTO : evidenceCategoryTree) {
             List<EvidenceDirectoryDTO> directoryDTOS = evidenceDirectoryTree.stream().filter(evidenceDirectoryDTO -> evidenceDirectoryDTO.getCategoryId().equals(evidenceCategoryDTO.getId())).toList();
-            if (CollUtil.isEmpty(directoryDTOS)){
+            if (CollUtil.isEmpty(directoryDTOS)) {
                 EvidenceDirectory evidenceDirectory = new EvidenceDirectory();
                 evidenceDirectory.setCaseId(caseId);
                 evidenceDirectory.setDirectoryName(evidenceCategoryDTO.getCategoryName());
@@ -1346,7 +1364,7 @@ public class CaseEvidenceServiceImpl extends ServiceImpl<CaseEvidenceMapper, Cas
 
             EvidenceDirectoryDTO parentDTO = CollUtil.getFirst(directoryDTOS);
             if (CollUtil.isNotEmpty(evidenceCategoryDTO.getChild())) {
-                initCaseEvidenceDirectory(evidenceCategoryDTO.getChild(),parentDTO.getChild(),caseId,parentDTO.getId());
+                initCaseEvidenceDirectory(evidenceCategoryDTO.getChild(), parentDTO.getChild(), caseId, parentDTO.getId());
             }
         }
     }
diff --git a/src/main/java/com/supervision/police/service/impl/ChatServiceImpl.java b/src/main/java/com/supervision/police/service/impl/ChatServiceImpl.java
index a70ac13..e01b5fb 100644
--- a/src/main/java/com/supervision/police/service/impl/ChatServiceImpl.java
+++ b/src/main/java/com/supervision/police/service/impl/ChatServiceImpl.java
@@ -193,6 +193,7 @@ public class ChatServiceImpl implements ChatService {
         chatResVO.setAnswwerMap(answerMap);
         chatResVO.setType(type);
         chatResVO.setIntentType(intentType);
+        chatResVO.setConversationId(chatReqVO.getConversationId());
         return chatResVO;
     }
 
@@ -270,7 +271,7 @@ public class ChatServiceImpl implements ChatService {
                         atomicIndexDTO.getEvidentResultList().forEach(evidentIndexResultDTO -> {
                             Map<String, String> evidenceMap = new HashMap<>();
                             evidenceMap.put("evidenceName", evidentIndexResultDTO.getEvidenceName());
-                            evidenceMap.put("evidenceId", evidentIndexResultDTO.getIndexId());
+                            evidenceMap.put("evidenceId", evidentIndexResultDTO.getEvidenceId());
                             evidenceList.add(evidenceMap);
                         });
                     }
diff --git a/src/main/java/com/supervision/police/vo/ChatResVO.java b/src/main/java/com/supervision/police/vo/ChatResVO.java
index f33728f..87da635 100644
--- a/src/main/java/com/supervision/police/vo/ChatResVO.java
+++ b/src/main/java/com/supervision/police/vo/ChatResVO.java
@@ -23,7 +23,7 @@ public class ChatResVO {
     private String question;
 
     private Date questionTime;
-
+    private String conversationId;
     private String answer;
     private Map<String, Object> answwerMap;
     private String type;
diff --git a/src/main/java/com/supervision/utils/CalculationUtil.java b/src/main/java/com/supervision/utils/CalculationUtil.java
index 83b5afb..79ebd98 100644
--- a/src/main/java/com/supervision/utils/CalculationUtil.java
+++ b/src/main/java/com/supervision/utils/CalculationUtil.java
@@ -52,13 +52,38 @@ public class CalculationUtil {
         // 初始化SpEL解析器
         ExpressionParser parser = new SpelExpressionParser();
         StandardEvaluationContext context = new StandardEvaluationContext();
-        context.setVariable("leftOperand", leftOperand);
-        context.setVariable("rightOperand", rightOperand);
+        // 判断并转换变量类型
+        Object leftValue = parseOperand(leftOperand);
+        Object rightValue = parseOperand(rightOperand);
+        context.setVariable("leftOperand", leftValue);
+        context.setVariable("rightOperand", rightValue);
 
         // 计算结果
         return Boolean.TRUE.equals(parser.parseExpression(expression).getValue(context, Boolean.class));
     }
 
+    /**
+     * 辅助方法:动态解析操作数类型
+     *
+     * @param operand 操作数
+     * @return 解析结果
+     */
+    private static Object parseOperand(String operand) {
+        if (operand == null) {
+            return null;
+        }
+        try {
+            // 尝试解析为数字(支持整数和小数)
+            if (operand.contains(".")) {
+                return Double.valueOf(operand);
+            } else {
+                return Integer.valueOf(operand);
+            }
+        } catch (NumberFormatException e) {
+            // 如果解析失败,返回原始字符串
+            return operand;
+        }
+    }
 
     /**
      * 计算布尔值集合的逻辑运算结果
diff --git a/src/main/java/com/supervision/utils/ZipFileUtil.java b/src/main/java/com/supervision/utils/ZipFileUtil.java
new file mode 100644
index 0000000..6df7a9e
--- /dev/null
+++ b/src/main/java/com/supervision/utils/ZipFileUtil.java
@@ -0,0 +1,39 @@
+package com.supervision.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import jakarta.servlet.http.HttpServletResponse;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+@Slf4j
+@Component
+public class ZipFileUtil {
+
+    public static void createZipAndDownload(HttpServletResponse response, String zipFileName, Map<String, InputStream> fileInputStreamMap) throws IOException {
+        response.setHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(zipFileName, StandardCharsets.UTF_8) + ".zip");
+        response.setContentType("application/zip");
+        try (BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
+             ZipOutputStream zipOut = new ZipOutputStream(bos)) {
+            for (Map.Entry<String, InputStream> entry : fileInputStreamMap.entrySet()) {
+                InputStream inputStream = entry.getValue();
+                zipOut.putNextEntry(new ZipEntry(entry.getKey()));
+                byte[] buffer = new byte[1024];
+                int length;
+                while ((length = inputStream.read(buffer)) >= 0) {
+                    zipOut.write(buffer, 0, length);
+                }
+                zipOut.closeEntry();
+                inputStream.close();
+            }
+            zipOut.finish();
+        }
+    }
+}