EmailParseApiServiceImpl.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  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.enums.TaskType;
  9. import com.simuwang.base.common.util.DateUtils;
  10. import com.simuwang.base.common.util.EmailUtil;
  11. import com.simuwang.base.mapper.EmailFileInfoMapper;
  12. import com.simuwang.base.mapper.EmailParseInfoMapper;
  13. import com.simuwang.base.mapper.EmailTaskInfoMapper;
  14. import com.simuwang.base.pojo.dos.EmailFileInfoDO;
  15. import com.simuwang.base.pojo.dos.EmailParseInfoDO;
  16. import com.simuwang.base.pojo.dos.EmailTaskInfoDO;
  17. import com.simuwang.base.pojo.dto.EmailContentInfoDTO;
  18. import com.simuwang.base.pojo.dto.EmailFundNavDTO;
  19. import com.simuwang.base.pojo.dto.EmailInfoDTO;
  20. import com.simuwang.base.pojo.dto.MailboxInfoDTO;
  21. import com.simuwang.shiro.utils.UserUtils;
  22. import org.slf4j.Logger;
  23. import org.slf4j.LoggerFactory;
  24. import org.springframework.beans.factory.annotation.Qualifier;
  25. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  26. import org.springframework.stereotype.Service;
  27. import java.io.BufferedReader;
  28. import java.io.FileReader;
  29. import java.io.IOException;
  30. import java.util.Date;
  31. import java.util.List;
  32. import java.util.Map;
  33. import java.util.stream.Collectors;
  34. /**
  35. * @author mozuwen
  36. * @date 2024-09-12
  37. * @description 邮件解析服务对外接口实现层
  38. */
  39. @Service
  40. public class EmailParseApiServiceImpl implements EmailParseApiService {
  41. private static final Logger log = LoggerFactory.getLogger(EmailParseApiServiceImpl.class);
  42. private final EmailParseService emailParseService;
  43. private final EmailParseInfoMapper emailParseInfoMapper;
  44. private final EmailFileInfoMapper emailFileInfoMapper;
  45. private final ThreadPoolTaskExecutor asyncExecutor;
  46. private final EmailTaskInfoMapper emailTaskInfoMapper;
  47. public EmailParseApiServiceImpl(EmailParseService emailParseService, EmailParseInfoMapper emailParseInfoMapper,
  48. EmailFileInfoMapper emailFileInfoMapper, @Qualifier("asyncExecutor") ThreadPoolTaskExecutor asyncExecutor, EmailTaskInfoMapper emailTaskInfoMapper) {
  49. this.emailParseService = emailParseService;
  50. this.emailParseInfoMapper = emailParseInfoMapper;
  51. this.emailFileInfoMapper = emailFileInfoMapper;
  52. this.asyncExecutor = asyncExecutor;
  53. this.emailTaskInfoMapper = emailTaskInfoMapper;
  54. }
  55. @Override
  56. public void parseEmail(MailboxInfoDTO mailboxInfoDTO, Date startDate, Date endDate) {
  57. Integer userId = null;
  58. try{
  59. if(UserUtils.getPrincipal() == null){
  60. userId = 1;
  61. }else{
  62. userId = UserUtils.getLoginUser().getUserId();
  63. }
  64. }catch (Exception e){
  65. log.error(e.getMessage());
  66. }
  67. Integer finalUserId = userId;
  68. asyncExecutor.execute(new Runnable() {
  69. @Override
  70. public void run() {
  71. EmailTaskInfoDO emailTaskInfoDO = startEmailTask(mailboxInfoDTO.getAccount(), 1, finalUserId);
  72. try{
  73. emailParseService.parseEmail(mailboxInfoDTO, startDate, endDate);
  74. }catch (Exception e){
  75. log.error(e.getMessage(),e);
  76. endEmailTask(emailTaskInfoDO.getId(),-1);
  77. return;
  78. }
  79. endEmailTask(emailTaskInfoDO.getId(),2);
  80. }
  81. }
  82. );
  83. }
  84. private void endEmailTask(Integer id,Integer taskStatus) {
  85. try{
  86. EmailTaskInfoDO emailTaskInfoDO = new EmailTaskInfoDO();
  87. emailTaskInfoDO.setId(id);
  88. emailTaskInfoDO.setTaskStatus(taskStatus);
  89. emailTaskInfoDO.setUpdateTime(DateUtils.getNowDate());
  90. emailTaskInfoDO.setEndTime(DateUtils.getNowDate());
  91. emailTaskInfoMapper.updateTaskStatusById(emailTaskInfoDO);
  92. }catch (Exception e){
  93. log.error(e.getMessage());
  94. }
  95. }
  96. private EmailTaskInfoDO startEmailTask(String email,Integer taskStatus,Integer userId) {
  97. EmailTaskInfoDO emailTaskInfoDO = new EmailTaskInfoDO();
  98. try{
  99. emailTaskInfoDO.setTaskName(TaskType.EMAIL_PARSE.getInfo());
  100. emailTaskInfoDO.setTaskType(TaskType.EMAIL_PARSE.getType());
  101. emailTaskInfoDO.setTaskStatus(taskStatus);
  102. emailTaskInfoDO.setStartTime(DateUtils.getNowDate());
  103. emailTaskInfoDO.setIsvalid(1);
  104. emailTaskInfoDO.setEmail(email);
  105. emailTaskInfoDO.setCreateTime(DateUtils.getNowDate());
  106. emailTaskInfoDO.setUpdateTime(DateUtils.getNowDate());
  107. emailTaskInfoDO.setCreatorId(userId);
  108. emailTaskInfoDO.setUpdaterId(userId);
  109. emailTaskInfoMapper.insert(emailTaskInfoDO);
  110. }catch (Exception e){
  111. log.error(e.getMessage());
  112. }
  113. return emailTaskInfoDO;
  114. }
  115. @Override
  116. public void reparseEmail(Integer emailId) {
  117. // 查询邮件信息
  118. EmailParseInfoDO emailParseInfoDO = emailParseInfoMapper.queryById(emailId);
  119. if (emailParseInfoDO == null) {
  120. log.info("邮件不存在 ->邮件id:{}", emailId);
  121. return;
  122. }
  123. //解析成功的邮件不再解析
  124. // if (emailParseInfoDO.getParseStatus() == 1) {
  125. // log.info("邮件解析状态为成功,不再解析 ->邮件id:{}", emailId);
  126. // return;
  127. // }
  128. List<EmailFileInfoDO> emailFileInfoDOList = emailFileInfoMapper.queryByEmailId(emailId);
  129. if (CollUtil.isEmpty(emailFileInfoDOList)) {
  130. log.info("该邮件不存在附件 -> 邮件id:{}", emailId);
  131. return;
  132. }
  133. // 邮件字段识别映射表
  134. Map<String, List<String>> emailFieldMap = emailParseService.getEmailFieldMapping();
  135. // 邮件类型配置
  136. Map<Integer, List<String>> emailTypeMap = emailParseService.getEmailType();
  137. // 解析流程
  138. List<EmailContentInfoDTO> emailContentInfoDTOList = buildEmailContentInfoDTO(emailId, emailParseInfoDO, emailFileInfoDOList, emailTypeMap);
  139. List<EmailFundNavDTO> emailFundNavDTOList = CollUtil.newArrayList();
  140. Map<EmailContentInfoDTO, List<EmailFundNavDTO>> fileNameNavMap = MapUtil.newHashMap();
  141. asyncExecutor.execute(() -> {
  142. for (EmailContentInfoDTO emailContentInfoDTO : emailContentInfoDTOList) {
  143. try {
  144. List<EmailFundNavDTO> fundNavDTOList = emailParseService.parseEmail(emailContentInfoDTO, emailFieldMap);
  145. fileNameNavMap.put(emailContentInfoDTO, fundNavDTOList);
  146. emailFundNavDTOList.addAll(fundNavDTOList);
  147. } catch (Exception e) {
  148. log.error("重新解析邮件失败,邮件id:{},堆栈信息:{}", emailId, ExceptionUtil.stacktraceToString(e));
  149. }
  150. }
  151. // 保存相关信息 -> 邮件信息表,邮件文件表,邮件净值表,邮件规模表,基金净值表
  152. emailParseService.saveRelatedTable(emailParseInfoDO.getEmail(), emailContentInfoDTOList, fileNameNavMap);
  153. });
  154. }
  155. @Override
  156. public void reparseFile(List<Integer> fileIdList) {
  157. if (CollUtil.isEmpty(fileIdList)) {
  158. return;
  159. }
  160. List<EmailInfoDTO> emailParseInfoDOList = emailParseInfoMapper.queryValuationEmailByFileId(fileIdList);
  161. if (CollUtil.isEmpty(emailParseInfoDOList)) {
  162. return;
  163. }
  164. asyncExecutor.execute(() -> {
  165. Map<Integer, List<EmailInfoDTO>> emailIdFileMap = emailParseInfoDOList.stream().collect(Collectors.groupingBy(EmailInfoDTO::getId));
  166. for (Map.Entry<Integer, List<EmailInfoDTO>> entry : emailIdFileMap.entrySet()) {
  167. Integer emailId = entry.getKey();
  168. List<EmailInfoDTO> emailInfoDTOList = entry.getValue();
  169. String emailAddress = emailInfoDTOList.get(0).getEmail();
  170. List<EmailContentInfoDTO> emailContentInfoDTOList = emailInfoDTOList.stream().map(this::buildEmailContentInfoDTO).collect(Collectors.toList());
  171. List<EmailFundNavDTO> emailFundNavDTOList = CollUtil.newArrayList();
  172. Map<EmailContentInfoDTO, List<EmailFundNavDTO>> fileNameNavMap = MapUtil.newHashMap();
  173. for (EmailContentInfoDTO emailContentInfoDTO : emailContentInfoDTOList) {
  174. try {
  175. log.info("开始重新解析文件 -> 文件id:{}", emailContentInfoDTO.getFileId());
  176. List<EmailFundNavDTO> fundNavDTOList = emailParseService.parseEmail(emailContentInfoDTO, MapUtil.newHashMap());
  177. fileNameNavMap.put(emailContentInfoDTO, fundNavDTOList);
  178. emailFundNavDTOList.addAll(fundNavDTOList);
  179. } catch (Exception e) {
  180. log.error("重新解析文件失败,邮件id:{},文件id:{},堆栈信息:{}", emailId, emailContentInfoDTO.getFileId(), ExceptionUtil.stacktraceToString(e));
  181. }
  182. }
  183. // 保存相关信息 -> 邮件信息表,邮件文件表,邮件净值表,邮件规模表,基金净值表
  184. emailParseService.saveRelatedTable(emailAddress, emailContentInfoDTOList, fileNameNavMap);
  185. }
  186. log.info("重新解析文件结束... -> 文件id:{}", fileIdList);
  187. });
  188. }
  189. private EmailContentInfoDTO buildEmailContentInfoDTO(EmailInfoDTO emailInfoDTO) {
  190. String emailDate = DateUtil.format(emailInfoDTO.getEmailDate(), DateConst.YYYY_MM_DD_HH_MM_SS);
  191. String parseDate = DateUtil.format(new Date(), DateConst.YYYY_MM_DD_HH_MM_SS);
  192. EmailContentInfoDTO contentInfoDTO = new EmailContentInfoDTO();
  193. contentInfoDTO.setEmailId(emailInfoDTO.getId());
  194. contentInfoDTO.setFileId(emailInfoDTO.getFileId());
  195. contentInfoDTO.setEmailAddress(emailInfoDTO.getEmail());
  196. contentInfoDTO.setEmailDate(emailDate);
  197. contentInfoDTO.setEmailTitle(emailInfoDTO.getEmailTitle());
  198. contentInfoDTO.setParseDate(parseDate);
  199. contentInfoDTO.setFileName(emailInfoDTO.getFileName());
  200. contentInfoDTO.setFilePath(emailInfoDTO.getFilePath());
  201. contentInfoDTO.setEmailType(emailInfoDTO.getEmailType());
  202. return contentInfoDTO;
  203. }
  204. private List<EmailContentInfoDTO> buildEmailContentInfoDTO(Integer emailId, EmailParseInfoDO emailParseInfoDO, List<EmailFileInfoDO> emailFileInfoDOList, Map<Integer, List<String>> emailTypeMap) {
  205. List<EmailContentInfoDTO> emailContentInfoDTOList = CollUtil.newArrayList();
  206. String emailDate = DateUtil.format(emailParseInfoDO.getEmailDate(), DateConst.YYYY_MM_DD_HH_MM_SS);
  207. String parseDate = DateUtil.format(new Date(), DateConst.YYYY_MM_DD_HH_MM_SS);
  208. for (EmailFileInfoDO fileInfoDO : emailFileInfoDOList) {
  209. EmailContentInfoDTO contentInfoDTO = new EmailContentInfoDTO();
  210. contentInfoDTO.setEmailId(emailId);
  211. contentInfoDTO.setFileId(fileInfoDO.getId());
  212. contentInfoDTO.setSenderEmail(emailParseInfoDO.getSenderEmail());
  213. contentInfoDTO.setEmailAddress(emailParseInfoDO.getEmail());
  214. contentInfoDTO.setEmailDate(emailDate);
  215. contentInfoDTO.setEmailTitle(emailParseInfoDO.getEmailTitle());
  216. contentInfoDTO.setParseDate(parseDate);
  217. contentInfoDTO.setFileName(fileInfoDO.getFileName());
  218. contentInfoDTO.setFilePath(fileInfoDO.getFilePath());
  219. Integer emailType = EmailUtil.getEmailTypeBySubject(emailParseInfoDO.getEmailTitle(), emailTypeMap);
  220. contentInfoDTO.setEmailType(emailType);
  221. String emailContent = readHtmlFileContent(fileInfoDO.getFilePath());
  222. contentInfoDTO.setEmailContent(emailContent);
  223. emailContentInfoDTOList.add(contentInfoDTO);
  224. }
  225. return emailContentInfoDTOList;
  226. }
  227. public static String readHtmlFileContent(String filePath) {
  228. if (StrUtil.isNotBlank(filePath) && filePath.endsWith("html")) {
  229. StringBuilder content = new StringBuilder();
  230. try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
  231. String line;
  232. while ((line = reader.readLine()) != null) {
  233. // 追加每一行到StringBuilder中
  234. content.append(line).append("\n");
  235. }
  236. } catch (IOException e) {
  237. System.err.println("Error reading the file: " + e.getMessage());
  238. return null;
  239. }
  240. return content.toString();
  241. }
  242. return null;
  243. }
  244. }