EmailParseApiServiceImpl.java 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. package com.simuwang.daq.service;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.date.DateUtil;
  4. import cn.hutool.core.exceptions.ExceptionUtil;
  5. import cn.hutool.core.map.MapUtil;
  6. import cn.hutool.core.util.StrUtil;
  7. import com.simuwang.base.common.conts.DateConst;
  8. import com.simuwang.base.common.util.EmailUtil;
  9. import com.simuwang.base.mapper.EmailFileInfoMapper;
  10. import com.simuwang.base.mapper.EmailParseInfoMapper;
  11. import com.simuwang.base.pojo.dos.EmailFileInfoDO;
  12. import com.simuwang.base.pojo.dos.EmailParseInfoDO;
  13. import com.simuwang.base.pojo.dto.EmailContentInfoDTO;
  14. import com.simuwang.base.pojo.dto.EmailFundNavDTO;
  15. import com.simuwang.base.pojo.dto.EmailInfoDTO;
  16. import com.simuwang.base.pojo.dto.MailboxInfoDTO;
  17. import org.slf4j.Logger;
  18. import org.slf4j.LoggerFactory;
  19. import org.springframework.beans.factory.annotation.Qualifier;
  20. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  21. import org.springframework.stereotype.Service;
  22. import java.io.BufferedReader;
  23. import java.io.FileReader;
  24. import java.io.IOException;
  25. import java.util.Date;
  26. import java.util.List;
  27. import java.util.Map;
  28. import java.util.stream.Collectors;
  29. /**
  30. * @author mozuwen
  31. * @date 2024-09-12
  32. * @description 邮件解析服务对外接口实现层
  33. */
  34. @Service
  35. public class EmailParseApiServiceImpl implements EmailParseApiService {
  36. private static final Logger log = LoggerFactory.getLogger(EmailParseApiServiceImpl.class);
  37. private final EmailParseService emailParseService;
  38. private final EmailParseInfoMapper emailParseInfoMapper;
  39. private final EmailFileInfoMapper emailFileInfoMapper;
  40. private final ThreadPoolTaskExecutor asyncExecutor;
  41. public EmailParseApiServiceImpl(EmailParseService emailParseService, EmailParseInfoMapper emailParseInfoMapper,
  42. EmailFileInfoMapper emailFileInfoMapper, @Qualifier("asyncExecutor") ThreadPoolTaskExecutor asyncExecutor) {
  43. this.emailParseService = emailParseService;
  44. this.emailParseInfoMapper = emailParseInfoMapper;
  45. this.emailFileInfoMapper = emailFileInfoMapper;
  46. this.asyncExecutor = asyncExecutor;
  47. }
  48. @Override
  49. public void parseEmail(MailboxInfoDTO mailboxInfoDTO, Date startDate, Date endDate) {
  50. asyncExecutor.execute(() -> emailParseService.parseEmail(mailboxInfoDTO, startDate, endDate));
  51. }
  52. @Override
  53. public void reparseEmail(Integer emailId) {
  54. // 查询邮件信息
  55. EmailParseInfoDO emailParseInfoDO = emailParseInfoMapper.queryById(emailId);
  56. if (emailParseInfoDO == null) {
  57. log.info("邮件不存在 ->邮件id:{}", emailId);
  58. return;
  59. }
  60. List<EmailFileInfoDO> emailFileInfoDOList = emailFileInfoMapper.queryByEmailId(emailId);
  61. if (CollUtil.isEmpty(emailFileInfoDOList)) {
  62. log.info("该邮件不存在附件 -> 邮件id:{}", emailId);
  63. return;
  64. }
  65. // 邮件字段识别映射表
  66. Map<String, List<String>> emailFieldMap = emailParseService.getEmailFieldMapping();
  67. // 邮件类型配置
  68. Map<Integer, List<String>> emailTypeMap = emailParseService.getEmailType();
  69. // 解析流程
  70. List<EmailContentInfoDTO> emailContentInfoDTOList = buildEmailContentInfoDTO(emailId, emailParseInfoDO, emailFileInfoDOList, emailTypeMap);
  71. List<EmailFundNavDTO> emailFundNavDTOList = CollUtil.newArrayList();
  72. Map<EmailContentInfoDTO, List<EmailFundNavDTO>> fileNameNavMap = MapUtil.newHashMap();
  73. asyncExecutor.execute(() -> {
  74. for (EmailContentInfoDTO emailContentInfoDTO : emailContentInfoDTOList) {
  75. try {
  76. List<EmailFundNavDTO> fundNavDTOList = emailParseService.parseEmail(emailContentInfoDTO, emailFieldMap);
  77. fileNameNavMap.put(emailContentInfoDTO, fundNavDTOList);
  78. emailFundNavDTOList.addAll(fundNavDTOList);
  79. } catch (Exception e) {
  80. log.error("重新解析邮件失败,邮件id:{},堆栈信息:{}", emailId, ExceptionUtil.stacktraceToString(e));
  81. }
  82. }
  83. // 保存相关信息 -> 邮件信息表,邮件文件表,邮件净值表,邮件规模表,基金净值表
  84. emailParseService.saveRelatedTable(emailParseInfoDO.getEmail(), emailContentInfoDTOList, fileNameNavMap);
  85. });
  86. }
  87. @Override
  88. public void reparseFile(List<Integer> fileIdList) {
  89. if (CollUtil.isEmpty(fileIdList)) {
  90. return;
  91. }
  92. List<EmailInfoDTO> emailParseInfoDOList = emailParseInfoMapper.queryValuationEmailByFileId(fileIdList);
  93. if (CollUtil.isEmpty(emailParseInfoDOList)) {
  94. return;
  95. }
  96. asyncExecutor.execute(() -> {
  97. Map<Integer, List<EmailInfoDTO>> emailIdFileMap = emailParseInfoDOList.stream().collect(Collectors.groupingBy(EmailInfoDTO::getId));
  98. for (Map.Entry<Integer, List<EmailInfoDTO>> entry : emailIdFileMap.entrySet()) {
  99. Integer emailId = entry.getKey();
  100. List<EmailInfoDTO> emailInfoDTOList = entry.getValue();
  101. String emailAddress = emailInfoDTOList.get(0).getEmail();
  102. List<EmailContentInfoDTO> emailContentInfoDTOList = emailInfoDTOList.stream().map(this::buildEmailContentInfoDTO).collect(Collectors.toList());
  103. List<EmailFundNavDTO> emailFundNavDTOList = CollUtil.newArrayList();
  104. Map<EmailContentInfoDTO, List<EmailFundNavDTO>> fileNameNavMap = MapUtil.newHashMap();
  105. for (EmailContentInfoDTO emailContentInfoDTO : emailContentInfoDTOList) {
  106. try {
  107. log.info("开始重新解析文件 -> 文件id:{}", emailContentInfoDTO.getFielId());
  108. List<EmailFundNavDTO> fundNavDTOList = emailParseService.parseEmail(emailContentInfoDTO, MapUtil.newHashMap());
  109. fileNameNavMap.put(emailContentInfoDTO, fundNavDTOList);
  110. emailFundNavDTOList.addAll(fundNavDTOList);
  111. } catch (Exception e) {
  112. log.error("重新解析文件失败,邮件id:{},文件id:{},堆栈信息:{}", emailId, emailContentInfoDTO.getFielId(), ExceptionUtil.stacktraceToString(e));
  113. }
  114. }
  115. // 保存相关信息 -> 邮件信息表,邮件文件表,邮件净值表,邮件规模表,基金净值表
  116. emailParseService.saveRelatedTable(emailAddress, emailContentInfoDTOList, fileNameNavMap);
  117. }
  118. log.info("重新解析文件结束... -> 文件id:{}", fileIdList);
  119. });
  120. }
  121. private EmailContentInfoDTO buildEmailContentInfoDTO(EmailInfoDTO emailInfoDTO) {
  122. String emailDate = DateUtil.format(emailInfoDTO.getEmailDate(), DateConst.YYYY_MM_DD_HH_MM_SS);
  123. String parseDate = DateUtil.format(new Date(), DateConst.YYYY_MM_DD_HH_MM_SS);
  124. EmailContentInfoDTO contentInfoDTO = new EmailContentInfoDTO();
  125. contentInfoDTO.setEmailId(emailInfoDTO.getId());
  126. contentInfoDTO.setFielId(emailInfoDTO.getFileId());
  127. contentInfoDTO.setEmailAddress(emailInfoDTO.getEmail());
  128. contentInfoDTO.setEmailDate(emailDate);
  129. contentInfoDTO.setEmailTitle(emailInfoDTO.getEmailTitle());
  130. contentInfoDTO.setParseDate(parseDate);
  131. contentInfoDTO.setFileName(emailInfoDTO.getFileName());
  132. contentInfoDTO.setFilePath(emailInfoDTO.getFilePath());
  133. contentInfoDTO.setEmailType(emailInfoDTO.getEmailType());
  134. return contentInfoDTO;
  135. }
  136. private List<EmailContentInfoDTO> buildEmailContentInfoDTO(Integer emailId, EmailParseInfoDO emailParseInfoDO, List<EmailFileInfoDO> emailFileInfoDOList, Map<Integer, List<String>> emailTypeMap) {
  137. List<EmailContentInfoDTO> emailContentInfoDTOList = CollUtil.newArrayList();
  138. String emailDate = DateUtil.format(emailParseInfoDO.getEmailDate(), DateConst.YYYY_MM_DD_HH_MM_SS);
  139. String parseDate = DateUtil.format(new Date(), DateConst.YYYY_MM_DD_HH_MM_SS);
  140. for (EmailFileInfoDO fileInfoDO : emailFileInfoDOList) {
  141. EmailContentInfoDTO contentInfoDTO = new EmailContentInfoDTO();
  142. contentInfoDTO.setEmailId(emailId);
  143. contentInfoDTO.setFielId(fileInfoDO.getId());
  144. contentInfoDTO.setEmailAddress(emailParseInfoDO.getEmail());
  145. contentInfoDTO.setEmailDate(emailDate);
  146. contentInfoDTO.setEmailTitle(emailParseInfoDO.getEmailTitle());
  147. contentInfoDTO.setParseDate(parseDate);
  148. contentInfoDTO.setFileName(fileInfoDO.getFileName());
  149. contentInfoDTO.setFilePath(fileInfoDO.getFilePath());
  150. Integer emailType = EmailUtil.getEmailTypeBySubject(emailParseInfoDO.getEmailTitle(), emailTypeMap);
  151. contentInfoDTO.setEmailType(emailType);
  152. String emailContent = readHtmlFileContent(fileInfoDO.getFilePath());
  153. contentInfoDTO.setEmailContent(emailContent);
  154. emailContentInfoDTOList.add(contentInfoDTO);
  155. }
  156. return emailContentInfoDTOList;
  157. }
  158. public static String readHtmlFileContent(String filePath) {
  159. if (StrUtil.isNotBlank(filePath) && filePath.endsWith("html")) {
  160. StringBuilder content = new StringBuilder();
  161. try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
  162. String line;
  163. while ((line = reader.readLine()) != null) {
  164. // 追加每一行到StringBuilder中
  165. content.append(line).append("\n");
  166. }
  167. } catch (IOException e) {
  168. System.err.println("Error reading the file: " + e.getMessage());
  169. return null;
  170. }
  171. return content.toString();
  172. }
  173. return null;
  174. }
  175. }