|
@@ -72,7 +72,6 @@ public class EmailTemplateService {
|
|
|
this.emailTemplateDataRuleMapper = emailTemplateDataRuleMapper;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
public List<EmailFundNavDTO> parseUsingTemplate(EmailContentInfoDTO emailContentInfoDTO) {
|
|
|
// 考虑文件为PDF,html,zip等情况 -> 将正文html和pdf文件转成Excel
|
|
|
List<EmailFileContentDTO> emailFileContentDTOList = getRealFilePath(emailContentInfoDTO.getFilePath(), emailContentInfoDTO.getEmailContent());
|
|
@@ -83,29 +82,39 @@ public class EmailTemplateService {
|
|
|
for (EmailFileContentDTO emailFileContentDTO : emailFileContentDTOList) {
|
|
|
String filePath = emailFileContentDTO.getFilePath();
|
|
|
String textContent = emailFileContentDTO.getContent();
|
|
|
+ // 获取模板信息
|
|
|
List<TemplateDetailDTO> templateDetailDTOList = getTemplateDetail(emailContentInfoDTO, textContent, filePath);
|
|
|
if (CollUtil.isEmpty(templateDetailDTOList)) {
|
|
|
+ log.info("未匹配模板 -> 参数:{}", emailFileContentDTO);
|
|
|
return CollUtil.newArrayList();
|
|
|
}
|
|
|
// 按照模板分别进行解析
|
|
|
for (TemplateDetailDTO templateDetailDTO : templateDetailDTOList) {
|
|
|
try {
|
|
|
- // 按照模板配置规则解析
|
|
|
List<EmailFundNavDTO> fundNavDTOList = extraFundNav(filePath, textContent, templateDetailDTO);
|
|
|
fundNavDTOList = fundNavDTOList.stream().filter(NavDataUtil::navDataFormatCheck).toList();
|
|
|
if (CollUtil.isNotEmpty(fundNavDTOList)) {
|
|
|
- fundNavDTOList.forEach(e->e.setTemplateId(templateDetailDTO.getTemplateId()));
|
|
|
+ fundNavDTOList.forEach(e -> e.setTemplateId(templateDetailDTO.getTemplateId()));
|
|
|
emailFundNavDTOList.addAll(fundNavDTOList);
|
|
|
}
|
|
|
+ log.info("模板配置规则解析不到数据 -> 模板id:{}", templateDetailDTO.getTemplateId());
|
|
|
} catch (Exception e) {
|
|
|
log.error("净值模板解析报错 -> 模板id:{},文件:{},堆栈信息:{}", templateDetailDTO.getTemplateId(), filePath, ExceptionUtil.stacktraceToString(e));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- // 过滤掉相同的数据
|
|
|
+ // 过滤掉相同的数据(考虑到多个模板解析到相同数据的情况)
|
|
|
return emailFundNavDTOList.stream().distinct().toList();
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 根据模板信息提取净值数据
|
|
|
+ *
|
|
|
+ * @param filePath 文件路径(excel类型)
|
|
|
+ * @param textContent 邮件正文内容
|
|
|
+ * @param templateDetailDTO 模板配置信息
|
|
|
+ * @return 净值数据
|
|
|
+ */
|
|
|
private List<EmailFundNavDTO> extraFundNav(String filePath, String textContent, TemplateDetailDTO templateDetailDTO) {
|
|
|
List<TemplateDataRuleDTO> dataRuleDetailList = templateDetailDTO.getDataRuleDetailList();
|
|
|
Map<String, String> fieldValueMap = MapUtil.newHashMap(8);
|
|
@@ -116,10 +125,12 @@ public class EmailTemplateService {
|
|
|
for (TemplateDataRuleDTO templateDataRuleDTO : dataRuleDetailList) {
|
|
|
Integer fieldName = templateDataRuleDTO.getFieldName();
|
|
|
Integer position = templateDataRuleDTO.getPosition();
|
|
|
+ // 提取位置-正文
|
|
|
if (position == 1) {
|
|
|
String valueByPattern = getValueByPattern(textContent, templateDataRuleDTO.getFieldRule());
|
|
|
fieldValueMap.put(FILE_TYPE_MAP.get(fieldName), valueByPattern);
|
|
|
}
|
|
|
+ // 提取位置-正文表格或附件表格(表格数据提取一次后不再提取)
|
|
|
if (position == 2 && !hasParsedTableData) {
|
|
|
hasParsedTableData = true;
|
|
|
List<TemplateDataRuleDTO> dataRuleDTOS = dataRuleDetailList.stream().filter(e -> e.getPosition() == 2).toList();
|
|
@@ -129,6 +140,14 @@ public class EmailTemplateService {
|
|
|
return buildEmailFundNavDTO(fieldValueMap, fieldValueMapList);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 根据数据提取规则提取数据
|
|
|
+ *
|
|
|
+ * @param filePath 文件路径(excel类型)
|
|
|
+ * @param direction 数据方向:1-行,2-列,3-其他(无规律)
|
|
|
+ * @param dataRuleDTOS 数据提取规则
|
|
|
+ * @return 数据字段-字段值映射关系
|
|
|
+ */
|
|
|
private List<Map<String, String>> parsedTableData(String filePath, Integer direction, List<TemplateDataRuleDTO> dataRuleDTOS) {
|
|
|
if (StrUtil.isBlank(filePath) || CollUtil.isEmpty(dataRuleDTOS)) {
|
|
|
return CollUtil.newArrayList();
|
|
@@ -253,34 +272,14 @@ public class EmailTemplateService {
|
|
|
return fundNavDTOList;
|
|
|
}
|
|
|
|
|
|
- private EmailFundNavDTO buildEmailFundNavDTO(Map<String, String> excelFieldValueMap, Map<String, String> textFieldValueMap) {
|
|
|
- EmailFundNavDTO fundNavDTO = new EmailFundNavDTO();
|
|
|
- String registerNumber = MapUtil.isNotEmpty(excelFieldValueMap) && StrUtil.isNotBlank(excelFieldValueMap.get(EmailFieldConst.REGISTER_NUMBER))
|
|
|
- ? excelFieldValueMap.get(EmailFieldConst.REGISTER_NUMBER) : MapUtil.isNotEmpty(textFieldValueMap) ? textFieldValueMap.get(EmailFieldConst.REGISTER_NUMBER) : null;
|
|
|
- String fundName = MapUtil.isNotEmpty(excelFieldValueMap) && StrUtil.isNotBlank(excelFieldValueMap.get(EmailFieldConst.FUND_NAME))
|
|
|
- ? excelFieldValueMap.get(EmailFieldConst.FUND_NAME) : MapUtil.isNotEmpty(textFieldValueMap) ? textFieldValueMap.get(EmailFieldConst.FUND_NAME) : null;
|
|
|
- String priceDate = MapUtil.isNotEmpty(excelFieldValueMap) && StrUtil.isNotBlank(excelFieldValueMap.get(EmailFieldConst.PRICE_DATE))
|
|
|
- ? excelFieldValueMap.get(EmailFieldConst.PRICE_DATE) : MapUtil.isNotEmpty(textFieldValueMap) ? textFieldValueMap.get(EmailFieldConst.PRICE_DATE) : null;
|
|
|
- String nav = MapUtil.isNotEmpty(excelFieldValueMap) && StrUtil.isNotBlank(excelFieldValueMap.get(EmailFieldConst.NAV))
|
|
|
- ? excelFieldValueMap.get(EmailFieldConst.NAV) : MapUtil.isNotEmpty(textFieldValueMap) ? textFieldValueMap.get(EmailFieldConst.NAV) : null;
|
|
|
- String cumulativeNavWithdrawal = MapUtil.isNotEmpty(excelFieldValueMap) && StrUtil.isNotBlank(excelFieldValueMap.get(EmailFieldConst.CUMULATIVE_NAV_WITHDRAWAL))
|
|
|
- ? excelFieldValueMap.get(EmailFieldConst.CUMULATIVE_NAV_WITHDRAWAL) : MapUtil.isNotEmpty(textFieldValueMap) ? textFieldValueMap.get(EmailFieldConst.CUMULATIVE_NAV_WITHDRAWAL) : null;
|
|
|
- String assetShare = MapUtil.isNotEmpty(excelFieldValueMap) && StrUtil.isNotBlank(excelFieldValueMap.get(EmailFieldConst.ASSET_SHARE))
|
|
|
- ? excelFieldValueMap.get(EmailFieldConst.ASSET_SHARE) : MapUtil.isNotEmpty(textFieldValueMap) ? textFieldValueMap.get(EmailFieldConst.ASSET_SHARE) : null;
|
|
|
- String assetNet = MapUtil.isNotEmpty(excelFieldValueMap) && StrUtil.isNotBlank(excelFieldValueMap.get(EmailFieldConst.ASSET_NET))
|
|
|
- ? excelFieldValueMap.get(EmailFieldConst.ASSET_NET) : MapUtil.isNotEmpty(textFieldValueMap) ? textFieldValueMap.get(EmailFieldConst.ASSET_NET) : null;
|
|
|
-
|
|
|
- fundNavDTO.setRegisterNumber(registerNumber);
|
|
|
- fundNavDTO.setFundName(fundName);
|
|
|
- fundNavDTO.setPriceDate(priceDate);
|
|
|
- fundNavDTO.setNav(nav);
|
|
|
- fundNavDTO.setCumulativeNavWithdrawal(cumulativeNavWithdrawal);
|
|
|
- fundNavDTO.setAssetShare(assetShare);
|
|
|
- fundNavDTO.setAssetNet(assetNet);
|
|
|
- return fundNavDTO;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
+ /**
|
|
|
+ * 获取模板配置信息
|
|
|
+ *
|
|
|
+ * @param emailContentInfoDTO 采集到的邮件原始信息
|
|
|
+ * @param textContent 邮件正文内容
|
|
|
+ * @param filePath 文件路径(excel类型)
|
|
|
+ * @return 模板配置信息列表
|
|
|
+ */
|
|
|
public List<TemplateDetailDTO> getTemplateDetail(EmailContentInfoDTO emailContentInfoDTO, String textContent, String filePath) {
|
|
|
List<TemplateDetailDTO> templateDetailDTOList = CollUtil.newArrayList();
|
|
|
String senderEmail = emailContentInfoDTO.getSenderEmail();
|
|
@@ -330,53 +329,6 @@ public class EmailTemplateService {
|
|
|
return templateDetailDTOList;
|
|
|
}
|
|
|
|
|
|
- public List<EmailFileContentDTO> getRealFilePath(String filePath, String content) {
|
|
|
- List<EmailFileContentDTO> emailFileContentDTOList = CollUtil.newArrayList();
|
|
|
- if (StrUtil.isBlank(filePath)) {
|
|
|
- return emailFileContentDTOList;
|
|
|
- }
|
|
|
- if (ExcelUtil.isExcel(filePath)) {
|
|
|
- emailFileContentDTOList.add(new EmailFileContentDTO(filePath, null));
|
|
|
- } else if (ExcelUtil.isHTML(filePath)) {
|
|
|
- String excelFilePath = filePath.replace(".html", ".xlsx");
|
|
|
- excelFilePath = ExcelUtil.contentConvertToExcel(content, excelFilePath);
|
|
|
- emailFileContentDTOList.add(new EmailFileContentDTO(excelFilePath, getTextFromHtml(content)));
|
|
|
- } else if (ExcelUtil.isPdf(filePath)) {
|
|
|
- String excelFilePath = filePath.replace(".pdf", ".xlsx").replace(".PDF", ".xlsx");
|
|
|
- excelFilePath = ExcelUtil.pdfConvertToExcel(filePath, excelFilePath);
|
|
|
- emailFileContentDTOList.add(new EmailFileContentDTO(excelFilePath, null));
|
|
|
- } else if (ExcelUtil.isZip(filePath)) {
|
|
|
-
|
|
|
- String destPath = filePath.replaceAll(".zip", "").replaceAll(".ZIP", "");
|
|
|
- List<String> dir = ExcelUtil.extractCompressedFiles(filePath, destPath);
|
|
|
- for (String zipFilePath : dir) {
|
|
|
- File file = new File(zipFilePath);
|
|
|
- if (file.isDirectory()) {
|
|
|
- for (String navFilePath : Objects.requireNonNull(file.list())) {
|
|
|
- Optional.ofNullable(getRealFilePath(navFilePath, null)).ifPresent(emailFileContentDTOList::addAll);
|
|
|
- }
|
|
|
- } else {
|
|
|
- Optional.ofNullable(getRealFilePath(zipFilePath, null)).ifPresent(emailFileContentDTOList::addAll);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return emailFileContentDTOList;
|
|
|
- }
|
|
|
-
|
|
|
- private String getTextFromHtml(String htmlContent) {
|
|
|
- if (StrUtil.isBlank(htmlContent)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- Document doc = Jsoup.parse(htmlContent);
|
|
|
- if (doc == null) {
|
|
|
- return htmlContent;
|
|
|
- }
|
|
|
- Elements allElements = doc.getAllElements();
|
|
|
- String textContent = allElements.stream().map(Element::ownText).collect(Collectors.joining("\n"));
|
|
|
-
|
|
|
- return textContent.trim();
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 判断邮件是否满足模板的适用性规则
|
|
|
*
|
|
@@ -442,16 +394,104 @@ public class EmailTemplateService {
|
|
|
return isMatch;
|
|
|
}
|
|
|
|
|
|
- private Map<String, Pair<Integer, Integer>> getFieldPosition(List<EmailTemplateDataRuleDO> emailTemplateDataRuleDOList) {
|
|
|
- Map<String, Pair<Integer, Integer>> fieldPositionMap = new HashMap<>();
|
|
|
- for (EmailTemplateDataRuleDO templateDataRuleDO : emailTemplateDataRuleDOList) {
|
|
|
- Integer fieldName = templateDataRuleDO.getFieldName();
|
|
|
- String fieldValue = FILE_TYPE_MAP.get(fieldName);
|
|
|
- int column = columnLetterToIndex(templateDataRuleDO.getColumn());
|
|
|
- Pair<Integer, Integer> pair = new Pair<>(templateDataRuleDO.getRow() - 1, column);
|
|
|
- fieldPositionMap.put(fieldValue, pair);
|
|
|
+ /**
|
|
|
+ * 判断字符串是否包含指定的关键词列表,并且不包含指定的排除关键词列表。
|
|
|
+ *
|
|
|
+ * @param emailTitle 要检查的字符串
|
|
|
+ * @param containKeyword 逗号分隔的必须包含的关键词列表
|
|
|
+ * @param notContainKeyword 逗号分隔的必须不包含的关键词列表
|
|
|
+ * @return true or false
|
|
|
+ */
|
|
|
+ public boolean iskeywordMatch(String emailTitle, String containKeyword, String notContainKeyword) {
|
|
|
+ boolean isMatch = true;
|
|
|
+ if (StrUtil.isNotBlank(containKeyword)) {
|
|
|
+ isMatch &= Arrays.stream(containKeyword.split(","))
|
|
|
+ .allMatch(emailTitle::contains);
|
|
|
+ }
|
|
|
+ if (StrUtil.isNotBlank(notContainKeyword)) {
|
|
|
+ isMatch &= Arrays.stream(notContainKeyword.split(","))
|
|
|
+ .noneMatch(emailTitle::contains);
|
|
|
+ }
|
|
|
+ return isMatch;
|
|
|
+ }
|
|
|
+
|
|
|
+ private EmailFundNavDTO buildEmailFundNavDTO(Map<String, String> excelFieldValueMap, Map<String, String> textFieldValueMap) {
|
|
|
+ EmailFundNavDTO fundNavDTO = new EmailFundNavDTO();
|
|
|
+ String registerNumber = MapUtil.isNotEmpty(excelFieldValueMap) && StrUtil.isNotBlank(excelFieldValueMap.get(EmailFieldConst.REGISTER_NUMBER))
|
|
|
+ ? excelFieldValueMap.get(EmailFieldConst.REGISTER_NUMBER) : MapUtil.isNotEmpty(textFieldValueMap) ? textFieldValueMap.get(EmailFieldConst.REGISTER_NUMBER) : null;
|
|
|
+ String fundName = MapUtil.isNotEmpty(excelFieldValueMap) && StrUtil.isNotBlank(excelFieldValueMap.get(EmailFieldConst.FUND_NAME))
|
|
|
+ ? excelFieldValueMap.get(EmailFieldConst.FUND_NAME) : MapUtil.isNotEmpty(textFieldValueMap) ? textFieldValueMap.get(EmailFieldConst.FUND_NAME) : null;
|
|
|
+ String priceDate = MapUtil.isNotEmpty(excelFieldValueMap) && StrUtil.isNotBlank(excelFieldValueMap.get(EmailFieldConst.PRICE_DATE))
|
|
|
+ ? excelFieldValueMap.get(EmailFieldConst.PRICE_DATE) : MapUtil.isNotEmpty(textFieldValueMap) ? textFieldValueMap.get(EmailFieldConst.PRICE_DATE) : null;
|
|
|
+ String nav = MapUtil.isNotEmpty(excelFieldValueMap) && StrUtil.isNotBlank(excelFieldValueMap.get(EmailFieldConst.NAV))
|
|
|
+ ? excelFieldValueMap.get(EmailFieldConst.NAV) : MapUtil.isNotEmpty(textFieldValueMap) ? textFieldValueMap.get(EmailFieldConst.NAV) : null;
|
|
|
+ String cumulativeNavWithdrawal = MapUtil.isNotEmpty(excelFieldValueMap) && StrUtil.isNotBlank(excelFieldValueMap.get(EmailFieldConst.CUMULATIVE_NAV_WITHDRAWAL))
|
|
|
+ ? excelFieldValueMap.get(EmailFieldConst.CUMULATIVE_NAV_WITHDRAWAL) : MapUtil.isNotEmpty(textFieldValueMap) ? textFieldValueMap.get(EmailFieldConst.CUMULATIVE_NAV_WITHDRAWAL) : null;
|
|
|
+ String assetShare = MapUtil.isNotEmpty(excelFieldValueMap) && StrUtil.isNotBlank(excelFieldValueMap.get(EmailFieldConst.ASSET_SHARE))
|
|
|
+ ? excelFieldValueMap.get(EmailFieldConst.ASSET_SHARE) : MapUtil.isNotEmpty(textFieldValueMap) ? textFieldValueMap.get(EmailFieldConst.ASSET_SHARE) : null;
|
|
|
+ String assetNet = MapUtil.isNotEmpty(excelFieldValueMap) && StrUtil.isNotBlank(excelFieldValueMap.get(EmailFieldConst.ASSET_NET))
|
|
|
+ ? excelFieldValueMap.get(EmailFieldConst.ASSET_NET) : MapUtil.isNotEmpty(textFieldValueMap) ? textFieldValueMap.get(EmailFieldConst.ASSET_NET) : null;
|
|
|
+
|
|
|
+ fundNavDTO.setRegisterNumber(registerNumber);
|
|
|
+ fundNavDTO.setFundName(fundName);
|
|
|
+ fundNavDTO.setPriceDate(priceDate);
|
|
|
+ fundNavDTO.setNav(nav);
|
|
|
+ fundNavDTO.setCumulativeNavWithdrawal(cumulativeNavWithdrawal);
|
|
|
+ fundNavDTO.setAssetShare(assetShare);
|
|
|
+ fundNavDTO.setAssetNet(assetNet);
|
|
|
+ return fundNavDTO;
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<EmailFileContentDTO> getRealFilePath(String filePath, String content) {
|
|
|
+ List<EmailFileContentDTO> emailFileContentDTOList = CollUtil.newArrayList();
|
|
|
+ if (StrUtil.isBlank(filePath)) {
|
|
|
+ return emailFileContentDTOList;
|
|
|
}
|
|
|
- return fieldPositionMap;
|
|
|
+ if (ExcelUtil.isExcel(filePath)) {
|
|
|
+ emailFileContentDTOList.add(new EmailFileContentDTO(filePath, null));
|
|
|
+ } else if (ExcelUtil.isHTML(filePath)) {
|
|
|
+ String excelFilePath = filePath.replace(".html", ".xlsx");
|
|
|
+ excelFilePath = ExcelUtil.contentConvertToExcel(content, excelFilePath);
|
|
|
+ emailFileContentDTOList.add(new EmailFileContentDTO(excelFilePath, getTextFromHtml(content)));
|
|
|
+ } else if (ExcelUtil.isPdf(filePath)) {
|
|
|
+ String excelFilePath = filePath.replace(".pdf", ".xlsx").replace(".PDF", ".xlsx");
|
|
|
+ excelFilePath = ExcelUtil.pdfConvertToExcel(filePath, excelFilePath);
|
|
|
+ emailFileContentDTOList.add(new EmailFileContentDTO(excelFilePath, null));
|
|
|
+ } else if (ExcelUtil.isZip(filePath)) {
|
|
|
+ String destPath = filePath.replaceAll(".zip", "").replaceAll(".ZIP", "");
|
|
|
+ List<String> dir = ExcelUtil.extractCompressedFiles(filePath, destPath);
|
|
|
+ for (String zipFilePath : dir) {
|
|
|
+ File file = new File(zipFilePath);
|
|
|
+ if (file.isDirectory()) {
|
|
|
+ for (String navFilePath : Objects.requireNonNull(file.list())) {
|
|
|
+ Optional.ofNullable(getRealFilePath(navFilePath, null)).ifPresent(emailFileContentDTOList::addAll);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ Optional.ofNullable(getRealFilePath(zipFilePath, null)).ifPresent(emailFileContentDTOList::addAll);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return emailFileContentDTOList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取html所有文本内容
|
|
|
+ *
|
|
|
+ * @param htmlContent 内容(html格式)
|
|
|
+ * @return 文本内容
|
|
|
+ */
|
|
|
+ private String getTextFromHtml(String htmlContent) {
|
|
|
+ if (StrUtil.isBlank(htmlContent)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ Document doc = Jsoup.parse(htmlContent);
|
|
|
+ if (doc == null) {
|
|
|
+ return htmlContent;
|
|
|
+ }
|
|
|
+ Elements allElements = doc.getAllElements();
|
|
|
+ String textContent = allElements.stream().map(Element::ownText).collect(Collectors.joining("\n"));
|
|
|
+
|
|
|
+ return textContent.trim();
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -473,26 +513,4 @@ public class EmailTemplateService {
|
|
|
}
|
|
|
return columnIndex;
|
|
|
}
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断字符串是否包含指定的关键词列表,并且不包含指定的排除关键词列表。
|
|
|
- *
|
|
|
- * @param emailTitle 要检查的字符串
|
|
|
- * @param containKeyword 逗号分隔的必须包含的关键词列表
|
|
|
- * @param notContainKeyword 逗号分隔的必须不包含的关键词列表
|
|
|
- * @return true or false
|
|
|
- */
|
|
|
- public boolean iskeywordMatch(String emailTitle, String containKeyword, String notContainKeyword) {
|
|
|
- boolean isMatch = true;
|
|
|
- if (StrUtil.isNotBlank(containKeyword)) {
|
|
|
- isMatch &= Arrays.stream(containKeyword.split(","))
|
|
|
- .allMatch(emailTitle::contains);
|
|
|
- }
|
|
|
- if (StrUtil.isNotBlank(notContainKeyword)) {
|
|
|
- isMatch &= Arrays.stream(notContainKeyword.split(","))
|
|
|
- .noneMatch(emailTitle::contains);
|
|
|
- }
|
|
|
- return isMatch;
|
|
|
- }
|
|
|
-
|
|
|
}
|