EmailParseApiServiceImpl.java 13 KB

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