Ver Fonte

fix:优化邮件附件处理逻辑

wangzaijun há 2 semanas atrás
pai
commit
4b9a093b56

+ 5 - 6
mo-daq/src/main/java/com/smppw/modaq/application/api/ParseApi.java

@@ -7,7 +7,6 @@ import com.smppw.modaq.domain.dto.UploadReportParams;
 import com.smppw.modaq.domain.dto.UploadReportResult;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
-import org.springframework.web.multipart.MultipartFile;
 
 import java.util.Date;
 import java.util.List;
@@ -34,11 +33,11 @@ public class ParseApi {
         return ResponseEntity.ok("success");
     }
 
-    @GetMapping("reparse")
-    public ResponseEntity<String> reparseReport(Integer emailId) {
-        this.service.reparseEmail(emailId);
-        return ResponseEntity.ok("success");
-    }
+//    @GetMapping("reparse")
+//    public ResponseEntity<String> reparseReport(Integer emailId) {
+//        this.service.reparseEmail(emailId);
+//        return ResponseEntity.ok("success");
+//    }
 
     @PostMapping("upload-parse")
     public ResponseEntity<List<UploadReportResult>> uploadReport(@RequestBody UploadReportParams params) {

+ 6 - 6
mo-daq/src/main/java/com/smppw/modaq/application/service/EmailParseApiService.java

@@ -25,12 +25,12 @@ public interface EmailParseApiService {
      */
     void parseEmail(MailboxInfoDTO mailboxInfoDTO, Date startDate, Date endDate, List<String> folderNames, List<Integer> emailTypes);
 
-    /**
-     * 重新解析指定邮件
-     *
-     * @param emailId 邮件id
-     */
-    void reparseEmail(Integer emailId);
+//    /**
+//     * 重新解析指定邮件
+//     *
+//     * @param emailId 邮件id
+//     */
+//    void reparseEmail(Integer emailId);
 //
 //
 //    /**

+ 40 - 44
mo-daq/src/main/java/com/smppw/modaq/application/service/EmailParseApiServiceImpl.java

@@ -2,13 +2,10 @@ package com.smppw.modaq.application.service;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateUtil;
-import cn.hutool.core.exceptions.ExceptionUtil;
-import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import com.smppw.modaq.application.util.EmailUtil;
 import com.smppw.modaq.common.conts.DateConst;
 import com.smppw.modaq.domain.dto.EmailContentInfoDTO;
-import com.smppw.modaq.domain.dto.EmailZipFileDTO;
 import com.smppw.modaq.domain.dto.MailboxInfoDTO;
 import com.smppw.modaq.domain.entity.EmailFileInfoDO;
 import com.smppw.modaq.domain.entity.EmailParseInfoDO;
@@ -26,7 +23,6 @@ import java.io.FileReader;
 import java.io.IOException;
 import java.util.Date;
 import java.util.List;
-import java.util.Map;
 
 /**
  * @author mozuwen
@@ -130,46 +126,46 @@ public class EmailParseApiServiceImpl implements EmailParseApiService {
 //        return emailTaskInfoDO;
 //    }
 
-    @Override
-    public void reparseEmail(Integer emailId) {
-        // 查询邮件信息
-        EmailParseInfoDO emailParseInfoDO = emailParseInfoMapper.queryById(emailId);
-        if (emailParseInfoDO == null) {
-            log.info("邮件不存在 ->邮件id:{}", emailId);
-            return;
-        }
-        //解析成功的邮件不再解析
-        if (emailParseInfoDO.getParseStatus() == 1) {
-            log.info("邮件解析状态为成功,不再解析 ->邮件id:{}", emailId);
-            return;
-        }
-        List<EmailFileInfoDO> emailFileInfoDOList = emailFileInfoMapper.queryByEmailId(emailId);
-        if (CollUtil.isEmpty(emailFileInfoDOList)) {
-            log.info("该邮件不存在附件 -> 邮件id:{}", emailId);
-            return;
-        }
-//        // 邮件字段识别映射表
-//        Map<String, List<String>> emailFieldMap = emailParseService.getEmailFieldMapping();
-//        // 邮件类型配置
-//        Map<Integer, List<String>> emailTypeMap = emailParseService.getEmailType();
-
-        // 解析流程
-        List<EmailContentInfoDTO> emailContentInfoDTOList = buildEmailContentInfoDTO(emailId, emailParseInfoDO, emailFileInfoDOList);
-
-//        List<EmailFundNavDTO> emailFundNavDTOList = CollUtil.newArrayList();
-        Map<EmailContentInfoDTO, List<EmailZipFileDTO>> emailZipFileMap = MapUtil.newHashMap();
-        for (EmailContentInfoDTO emailContentInfoDTO : emailContentInfoDTOList) {
-            try {
-                List<EmailZipFileDTO> emailZipFiles = emailParseService.parseZipEmail(emailContentInfoDTO);
-                emailZipFileMap.put(emailContentInfoDTO, emailZipFiles);
-//                    emailFundNavDTOList.addAll(fundNavDTOList);
-            } catch (Exception e) {
-                log.error("重新解析邮件失败,邮件id:{},堆栈信息:{}", emailId, ExceptionUtil.stacktraceToString(e));
-            }
-        }
-        // 保存相关信息 -> 邮件信息表,邮件文件表,邮件净值表,邮件规模表,基金净值表
-        emailParseService.saveRelatedTable(null, emailParseInfoDO.getEmail(), emailZipFileMap);
-    }
+//    @Override
+//    public void reparseEmail(Integer emailId) {
+//        // 查询邮件信息
+//        EmailParseInfoDO emailParseInfoDO = emailParseInfoMapper.queryById(emailId);
+//        if (emailParseInfoDO == null) {
+//            log.info("邮件不存在 ->邮件id:{}", emailId);
+//            return;
+//        }
+//        //解析成功的邮件不再解析
+//        if (emailParseInfoDO.getParseStatus() == 1) {
+//            log.info("邮件解析状态为成功,不再解析 ->邮件id:{}", emailId);
+//            return;
+//        }
+//        List<EmailFileInfoDO> emailFileInfoDOList = emailFileInfoMapper.queryByEmailId(emailId);
+//        if (CollUtil.isEmpty(emailFileInfoDOList)) {
+//            log.info("该邮件不存在附件 -> 邮件id:{}", emailId);
+//            return;
+//        }
+////        // 邮件字段识别映射表
+////        Map<String, List<String>> emailFieldMap = emailParseService.getEmailFieldMapping();
+////        // 邮件类型配置
+////        Map<Integer, List<String>> emailTypeMap = emailParseService.getEmailType();
+//
+//        // 解析流程
+//        List<EmailContentInfoDTO> emailContentInfoDTOList = buildEmailContentInfoDTO(emailId, emailParseInfoDO, emailFileInfoDOList);
+//
+////        List<EmailFundNavDTO> emailFundNavDTOList = CollUtil.newArrayList();
+//        Map<EmailContentInfoDTO, List<EmailZipFileDTO>> emailZipFileMap = MapUtil.newHashMap();
+//        for (EmailContentInfoDTO emailContentInfoDTO : emailContentInfoDTOList) {
+//            try {
+//                List<EmailZipFileDTO> emailZipFiles = emailParseService.parseZipEmail(emailContentInfoDTO);
+//                emailZipFileMap.put(emailContentInfoDTO, emailZipFiles);
+////                    emailFundNavDTOList.addAll(fundNavDTOList);
+//            } catch (Exception e) {
+//                log.error("重新解析邮件失败,邮件id:{},堆栈信息:{}", emailId, ExceptionUtil.stacktraceToString(e));
+//            }
+//        }
+//        // 保存相关信息 -> 邮件信息表,邮件文件表,邮件净值表,邮件规模表,基金净值表
+//        emailParseService.saveRelatedTable(null, emailParseInfoDO.getEmail(), emailZipFileMap);
+//    }
 //
 //    @Override
 //    public void reparseFile(List<Integer> fileIdList) {

+ 1 - 1
mo-daq/src/main/java/com/smppw/modaq/common/enums/ReportType.java

@@ -27,7 +27,7 @@ public enum ReportType {
             new String[]{"年度", "年报", "年度报告"}),
 
     WEEKLY(3, "周",
-            new String[]{"周报", "周度报告", "周度"}),
+            new String[]{"周报", "周度报告", "周度", "周总结"}),
     ;
 
     private final int type;

+ 5 - 9
mo-daq/src/main/java/com/smppw/modaq/domain/dto/EmailContentInfoDTO.java

@@ -74,10 +74,6 @@ public class EmailContentInfoDTO implements Serializable {
      */
     private int fileSize;
 
-    public String groupBy() {
-        return this.emailTitle + this.emailAddress + this.emailDate + this.senderEmail;
-    }
-
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
@@ -85,16 +81,16 @@ public class EmailContentInfoDTO implements Serializable {
         return Objects.equals(emailAddress, that.emailAddress)
                 && Objects.equals(emailTitle, that.emailTitle)
                 && Objects.equals(emailDate, that.emailDate)
-//                && Objects.equals(fileName, that.fileName)
-//                && Objects.equals(filePath, that.filePath)
-//                && Objects.equals(fileSize, that.fileSize)
-//                && Objects.equals(emailType, that.emailType)
+                && Objects.equals(fileName, that.fileName)
+                && Objects.equals(filePath, that.filePath)
+                && Objects.equals(fileSize, that.fileSize)
+                && Objects.equals(emailType, that.emailType)
                 && Objects.equals(senderEmail, that.senderEmail);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(emailAddress, emailTitle, emailDate, senderEmail);
+        return Objects.hash(emailAddress, emailTitle, emailDate, fileName, filePath, fileSize, emailType, senderEmail);
     }
 
     @Override

+ 25 - 26
mo-daq/src/main/java/com/smppw/modaq/domain/dto/EmailInfoDTO.java

@@ -1,46 +1,45 @@
 package com.smppw.modaq.domain.dto;
 
-import lombok.Data;
+import cn.hutool.core.collection.ListUtil;
+import lombok.Getter;
+import lombok.Setter;
 
-import java.util.Date;
+import java.util.List;
 
-@Data
+@Setter
+@Getter
 public class EmailInfoDTO {
     /**
-     * 邮件id
-     */
-    private Integer id;
-    /**
-     * 文件id
-     */
-    private Integer fileId;
-    /**
      * 邮箱地址
      */
-    private String email;
-    /**
-     * 邮箱日期
-     */
-    private Date emailDate;
+    private String emailAddress;
     /**
      * 邮件主题
      */
     private String emailTitle;
     /**
-     * 邮件类型,1-净值,2-估值表,3-定期报告
+     * 邮件日期:yyyyMMdd HH:mm:ss
      */
-    private Integer emailType;
+    private String emailDate;
     /**
-     * 解析状态
+     * 邮件发送人
      */
-    private Integer parseStatus;
+    private String senderEmail;
     /**
-     * 文件名称
+     * 当前邮件的所有附件信息(如果是压缩包则只记录解压后的文件)
      */
-    private String fileName;
+    private List<EmailZipFileDTO> emailFileList;
 
-    /**
-     * 文件地址
-     */
-    private String filePath;
+    public EmailInfoDTO() {
+        this.emailFileList = ListUtil.list(false);
+    }
+
+    public EmailInfoDTO(EmailContentInfoDTO emailDto, List<EmailZipFileDTO> emailFileList) {
+        this();
+        this.emailAddress = emailDto.getEmailAddress();
+        this.emailTitle = emailDto.getEmailTitle();
+        this.emailDate = emailDto.getEmailDate();
+        this.senderEmail = emailDto.getSenderEmail();
+        this.emailFileList = emailFileList;
+    }
 }

+ 127 - 153
mo-daq/src/main/java/com/smppw/modaq/domain/service/EmailParseService.java

@@ -25,6 +25,7 @@ import com.smppw.modaq.common.enums.ReportType;
 import com.smppw.modaq.common.exception.NotSupportReportException;
 import com.smppw.modaq.common.exception.ReportParseException;
 import com.smppw.modaq.domain.dto.EmailContentInfoDTO;
+import com.smppw.modaq.domain.dto.EmailInfoDTO;
 import com.smppw.modaq.domain.dto.EmailZipFileDTO;
 import com.smppw.modaq.domain.dto.MailboxInfoDTO;
 import com.smppw.modaq.domain.dto.report.OCRParseData;
@@ -144,23 +145,21 @@ public class EmailParseService {
                 log.warn("未采集到正文或附件");
                 continue;
             }
-            log.info("开始解析邮件数据 -> 邮件主题:{},邮件日期:{}",
-                    emailContentInfoDTOList.get(0).getEmailTitle(), emailContentInfoDTOList.get(0).getEmailDate());
-            Map<EmailContentInfoDTO, List<EmailZipFileDTO>> emailZipFileMap = MapUtil.newHashMap();
+            EmailContentInfoDTO dto = emailContentInfoDTOList.get(0);
+            String emailTitle = dto.getEmailTitle();
+            log.info("开始解析邮件数据 -> 邮件主题:{},邮件日期:{}", emailTitle, dto.getEmailDate());
+            List<EmailZipFileDTO> emailFileList = ListUtil.list(false);
+            EmailInfoDTO emailInfo = new EmailInfoDTO(dto, emailFileList);
             for (EmailContentInfoDTO emailDto : emailContentInfoDTOList) {
                 // 正文不用解压附件
-                if (emailDto.getFileName() != null && emailDto.getFileName().endsWith(".html")) {
-                    emailZipFileMap.put(emailDto, ListUtil.list(false));
+                if (emailDto.getFileName() != null && emailDto.getFileName().endsWith(Constants.FILE_HTML)) {
                     continue;
                 }
                 try {
-                    // 这里分组只用邮件的标题+发送人+接收人+发送时间
-                    List<EmailZipFileDTO> tempList = emailZipFileMap.getOrDefault(emailDto, ListUtil.list(false));
-                    tempList.addAll(this.parseZipEmail(emailDto));
-                    emailZipFileMap.put(emailDto, tempList);
+                    emailFileList.addAll(this.parseZipEmail(emailDto));
                 } catch (IOException e) {
                     log.error("压缩包解压失败:{}", ExceptionUtil.stacktraceToString(e));
-                    EmailParseInfoDO fail = buildEmailParseInfo(null, mailboxInfoDTO.getAccount(), emailDto, emailDto.getFileSize());
+                    EmailParseInfoDO fail = buildEmailParseInfo(mailboxInfoDTO.getAccount(), dto.getEmailType(), emailInfo, emailDto.getFileSize());
                     fail.setFailReason("压缩包解压失败");
                     fail.setParseStatus(EmailParseStatusConst.FAIL);
                     fail.setEmailKey(emailEntry.getKey());
@@ -169,35 +168,27 @@ public class EmailParseService {
                     log.error("堆栈信息:{}", ExceptionUtil.stacktraceToString(e));
                 }
             }
-
-            Iterator<Map.Entry<EmailContentInfoDTO, List<EmailZipFileDTO>>> entryIterator = emailZipFileMap.entrySet().iterator();
-            while (entryIterator.hasNext()) {
-                Map.Entry<EmailContentInfoDTO, List<EmailZipFileDTO>> entry = entryIterator.next();
-                EmailContentInfoDTO key = entry.getKey();
-                List<EmailZipFileDTO> dtos = entry.getValue();
-
-                List<Integer> types = ListUtil.list(false);
-                types.add(key.getEmailType());
-                if (CollUtil.isNotEmpty(dtos)) {
-                    List<Integer> list = dtos.stream().map(EmailZipFileDTO::getEmailType).distinct().toList();
-                    CollUtil.addAllIfNotContains(types, list);
+            // 重新判断类型
+            for (EmailZipFileDTO emailFile : emailFileList) {
+                if (EmailTypeConst.SUPPORT_NO_OTHER_TYPES.contains(emailFile.getEmailType())) {
+                    continue;
                 }
+                Integer type = EmailUtil.getEmailTypeBySubject(emailTitle + emailFile.getFilename());
+                emailFile.setEmailType(type);
+            }
 
-                boolean flag = false;
-                for (Integer type : types) {
-                    if (emailTypes.contains(type)) {
-                        flag = true;
-                        break;
-                    }
-                }
-                if (!flag) {
-                    log.warn("当前邮件{} 的类型{} 不在支持的任务类型{} 中,不用执行解析逻辑。", key, types, emailTypes);
+            Iterator<EmailZipFileDTO> entryIterator = emailFileList.iterator();
+            while (entryIterator.hasNext()) {
+                EmailZipFileDTO entry = entryIterator.next();
+                if (!emailTypes.contains(entry.getEmailType())) {
+                    log.warn("当前邮件{} 文件{} 的类型{} 不在支持的任务类型{} 中,不用执行解析逻辑。",
+                            entry.getEmailTitle(), entry.getFilepath(), entry.getEmailType(), emailTypes);
                     entryIterator.remove();
                 }
             }
 
             // 保存相关信息 -> 邮件信息表,邮件文件表,邮件净值表,邮件规模表,基金净值表
-            saveRelatedTable(emailEntry.getKey(), mailboxInfoDTO.getAccount(), emailZipFileMap);
+            saveRelatedTable(emailEntry.getKey(), mailboxInfoDTO.getAccount(), emailInfo);
             log.info("结束邮件解析 -> 邮箱信息:{},开始时间:{},结束时间:{}", emailEntry.getValue(),
                     DateUtil.format(startDate, DateConst.YYYY_MM_DD_HH_MM_SS), DateUtil.format(endDate, DateConst.YYYY_MM_DD_HH_MM_SS));
         }
@@ -287,125 +278,108 @@ public class EmailParseService {
         return path.getParent().resolve(baseName).toString();
     }
 
-    public void saveRelatedTable(String emailKey, String emailAddress,
-                                 Map<EmailContentInfoDTO, List<EmailZipFileDTO>> emailZipFileMap) {
-        // python 报告解析接口结果
-        List<ParseResult<ReportData>> dataList = ListUtil.list(false);
-        for (Map.Entry<EmailContentInfoDTO, List<EmailZipFileDTO>> entry : emailZipFileMap.entrySet()) {
-            EmailContentInfoDTO emailDto = entry.getKey();
-            if (emailDto.getFileName() != null && emailDto.getFileName().endsWith(Constants.FILE_HTML)) {
-                continue;
-            }
-            String emailTitle = emailDto.getEmailTitle();
+    public void saveRelatedTable(String emailKey, String emailAddress, EmailInfoDTO emailInfo) {
+        String emailTitle = emailInfo.getEmailTitle();
+        List<EmailZipFileDTO> dtos = emailInfo.getEmailFileList();
+        // 如果压缩包里面既有pdf又有其他格式的文件,说明其他格式的文件是不需要解析的
+        List<String> exts = dtos.stream().map(EmailZipFileDTO::getExtName).distinct().toList();
+        if (exts.contains(Constants.FILE_PDF) && exts.size() > 1) {
+            dtos.removeIf(e -> !Objects.equals(Constants.FILE_PDF, e.getExtName()));
+        }
+        // 移除逻辑
+        Iterator<EmailZipFileDTO> removeIterator = dtos.iterator();
+        while (removeIterator.hasNext()) {
+            EmailZipFileDTO dto = removeIterator.next();
+            String filename = dto.getFilename();
+            // 删除复核函或基金合同
+            if (filename.contains("复核函") || (filename.contains("基金合同") && !filename.contains("合同变更"))) {
+                log.warn("邮件{} 中的报告{} 是复核函或基金合同,不用解析上传。", emailTitle, filename);
+                removeIterator.remove();
+            }
+            // 不支持的类型
+            Integer type = dto.getEmailType();
+            if (!EmailTypeConst.SUPPORT_EMAIL_TYPES.contains(type)) {
+                log.info("邮件{} 类型{} 不支持解析。", emailTitle, type);
+                removeIterator.remove();
+            }
+        }
+        // 数据库已存在的数据过滤(邮件主题+报告名称+附件大小,压缩包文件大小汇总)
+        long totalSize = dtos.stream().map(EmailZipFileDTO::getFileSize).reduce(0L, Long::sum);
+        Iterator<EmailZipFileDTO> iterator = dtos.iterator();
+        while (iterator.hasNext()) {
+            EmailZipFileDTO dto = iterator.next();
+            String filename = dto.getFilename();
+            Integer type = dto.getEmailType();
+            int count = 0;
+            if (Objects.equals(type, EmailTypeConst.REPORT_LETTER_EMAIL_TYPE)) {
+                // 确认单
+                count = this.emailFileInfoMapper.getLetterFilenameSuccessCount(emailTitle, filename);
+            } else if (Objects.equals(type, EmailTypeConst.REPORT_EMAIL_TYPE)) {
+                // 定期报告
+                count = this.emailFileInfoMapper.getAmacFilenameSuccessCount(emailTitle, filename, totalSize);
+            } else if (Objects.equals(type, EmailTypeConst.REPORT_WEEKLY_TYPE)) {
+                // 管理人周报
+                count = this.emailFileInfoMapper.getWeeklyFilenameSuccessCount(emailTitle, filename, totalSize);
+            } else if (Objects.equals(type, EmailTypeConst.REPORT_OTHER_TYPE)) {
+                // 其他报告
+                count = this.emailFileInfoMapper.getOtherFilenameSuccessCount(emailTitle, filename, totalSize);
+            }
+            if (count > 0) {
+                iterator.remove();
+                log.info("邮件{} 报告{} 已存在解析成功的记录,不用重新解析。", emailTitle, filename);
+            }
+        }
+        if (CollUtil.isEmpty(dtos)) {
+            log.info("邮件{} 所有文件都已经解析成功过,不能重复解析了", emailTitle);
+            return;
+        }
+        if (log.isInfoEnabled()) {
+            log.info("邮件{} 还有报告待解析:\n{}", emailTitle, dtos);
+        }
+        // 解析并保存数据
+        this.parseAndSave(emailKey, emailAddress, emailInfo, totalSize);
+    }
 
-            // 待解析文件数据处理,不支持已存在的文件重复解析
-            List<EmailZipFileDTO> dtos = ListUtil.list(false);
-            List<EmailZipFileDTO> zipFiles = entry.getValue();
-            if (CollUtil.isEmpty(zipFiles)) {
-                dtos.add(new EmailZipFileDTO(emailTitle, emailDto));
-            } else {
-                dtos.addAll(zipFiles);
-                zipFiles.clear();
-            }
-            // 重新判断类型
-            for (EmailZipFileDTO dto : dtos) {
-                if (!EmailTypeConst.SUPPORT_NO_OTHER_TYPES.contains(dto.getEmailType())) {
-                    Integer emailType = EmailUtil.getEmailTypeBySubject(emailTitle + dto.getFilename());
-                    dto.setEmailType(emailType);
-                }
-            }
-            // 如果压缩包里面既有pdf又有其他格式的文件,说明其他格式的文件是不需要解析的
-            List<String> exts = dtos.stream().map(EmailZipFileDTO::getExtName).distinct().toList();
-            if (exts.contains(Constants.FILE_PDF) && exts.size() > 1) {
-                dtos.removeIf(e -> !Objects.equals(Constants.FILE_PDF, e.getExtName()));
-            }
-            // 移除逻辑
-            Iterator<EmailZipFileDTO> removeIterator = dtos.iterator();
-            while (removeIterator.hasNext()) {
-                EmailZipFileDTO dto = removeIterator.next();
-                String filename = dto.getFilename();
-                // 删除复核函或基金合同
-                if (filename.contains("复核函") || (filename.contains("基金合同") && !filename.contains("合同变更"))) {
-                    log.warn("邮件{} 中的报告{} 是复核函或基金合同,不用解析上传。", emailTitle, filename);
-                    removeIterator.remove();
-                }
-                // 不支持的类型
-                Integer emailType = dto.getEmailType();
-                if (!EmailTypeConst.SUPPORT_EMAIL_TYPES.contains(emailType)) {
-                    log.info("邮件{} 类型{} 不支持解析。", emailTitle, emailType);
-                    removeIterator.remove();
-                }
-            }
+    private void parseAndSave(String emailKey, String emailAddress, EmailInfoDTO emailInfo, long totalSize) {
+        String emailTitle = emailInfo.getEmailTitle();
+        List<EmailZipFileDTO> dtos = emailInfo.getEmailFileList();
+        // 保存邮件信息
+        Integer emailType = dtos.get(0).getEmailType();
+        EmailParseInfoDO emailParseInfoDO = this.buildEmailParseInfo(emailAddress, emailType, emailInfo, totalSize);
+        emailParseInfoDO.setEmailKey(emailKey);
+        Integer emailId = this.saveEmailParseInfo(emailParseInfoDO);
+        if (emailId == null) {
+            return;
+        }
+        // 解析邮件报告
+        List<ParseResult<ReportData>> dataList = ListUtil.list(false);
+        for (EmailZipFileDTO zipFile : dtos) {
+            EmailFileInfoDO emailFile = this.saveEmailFileInfo(emailId, zipFile.getFilename(), zipFile.getFilepath());
+            // 解析并保存报告
+            ParseResult<ReportData> parseResult = this.parseReportAndHandleResult(emailTitle, emailFile, zipFile);
+            dataList.add(parseResult);
+        }
 
-            // 数据库已存在的数据过滤(邮件主题+报告名称+附件大小,压缩包文件大小汇总)
-            long totalSize = dtos.stream().map(EmailZipFileDTO::getFileSize).reduce(0L, Long::sum);
-            Iterator<EmailZipFileDTO> iterator = dtos.iterator();
-            while (iterator.hasNext()) {
-                EmailZipFileDTO dto = iterator.next();
-                String filename = dto.getFilename();
-                Integer emailType = dto.getEmailType();
-                int count = 0;
-                if (Objects.equals(emailType, EmailTypeConst.REPORT_LETTER_EMAIL_TYPE)) {
-                    // 确认单
-                    count = this.emailFileInfoMapper.getLetterFilenameSuccessCount(emailTitle, filename);
-                } else if (Objects.equals(emailType, EmailTypeConst.REPORT_EMAIL_TYPE)) {
-                    // 定期报告
-                    count = this.emailFileInfoMapper.getAmacFilenameSuccessCount(emailTitle, filename, totalSize);
-                } else if (Objects.equals(emailType, EmailTypeConst.REPORT_WEEKLY_TYPE)) {
-                    // 管理人周报
-                    count = this.emailFileInfoMapper.getWeeklyFilenameSuccessCount(emailTitle, filename, totalSize);
-                } else if (Objects.equals(emailType, EmailTypeConst.REPORT_OTHER_TYPE)) {
-                    // 其他报告
-                    count = this.emailFileInfoMapper.getOtherFilenameSuccessCount(emailTitle, filename, totalSize);
-                }
-                if (count > 0) {
-                    iterator.remove();
-                    log.info("邮件{} 报告{} 已存在解析成功的记录,不用重新解析。", emailTitle, filename);
+        String failReason = null;
+        int emailParseStatus = EmailParseStatusConst.SUCCESS;
+        // 报告邮件有一条失败就表示整个邮件解析失败
+        if (CollUtil.isNotEmpty(dataList)) {
+            // ai解析结果
+            List<ReportData> aiParaseList = dataList.stream().map(ParseResult::getData)
+                    .filter(Objects::nonNull).filter(e -> Objects.equals(true, e.getAiParse())).toList();
+            if (CollUtil.isNotEmpty(aiParaseList)) {
+                for (ReportData data : aiParaseList) {
+                    this.emailFileInfoMapper.updateAiParseByFileId(data.getBaseInfo().getFileId(),
+                            data.getAiParse(), data.getAiFileId());
                 }
             }
-            if (CollUtil.isEmpty(dtos)) {
-                log.info("邮件{} 所有文件都已经解析成功过,不能重复解析了", emailTitle);
-                continue;
-            }
-            if (log.isInfoEnabled()) {
-                log.info("邮件{} 还有报告待解析:\n{}", emailTitle, dtos);
-            }
-
-            Integer emailId = emailDto.getEmailId();
-            EmailParseInfoDO emailParseInfoDO = this.buildEmailParseInfo(emailId, emailAddress, emailDto, totalSize);
-            emailParseInfoDO.setEmailKey(emailKey);
-            emailId = this.saveEmailParseInfo(emailParseInfoDO);
-            if (emailId == null) {
-                continue;
-            }
-            for (EmailZipFileDTO zipFile : dtos) {
-                EmailFileInfoDO emailFile = this.saveEmailFileInfo(emailId, zipFile.getFilename(), zipFile.getFilepath());
-                // 解析并保存报告
-                ParseResult<ReportData> parseResult = this.parseReportAndHandleResult(emailTitle, emailFile, zipFile);
-                dataList.add(parseResult);
-            }
-
-            String failReason = null;
-            int emailParseStatus = EmailParseStatusConst.SUCCESS;
-            // 报告邮件有一条失败就表示整个邮件解析失败
-            if (CollUtil.isNotEmpty(dataList)) {
-                // ai解析结果
-                List<ReportData> aiParaseList = dataList.stream().map(ParseResult::getData)
-                        .filter(Objects::nonNull).filter(e -> Objects.equals(true, e.getAiParse())).toList();
-                if (CollUtil.isNotEmpty(aiParaseList)) {
-                    for (ReportData data : aiParaseList) {
-                        this.emailFileInfoMapper.updateAiParseByFileId(data.getBaseInfo().getFileId(),
-                                data.getAiParse(), data.getAiFileId());
-                    }
-                }
-                long failNum = dataList.stream().filter(e -> !Objects.equals(EmailParseStatusConst.SUCCESS, e.getStatus())).count();
-                if (failNum > 0) {
-                    emailParseStatus = EmailParseStatusConst.FAIL;
-                    failReason = dataList.stream().map(ParseResult::getMsg).collect(Collectors.joining(";"));
-                }
+            long failNum = dataList.stream().filter(e -> !Objects.equals(EmailParseStatusConst.SUCCESS, e.getStatus())).count();
+            if (failNum > 0) {
+                emailParseStatus = EmailParseStatusConst.FAIL;
+                failReason = dataList.stream().map(ParseResult::getMsg).collect(Collectors.joining(";"));
             }
-            emailParseInfoMapper.updateParseStatus(emailId, emailParseStatus, failReason);
         }
+        this.emailParseInfoMapper.updateParseStatus(emailId, emailParseStatus, failReason);
     }
 
     private ParseResult<ReportData> parseReportAndHandleResult(String emailTitle,
@@ -725,16 +699,16 @@ public class EmailParseService {
         return emailParseInfoDO.getId();
     }
 
-    private EmailParseInfoDO buildEmailParseInfo(Integer emailId, String emailAddress,
-                                                 EmailContentInfoDTO emailDto, long totalSize) {
+    private EmailParseInfoDO buildEmailParseInfo(String emailAddress, Integer emailType,
+                                                 EmailInfoDTO emailInfo, long totalSize) {
         EmailParseInfoDO emailParseInfoDO = new EmailParseInfoDO();
-        emailParseInfoDO.setId(emailId);
-        emailParseInfoDO.setSenderEmail(emailDto.getSenderEmail());
+        emailParseInfoDO.setId(null);
+        emailParseInfoDO.setSenderEmail(emailInfo.getSenderEmail());
         emailParseInfoDO.setEmail(emailAddress);
-        emailParseInfoDO.setEmailDate(DateUtil.parse(emailDto.getEmailDate(), DateConst.YYYY_MM_DD_HH_MM_SS));
-        emailParseInfoDO.setParseDate(emailDto.getParseDate() == null ? new Date() : DateUtil.parseDate(emailDto.getParseDate()));
-        emailParseInfoDO.setEmailTitle(emailDto.getEmailTitle());
-        emailParseInfoDO.setEmailType(emailDto.getEmailType());
+        emailParseInfoDO.setEmailDate(DateUtil.parse(emailInfo.getEmailDate(), DateConst.YYYY_MM_DD_HH_MM_SS));
+        emailParseInfoDO.setParseDate(new Date());
+        emailParseInfoDO.setEmailTitle(emailInfo.getEmailTitle());
+        emailParseInfoDO.setEmailType(emailType);
         emailParseInfoDO.setParseStatus(EmailParseStatusConst.SUCCESS);
         emailParseInfoDO.setAttrSize(totalSize);
         emailParseInfoDO.setIsvalid(1);

+ 6 - 6
mo-daq/src/test/java/com/smppw/modaq/MoDaqApplicationTests.java

@@ -38,8 +38,8 @@ public class MoDaqApplicationTests {
     @Test
     public void reportTest() {
         MailboxInfoDTO emailInfoDTO = this.buildMailbox("*@simuwang.com", "*");
-        Date startDate = DateUtil.parse("2025-06-09 10:20:00", DateConst.YYYY_MM_DD_HH_MM_SS);
-        Date endDate = DateUtil.parse("2025-06-09 17:05:00", DateConst.YYYY_MM_DD_HH_MM_SS);
+        Date startDate = DateUtil.parse("2025-06-09 10:27:00", DateConst.YYYY_MM_DD_HH_MM_SS);
+        Date endDate = DateUtil.parse("2025-06-09 10:56:00", DateConst.YYYY_MM_DD_HH_MM_SS);
         try {
             List<String> folderNames = ListUtil.list(false);
 //            folderNames.add("其他文件夹/报告公告");
@@ -51,10 +51,10 @@ public class MoDaqApplicationTests {
         }
     }
 
-    @Test
-    public void testReparseEmail() {
-        emailParseApiService.reparseEmail(23);
-    }
+//    @Test
+//    public void testReparseEmail() {
+//        emailParseApiService.reparseEmail(23);
+//    }
 
 
     private MailboxInfoDTO buildMailbox(String account, String pwd) {