package com.simuwang.daq.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.simuwang.base.common.conts.DateConst; import com.simuwang.base.common.util.EmailUtil; import com.simuwang.base.mapper.EmailFileInfoMapper; import com.simuwang.base.mapper.EmailParseInfoMapper; import com.simuwang.base.pojo.dos.EmailFileInfoDO; import com.simuwang.base.pojo.dos.EmailParseInfoDO; import com.simuwang.base.pojo.dto.EmailContentInfoDTO; import com.simuwang.base.pojo.dto.EmailFundNavDTO; import com.simuwang.base.pojo.dto.EmailInfoDTO; import com.simuwang.base.pojo.dto.MailboxInfoDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.Date; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * @author mozuwen * @date 2024-09-12 * @description 邮件解析服务对外接口实现层 */ @Service public class EmailParseApiServiceImpl implements EmailParseApiService { private static final Logger log = LoggerFactory.getLogger(EmailParseApiServiceImpl.class); private final EmailParseService emailParseService; private final EmailParseInfoMapper emailParseInfoMapper; private final EmailFileInfoMapper emailFileInfoMapper; private final ThreadPoolTaskExecutor asyncExecutor; public EmailParseApiServiceImpl(EmailParseService emailParseService, EmailParseInfoMapper emailParseInfoMapper, EmailFileInfoMapper emailFileInfoMapper, @Qualifier("asyncExecutor") ThreadPoolTaskExecutor asyncExecutor) { this.emailParseService = emailParseService; this.emailParseInfoMapper = emailParseInfoMapper; this.emailFileInfoMapper = emailFileInfoMapper; this.asyncExecutor = asyncExecutor; } @Override public void parseEmail(MailboxInfoDTO mailboxInfoDTO, Date startDate, Date endDate) { asyncExecutor.execute(() -> emailParseService.parseEmail(mailboxInfoDTO, startDate, endDate)); } @Override public void reparseEmail(Integer emailId) { // 查询邮件信息 EmailParseInfoDO emailParseInfoDO = emailParseInfoMapper.queryById(emailId); if (emailParseInfoDO == null) { log.info("邮件不存在 ->邮件id:{}", emailId); return; } List emailFileInfoDOList = emailFileInfoMapper.queryByEmailId(emailId); if (CollUtil.isEmpty(emailFileInfoDOList)) { log.info("该邮件不存在附件 -> 邮件id:{}", emailId); return; } // 邮件字段识别映射表 Map> emailFieldMap = emailParseService.getEmailFieldMapping(); // 邮件类型配置 Map> emailTypeMap = emailParseService.getEmailType(); // 解析流程 List emailContentInfoDTOList = buildEmailContentInfoDTO(emailId, emailParseInfoDO, emailFileInfoDOList, emailTypeMap); List emailFundNavDTOList = CollUtil.newArrayList(); Map> fileNameNavMap = MapUtil.newHashMap(); asyncExecutor.execute(() -> { for (EmailContentInfoDTO emailContentInfoDTO : emailContentInfoDTOList) { try { List fundNavDTOList = emailParseService.parseEmail(emailContentInfoDTO, emailFieldMap); fileNameNavMap.put(emailContentInfoDTO, fundNavDTOList); emailFundNavDTOList.addAll(fundNavDTOList); } catch (Exception e) { log.error("重新解析邮件失败,邮件id:{},堆栈信息:{}", emailId, ExceptionUtil.stacktraceToString(e)); } } // 保存相关信息 -> 邮件信息表,邮件文件表,邮件净值表,邮件规模表,基金净值表 emailParseService.saveRelatedTable(emailParseInfoDO.getEmail(), emailContentInfoDTOList, fileNameNavMap); }); } @Override public void reparseFile(List fileIdList) { if (CollUtil.isEmpty(fileIdList)) { return; } List emailParseInfoDOList = emailParseInfoMapper.queryValuationEmailByFileId(fileIdList); if (CollUtil.isEmpty(emailParseInfoDOList)) { return; } asyncExecutor.execute(() -> { Map> emailIdFileMap = emailParseInfoDOList.stream().collect(Collectors.groupingBy(EmailInfoDTO::getId)); for (Map.Entry> entry : emailIdFileMap.entrySet()) { Integer emailId = entry.getKey(); List emailInfoDTOList = entry.getValue(); String emailAddress = emailInfoDTOList.get(0).getEmail(); List emailContentInfoDTOList = emailInfoDTOList.stream().map(this::buildEmailContentInfoDTO).collect(Collectors.toList()); List emailFundNavDTOList = CollUtil.newArrayList(); Map> fileNameNavMap = MapUtil.newHashMap(); for (EmailContentInfoDTO emailContentInfoDTO : emailContentInfoDTOList) { try { log.info("开始重新解析文件 -> 文件id:{}", emailContentInfoDTO.getFielId()); List fundNavDTOList = emailParseService.parseEmail(emailContentInfoDTO, MapUtil.newHashMap()); fileNameNavMap.put(emailContentInfoDTO, fundNavDTOList); emailFundNavDTOList.addAll(fundNavDTOList); } catch (Exception e) { log.error("重新解析文件失败,邮件id:{},文件id:{},堆栈信息:{}", emailId, emailContentInfoDTO.getFielId(), ExceptionUtil.stacktraceToString(e)); } } // 保存相关信息 -> 邮件信息表,邮件文件表,邮件净值表,邮件规模表,基金净值表 emailParseService.saveRelatedTable(emailAddress, emailContentInfoDTOList, fileNameNavMap); } log.info("重新解析文件结束... -> 文件id:{}", fileIdList); }); } private EmailContentInfoDTO buildEmailContentInfoDTO(EmailInfoDTO emailInfoDTO) { String emailDate = DateUtil.format(emailInfoDTO.getEmailDate(), DateConst.YYYY_MM_DD_HH_MM_SS); String parseDate = DateUtil.format(new Date(), DateConst.YYYY_MM_DD_HH_MM_SS); EmailContentInfoDTO contentInfoDTO = new EmailContentInfoDTO(); contentInfoDTO.setEmailId(emailInfoDTO.getId()); contentInfoDTO.setFielId(emailInfoDTO.getFileId()); contentInfoDTO.setEmailAddress(emailInfoDTO.getEmail()); contentInfoDTO.setEmailDate(emailDate); contentInfoDTO.setEmailTitle(emailInfoDTO.getEmailTitle()); contentInfoDTO.setParseDate(parseDate); contentInfoDTO.setFileName(emailInfoDTO.getFileName()); contentInfoDTO.setFilePath(emailInfoDTO.getFilePath()); contentInfoDTO.setEmailType(emailInfoDTO.getEmailType()); return contentInfoDTO; } private List buildEmailContentInfoDTO(Integer emailId, EmailParseInfoDO emailParseInfoDO, List emailFileInfoDOList, Map> emailTypeMap) { List emailContentInfoDTOList = CollUtil.newArrayList(); String emailDate = DateUtil.format(emailParseInfoDO.getEmailDate(), DateConst.YYYY_MM_DD_HH_MM_SS); String parseDate = DateUtil.format(new Date(), DateConst.YYYY_MM_DD_HH_MM_SS); for (EmailFileInfoDO fileInfoDO : emailFileInfoDOList) { EmailContentInfoDTO contentInfoDTO = new EmailContentInfoDTO(); contentInfoDTO.setEmailId(emailId); contentInfoDTO.setFielId(fileInfoDO.getId()); contentInfoDTO.setEmailAddress(emailParseInfoDO.getEmail()); contentInfoDTO.setEmailDate(emailDate); contentInfoDTO.setEmailTitle(emailParseInfoDO.getEmailTitle()); contentInfoDTO.setParseDate(parseDate); contentInfoDTO.setFileName(fileInfoDO.getFileName()); contentInfoDTO.setFilePath(fileInfoDO.getFilePath()); Integer emailType = EmailUtil.getEmailTypeBySubject(emailParseInfoDO.getEmailTitle(), emailTypeMap); contentInfoDTO.setEmailType(emailType); String emailContent = readHtmlFileContent(fileInfoDO.getFilePath()); contentInfoDTO.setEmailContent(emailContent); emailContentInfoDTOList.add(contentInfoDTO); } return emailContentInfoDTOList; } public static String readHtmlFileContent(String filePath) { if (StrUtil.isNotBlank(filePath) && filePath.endsWith("html")) { StringBuilder content = new StringBuilder(); try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { String line; while ((line = reader.readLine()) != null) { // 追加每一行到StringBuilder中 content.append(line).append("\n"); } } catch (IOException e) { System.err.println("Error reading the file: " + e.getMessage()); return null; } return content.toString(); } return null; } }