|
@@ -100,13 +100,13 @@ public class EmailParseService {
|
|
|
if (CollUtil.isEmpty(emailTypes)) {
|
|
|
emailTypes = ListUtil.of(EmailTypeConst.REPORT_LETTER_EMAIL_TYPE);
|
|
|
}
|
|
|
- log.info("开始邮件解析 -> 邮箱信息:{},开始时间:{},结束时间:{}", mailboxInfoDTO, DateUtil.format(startDate,
|
|
|
- DateConst.YYYY_MM_DD_HH_MM_SS), DateUtil.format(endDate, DateConst.YYYY_MM_DD_HH_MM_SS));
|
|
|
- // 邮件类型配置
|
|
|
- Map<Integer, List<String>> emailTypeMap = getEmailType();
|
|
|
+ if (log.isInfoEnabled()) {
|
|
|
+ log.info("开始邮件解析 -> 邮箱信息:{},开始时间:{},结束时间:{}", mailboxInfoDTO, DateUtil.format(startDate,
|
|
|
+ DateConst.YYYY_MM_DD_HH_MM_SS), DateUtil.format(endDate, DateConst.YYYY_MM_DD_HH_MM_SS));
|
|
|
+ }
|
|
|
Map<String, List<EmailContentInfoDTO>> emailContentMap;
|
|
|
try {
|
|
|
- emailContentMap = realEmail(mailboxInfoDTO, emailTypeMap, startDate, endDate, folderNames);
|
|
|
+ emailContentMap = realEmail(mailboxInfoDTO, startDate, endDate, folderNames);
|
|
|
} catch (Exception e) {
|
|
|
log.error("采集邮件失败 -> 邮箱配置信息:{},堆栈信息:{}", mailboxInfoDTO, ExceptionUtil.stacktraceToString(e));
|
|
|
return;
|
|
@@ -149,13 +149,23 @@ public class EmailParseService {
|
|
|
while (entryIterator.hasNext()) {
|
|
|
Map.Entry<EmailContentInfoDTO, List<EmailZipFileDTO>> entry = entryIterator.next();
|
|
|
EmailContentInfoDTO key = entry.getKey();
|
|
|
+ String emailTitle = key.getEmailTitle();
|
|
|
List<EmailZipFileDTO> dtos = entry.getValue();
|
|
|
|
|
|
List<Integer> types = ListUtil.list(false);
|
|
|
types.add(key.getEmailType());
|
|
|
if (CollUtil.isNotEmpty(dtos)) {
|
|
|
+ Iterator<EmailZipFileDTO> iterator = dtos.iterator();
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ EmailZipFileDTO dto = iterator.next();
|
|
|
+ String filename = dto.getFilename();
|
|
|
+ if (filename != null && filename.contains("复核函")) {
|
|
|
+ log.warn("邮件{} 附件中的压缩文件{} 是复核函,不用解析上传。", emailTitle, filename);
|
|
|
+ iterator.remove();
|
|
|
+ }
|
|
|
+ }
|
|
|
List<Integer> list = dtos.stream().map(EmailZipFileDTO::getEmailType).distinct().toList();
|
|
|
- types.addAll(list);
|
|
|
+ CollUtil.addAllIfNotContains(types, list);
|
|
|
}
|
|
|
|
|
|
boolean flag = false;
|
|
@@ -310,8 +320,7 @@ public class EmailParseService {
|
|
|
for (EmailZipFileDTO zipFile : dtos) {
|
|
|
EmailFileInfoDO emailFile = saveEmailFileInfo(emailId, zipFile.getFilename(), zipFile.getFilepath());
|
|
|
// 解析并保存报告
|
|
|
- ParseResult<ReportData> parseResult = this.parseReportAndHandleResult(emailFile.getId(), zipFile.getFilename(),
|
|
|
- zipFile.getFilepath(), zipFile.getEmailType(), emailFile.getAiFileId());
|
|
|
+ ParseResult<ReportData> parseResult = this.parseReportAndHandleResult(emailTitle, emailFile, zipFile);
|
|
|
dataList.add(parseResult);
|
|
|
}
|
|
|
|
|
@@ -337,26 +346,31 @@ public class EmailParseService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private ParseResult<ReportData> parseReportAndHandleResult(int fileId, String fileName,
|
|
|
- String filepath, Integer emailType, String aiFileId) {
|
|
|
+ private ParseResult<ReportData> parseReportAndHandleResult(String emailTitle, EmailFileInfoDO emailFileInfo, EmailZipFileDTO zipFile) {
|
|
|
+ Integer emailType = zipFile.getEmailType();
|
|
|
+ String fileName = zipFile.getFilename();
|
|
|
+ String filepath = zipFile.getFilepath();
|
|
|
ParseResult<ReportData> result = new ParseResult<>();
|
|
|
boolean reportFlag = emailType == null || !EmailTypeConst.SUPPORT_EMAIL_TYPES.contains(emailType);
|
|
|
if (reportFlag || StrUtil.isBlank(fileName) || fileName.endsWith(".html")) {
|
|
|
result.setStatus(ReportParseStatus.NOT_A_REPORT.getCode());
|
|
|
result.setMsg(StrUtil.format(ReportParseStatus.NOT_A_REPORT.getMsg(), fileName));
|
|
|
+ log.error(result.getMsg());
|
|
|
return result;
|
|
|
}
|
|
|
- Pattern pattern = Pattern.compile("[A-Z0-9]{6}");
|
|
|
- Matcher matcher = pattern.matcher(fileName);
|
|
|
- String registerNumber = null;
|
|
|
- if (matcher.find()) {
|
|
|
- registerNumber = matcher.group();
|
|
|
- }
|
|
|
+ // 基金代码、备案编码
|
|
|
+ String registerNumber = ReportParseUtils.matchFundCode(fileName);
|
|
|
// 类型识别---先识别季度报告,没有季度再识别年度报告,最后识别月报
|
|
|
- ReportType reportType = ReportParseUtils.matchReportType(fileName);
|
|
|
+ ReportType reportType = ReportParseUtils.matchReportType(emailType, fileName);
|
|
|
if (Objects.equals(EmailTypeConst.REPORT_LETTER_EMAIL_TYPE, emailType)) {
|
|
|
reportType = ReportType.LETTER;
|
|
|
}
|
|
|
+ if (reportType == null) {
|
|
|
+ reportType = ReportParseUtils.matchReportType(emailType, emailTitle);
|
|
|
+ if (log.isDebugEnabled()) {
|
|
|
+ log.debug("报告{} 根据邮件主题{} 重新识别的类型是:{}", fileName, emailTitle, reportType);
|
|
|
+ }
|
|
|
+ }
|
|
|
// 解析器--根据文件后缀获取对应解析器,解析不了就用AI来解析
|
|
|
ReportParserFileType fileType;
|
|
|
String fileSuffix = StrUtil.subAfter(fileName, ".", true);
|
|
@@ -365,14 +379,18 @@ public class EmailParseService {
|
|
|
if (fileType == null) {
|
|
|
result.setStatus(ReportParseStatus.NO_SUPPORT_TEMPLATE.getCode());
|
|
|
result.setMsg(StrUtil.format(ReportParseStatus.NO_SUPPORT_TEMPLATE.getMsg(), fileName));
|
|
|
+ log.error(result.getMsg());
|
|
|
return result;
|
|
|
}
|
|
|
// 不是定期报告的判断逻辑放在不支持的格式下面
|
|
|
if (reportType == null) {
|
|
|
result.setStatus(ReportParseStatus.NOT_A_REPORT.getCode());
|
|
|
result.setMsg(StrUtil.format(ReportParseStatus.NOT_A_REPORT.getMsg(), fileName));
|
|
|
+ log.error(result.getMsg());
|
|
|
return result;
|
|
|
}
|
|
|
+ Integer fileId = emailFileInfo.getId();
|
|
|
+ String aiFileId = emailFileInfo.getAiFileId();
|
|
|
// 不支持解析的格式文件
|
|
|
boolean notSupportFile = false;
|
|
|
// 解析报告
|
|
@@ -395,7 +413,7 @@ public class EmailParseService {
|
|
|
}
|
|
|
} else {
|
|
|
if (log.isInfoEnabled()) {
|
|
|
- log.info("报告{} 是已经存在ai解析记录,上传过文件{},直接跳转到AI解析器进行解析", fileName, fileId);
|
|
|
+ log.info("报告{} 是已经存在ai解析记录,上传过文件{},直接跳转到AI解析器进行解析", fileName, aiFileId);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -525,14 +543,21 @@ public class EmailParseService {
|
|
|
|
|
|
public Map<Integer, List<String>> getEmailType() {
|
|
|
Map<Integer, List<String>> emailTypeMap = MapUtil.newHashMap(3, true);
|
|
|
- emailTypeMap.put(EmailTypeConst.REPORT_EMAIL_TYPE,
|
|
|
- ListUtil.toList("月报", "月度报告", "季报", "季度报告", "年报", "年度报告"));
|
|
|
+ // 定期报告的类型判断
|
|
|
+ List<String> types = ListUtil.list(true);
|
|
|
+ CollUtil.addAll(types, ReportType.QUARTERLY.getPatterns());
|
|
|
+ CollUtil.addAll(types, ReportType.ANNUALLY.getPatterns());
|
|
|
+ CollUtil.addAll(types, ReportType.MONTHLY.getPatterns());
|
|
|
+ emailTypeMap.put(EmailTypeConst.REPORT_EMAIL_TYPE, types);
|
|
|
+ // 确认函
|
|
|
emailTypeMap.put(EmailTypeConst.REPORT_LETTER_EMAIL_TYPE,
|
|
|
ListUtil.toList(ReportType.LETTER.getPatterns()));
|
|
|
- emailTypeMap.put(EmailTypeConst.REPORT_OTHER_TYPE,
|
|
|
- ListUtil.toList(ReportType.OTHER.getPatterns()));
|
|
|
+ // 周报
|
|
|
emailTypeMap.put(EmailTypeConst.REPORT_WEEKLY_TYPE,
|
|
|
ListUtil.toList(ReportType.WEEKLY.getPatterns()));
|
|
|
+ // 其他
|
|
|
+ emailTypeMap.put(EmailTypeConst.REPORT_OTHER_TYPE,
|
|
|
+ ListUtil.toList(ReportType.OTHER.getPatterns()));
|
|
|
return emailTypeMap;
|
|
|
}
|
|
|
|
|
@@ -540,14 +565,12 @@ public class EmailParseService {
|
|
|
* 读取邮件
|
|
|
*
|
|
|
* @param mailboxInfoDTO 邮箱配置信息
|
|
|
- * @param emailTypeMap 邮件类型识别规则映射表
|
|
|
* @param startDate 邮件起始日期
|
|
|
* @param endDate 邮件截止日期(为null,将解析邮件日期小于等于startDate的当天邮件)
|
|
|
* @return 读取到的邮件信息
|
|
|
* @throws Exception 异常信息
|
|
|
*/
|
|
|
private Map<String, List<EmailContentInfoDTO>> realEmail(MailboxInfoDTO mailboxInfoDTO,
|
|
|
- Map<Integer, List<String>> emailTypeMap,
|
|
|
Date startDate, Date endDate,
|
|
|
List<String> folderNames) throws Exception {
|
|
|
if (CollUtil.isEmpty(folderNames)) {
|
|
@@ -568,7 +591,7 @@ public class EmailParseService {
|
|
|
|
|
|
for (String folderName : folderNames) {
|
|
|
try {
|
|
|
- Map<String, List<EmailContentInfoDTO>> temp = this.getFolderEmail(mailboxInfoDTO, emailTypeMap,
|
|
|
+ Map<String, List<EmailContentInfoDTO>> temp = this.getFolderEmail(mailboxInfoDTO,
|
|
|
startDate, endDate, store, folderName);
|
|
|
if (MapUtil.isNotEmpty(temp)) {
|
|
|
result.putAll(temp);
|
|
@@ -587,7 +610,6 @@ public class EmailParseService {
|
|
|
}
|
|
|
|
|
|
private Map<String, List<EmailContentInfoDTO>> getFolderEmail(MailboxInfoDTO mailboxInfoDTO,
|
|
|
- Map<Integer, List<String>> emailTypeMap,
|
|
|
Date startDate, Date endDate,
|
|
|
Store store, String folderName) throws MessagingException {
|
|
|
// 默认读取收件箱的邮件
|
|
@@ -622,12 +644,14 @@ public class EmailParseService {
|
|
|
continue;
|
|
|
}
|
|
|
senderEmail = getSenderEmail(message);
|
|
|
- emailType = EmailUtil.getEmailTypeBySubject(emailTitle, emailTypeMap);
|
|
|
+ emailType = EmailUtil.getEmailTypeBySubject(emailTitle, this.getEmailType());
|
|
|
if (emailType == null) {
|
|
|
log.warn("{} 邮件不满足解析条件 -> 邮件主题:{},邮件日期:{}", folderName, emailTitle, emailDateStr);
|
|
|
continue;
|
|
|
}
|
|
|
- log.info("{} 邮件{} 基本信息获取完成,开始下载附件!邮件日期:{}", folderName, emailTitle, emailDateStr);
|
|
|
+ if (log.isInfoEnabled()) {
|
|
|
+ log.info("{} 邮件{} 基本信息获取完成,开始下载附件!邮件日期:{}", folderName, emailTitle, emailDateStr);
|
|
|
+ }
|
|
|
Object content = message.getContent();
|
|
|
|
|
|
if (content instanceof Multipart multipart) {
|