|
@@ -1,33 +1,54 @@
|
|
package com.simuwang.daq.service;
|
|
package com.simuwang.daq.service;
|
|
|
|
|
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
import cn.hutool.core.collection.CollUtil;
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
|
+import cn.hutool.core.exceptions.ExceptionUtil;
|
|
import cn.hutool.core.lang.Pair;
|
|
import cn.hutool.core.lang.Pair;
|
|
|
|
+import cn.hutool.core.map.MapUtil;
|
|
import cn.hutool.core.util.StrUtil;
|
|
import cn.hutool.core.util.StrUtil;
|
|
import com.simuwang.base.common.conts.ApplicationRuleFileConst;
|
|
import com.simuwang.base.common.conts.ApplicationRuleFileConst;
|
|
|
|
+import com.simuwang.base.common.conts.EmailDataDirectionConst;
|
|
import com.simuwang.base.common.conts.EmailFieldConst;
|
|
import com.simuwang.base.common.conts.EmailFieldConst;
|
|
import com.simuwang.base.common.util.ExcelUtil;
|
|
import com.simuwang.base.common.util.ExcelUtil;
|
|
|
|
+import com.simuwang.base.common.util.NavDataUtil;
|
|
import com.simuwang.base.mapper.EmailTemplateApplicationRuleMapper;
|
|
import com.simuwang.base.mapper.EmailTemplateApplicationRuleMapper;
|
|
import com.simuwang.base.mapper.EmailTemplateDataRuleMapper;
|
|
import com.simuwang.base.mapper.EmailTemplateDataRuleMapper;
|
|
import com.simuwang.base.mapper.EmailTemplateMappingMapper;
|
|
import com.simuwang.base.mapper.EmailTemplateMappingMapper;
|
|
|
|
+import com.simuwang.base.pojo.EmailFileContentDTO;
|
|
import com.simuwang.base.pojo.dos.EmailTemplateApplicationRuleDO;
|
|
import com.simuwang.base.pojo.dos.EmailTemplateApplicationRuleDO;
|
|
import com.simuwang.base.pojo.dos.EmailTemplateDataRuleDO;
|
|
import com.simuwang.base.pojo.dos.EmailTemplateDataRuleDO;
|
|
import com.simuwang.base.pojo.dos.EmailTemplateInfoDO;
|
|
import com.simuwang.base.pojo.dos.EmailTemplateInfoDO;
|
|
import com.simuwang.base.pojo.dto.EmailContentInfoDTO;
|
|
import com.simuwang.base.pojo.dto.EmailContentInfoDTO;
|
|
|
|
+import com.simuwang.base.pojo.dto.EmailFundNavDTO;
|
|
|
|
+import com.simuwang.base.pojo.dto.TemplateDataRuleDTO;
|
|
import com.simuwang.base.pojo.dto.TemplateDetailDTO;
|
|
import com.simuwang.base.pojo.dto.TemplateDetailDTO;
|
|
import org.apache.poi.ss.usermodel.Cell;
|
|
import org.apache.poi.ss.usermodel.Cell;
|
|
import org.apache.poi.ss.usermodel.Row;
|
|
import org.apache.poi.ss.usermodel.Row;
|
|
import org.apache.poi.ss.usermodel.Sheet;
|
|
import org.apache.poi.ss.usermodel.Sheet;
|
|
|
|
+import org.jsoup.Jsoup;
|
|
|
|
+import org.jsoup.nodes.Document;
|
|
|
|
+import org.jsoup.nodes.Element;
|
|
|
|
+import org.jsoup.select.Elements;
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
+import org.slf4j.LoggerFactory;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
-import java.util.Arrays;
|
|
|
|
-import java.util.HashMap;
|
|
|
|
-import java.util.List;
|
|
|
|
-import java.util.Map;
|
|
|
|
|
|
+import java.io.File;
|
|
|
|
+import java.util.*;
|
|
|
|
+import java.util.regex.Matcher;
|
|
|
|
+import java.util.regex.Pattern;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * @author mozuwen
|
|
|
|
+ * @date 2024-09-23
|
|
|
|
+ * @description 净值模板解析
|
|
|
|
+ */
|
|
@Service
|
|
@Service
|
|
public class EmailTemplateService {
|
|
public class EmailTemplateService {
|
|
|
|
|
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(EmailTemplateService.class);
|
|
|
|
+
|
|
private final EmailTemplateMappingMapper emailTemplateMappingMapper;
|
|
private final EmailTemplateMappingMapper emailTemplateMappingMapper;
|
|
private final EmailTemplateApplicationRuleMapper emailTemplateApplicationRuleMapper;
|
|
private final EmailTemplateApplicationRuleMapper emailTemplateApplicationRuleMapper;
|
|
private final EmailTemplateDataRuleMapper emailTemplateDataRuleMapper;
|
|
private final EmailTemplateDataRuleMapper emailTemplateDataRuleMapper;
|
|
@@ -51,19 +72,229 @@ public class EmailTemplateService {
|
|
this.emailTemplateDataRuleMapper = emailTemplateDataRuleMapper;
|
|
this.emailTemplateDataRuleMapper = emailTemplateDataRuleMapper;
|
|
}
|
|
}
|
|
|
|
|
|
- public List<TemplateDetailDTO> getTemplateDetail(EmailContentInfoDTO emailContentInfoDTO, String filePath) {
|
|
|
|
|
|
+
|
|
|
|
+ public List<EmailFundNavDTO> parseUsingTemplate(EmailContentInfoDTO emailContentInfoDTO) {
|
|
|
|
+ // 考虑文件为PDF,html,zip等情况 -> 将正文html和pdf文件转成Excel
|
|
|
|
+ List<EmailFileContentDTO> emailFileContentDTOList = getRealFilePath(emailContentInfoDTO.getFilePath(), emailContentInfoDTO.getEmailContent());
|
|
|
|
+ if (CollUtil.isEmpty(emailFileContentDTOList)) {
|
|
|
|
+ return CollUtil.newArrayList();
|
|
|
|
+ }
|
|
|
|
+ List<EmailFundNavDTO> emailFundNavDTOList = CollUtil.newArrayList();
|
|
|
|
+ for (EmailFileContentDTO emailFileContentDTO : emailFileContentDTOList) {
|
|
|
|
+ String filePath = emailFileContentDTO.getFilePath();
|
|
|
|
+ String textContent = emailFileContentDTO.getContent();
|
|
|
|
+ List<TemplateDetailDTO> templateDetailDTOList = getTemplateDetail(emailContentInfoDTO, textContent, filePath);
|
|
|
|
+ if (CollUtil.isEmpty(templateDetailDTOList)) {
|
|
|
|
+ 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)) {
|
|
|
|
+ emailFundNavDTOList.addAll(fundNavDTOList);
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error("净值模板解析报错 -> 模板id:{},文件:{},堆栈信息:{}", templateDetailDTO.getTemplateId(), filePath, ExceptionUtil.stacktraceToString(e));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 过滤掉相同的数据
|
|
|
|
+ return emailFundNavDTOList.stream().distinct().toList();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private List<EmailFundNavDTO> extraFundNav(String filePath, String textContent, TemplateDetailDTO templateDetailDTO) {
|
|
|
|
+ List<TemplateDataRuleDTO> dataRuleDetailList = templateDetailDTO.getDataRuleDetailList();
|
|
|
|
+ Map<String, String> fieldValueMap = MapUtil.newHashMap(8);
|
|
|
|
+ List<Map<String, String>> fieldValueMapList = CollUtil.newArrayList();
|
|
|
|
+ boolean hasParsedTableData = false;
|
|
|
|
+ Integer direction = templateDetailDTO.getDirection();
|
|
|
|
+
|
|
|
|
+ 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();
|
|
|
|
+ fieldValueMapList = parsedTableData(filePath, direction, dataRuleDTOS);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return buildEmailFundNavDTO(fieldValueMap, fieldValueMapList);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private List<Map<String, String>> parsedTableData(String filePath, Integer direction, List<TemplateDataRuleDTO> dataRuleDTOS) {
|
|
|
|
+ if (StrUtil.isBlank(filePath) || CollUtil.isEmpty(dataRuleDTOS)) {
|
|
|
|
+ return CollUtil.newArrayList();
|
|
|
|
+ }
|
|
|
|
+ Sheet sheet = ExcelUtil.getFirstSheet(filePath);
|
|
|
|
+ if (sheet == null) {
|
|
|
|
+ return CollUtil.newArrayList();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<Map<String, String>> fieldValueMapList = CollUtil.newArrayList();
|
|
|
|
+ Map<String, Pair<Integer, Integer>> fieldPositionMap = MapUtil.newHashMap();
|
|
|
|
+ Map<String, String> fieldPatternMap = MapUtil.newHashMap();
|
|
|
|
+ for (TemplateDataRuleDTO dataRuleDTO : dataRuleDTOS) {
|
|
|
|
+ Integer row = dataRuleDTO.getRow() - 1;
|
|
|
|
+ int column = columnLetterToIndex(dataRuleDTO.getColumn());
|
|
|
|
+ Pair<Integer, Integer> pair = new Pair<>(row, column);
|
|
|
|
+ fieldPositionMap.put(FILE_TYPE_MAP.get(dataRuleDTO.getFieldName()), pair);
|
|
|
|
+ if (StrUtil.isNotBlank(dataRuleDTO.getFieldRule())) {
|
|
|
|
+ fieldPatternMap.put(FILE_TYPE_MAP.get(dataRuleDTO.getFieldName()), dataRuleDTO.getFieldRule());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (direction.equals(EmailDataDirectionConst.ROW_DIRECTION_TYPE)) {
|
|
|
|
+ int startRow = fieldPositionMap.values().stream().map(Pair::getKey).min(Integer::compareTo).orElse(0);
|
|
|
|
+ for (int i = startRow + 1; i <= sheet.getLastRowNum(); i++) {
|
|
|
|
+ Map<String, String> fieldValueMap = MapUtil.newHashMap(8);
|
|
|
|
+ Row row = sheet.getRow(i);
|
|
|
|
+ if (row == null) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ for (Map.Entry<String, Pair<Integer, Integer>> fieldEntry : fieldPositionMap.entrySet()) {
|
|
|
|
+ String fieldName = fieldEntry.getKey();
|
|
|
|
+ String fieldRule = fieldPatternMap.get(fieldName);
|
|
|
|
+ int columnIndex = fieldEntry.getValue().getValue();
|
|
|
|
+ Cell cell = row.getCell(columnIndex);
|
|
|
|
+ String cellValue = getValueByPattern(ExcelUtil.getCellValue(cell), fieldRule);
|
|
|
|
+ fieldValueMap.put(fieldName, cellValue);
|
|
|
|
+ }
|
|
|
|
+ fieldValueMapList.add(fieldValueMap);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (direction.equals(EmailDataDirectionConst.COLUMN_DIRECTION_TYPE)) {
|
|
|
|
+ int startColumn = fieldPositionMap.values().stream().map(Pair::getValue).min(Integer::compareTo).orElse(0);
|
|
|
|
+ for (int columnNum = startColumn + 1; columnNum < EmailDataDirectionConst.MAX_ROW_COLUMN; columnNum++) {
|
|
|
|
+ Map<String, String> fieldValueMap = MapUtil.newHashMap();
|
|
|
|
+ for (Map.Entry<String, Pair<Integer, Integer>> fieldEntry : fieldPositionMap.entrySet()) {
|
|
|
|
+ String fieldName = fieldEntry.getKey();
|
|
|
|
+ String fieldRule = fieldPatternMap.get(fieldName);
|
|
|
|
+ Integer rowIndex = fieldEntry.getValue().getKey();
|
|
|
|
+ Integer columnIndex = fieldEntry.getValue().getValue();
|
|
|
|
+ Row row = sheet.getRow(rowIndex);
|
|
|
|
+ if (row == null) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ Cell cell = row.getCell(columnIndex);
|
|
|
|
+ String cellValue = getValueByPattern(ExcelUtil.getCellValue(cell), fieldRule);
|
|
|
|
+ fieldValueMap.put(fieldName, cellValue);
|
|
|
|
+ }
|
|
|
|
+ fieldValueMapList.add(fieldValueMap);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 表头和数据在同一个单元格
|
|
|
|
+ if (direction.equals(EmailDataDirectionConst.OTHER_DIRECTION_TYPE)) {
|
|
|
|
+ Map<String, String> fieldValueMap = MapUtil.newHashMap();
|
|
|
|
+ for (Map.Entry<String, Pair<Integer, Integer>> fieldEntry : fieldPositionMap.entrySet()) {
|
|
|
|
+ String fieldName = fieldEntry.getKey();
|
|
|
|
+ String fieldRule = fieldPatternMap.get(fieldName);
|
|
|
|
+ Integer rowIndex = fieldEntry.getValue().getKey();
|
|
|
|
+ Integer columnIndex = fieldEntry.getValue().getValue();
|
|
|
|
+ Row row = sheet.getRow(rowIndex);
|
|
|
|
+ if (row == null) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ Cell cell = row.getCell(columnIndex);
|
|
|
|
+ String cellValue = getValueByPattern(ExcelUtil.getCellValue(cell), fieldRule);
|
|
|
|
+ fieldValueMap.put(fieldName, cellValue);
|
|
|
|
+ }
|
|
|
|
+ fieldValueMapList.add(fieldValueMap);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return fieldValueMapList;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 根据正则表达式提取内容
|
|
|
|
+ *
|
|
|
|
+ * @param text 文本
|
|
|
|
+ * @param fieldRule 正则表达式
|
|
|
|
+ * @return 内容
|
|
|
|
+ */
|
|
|
|
+ private String getValueByPattern(String text, String fieldRule) {
|
|
|
|
+ if (StrUtil.isBlank(text) || StrUtil.isBlank(fieldRule)) {
|
|
|
|
+ return text;
|
|
|
|
+ }
|
|
|
|
+ Pattern pattern = Pattern.compile(fieldRule);
|
|
|
|
+ Matcher matcher = pattern.matcher(text);
|
|
|
|
+ while (matcher.find()) {
|
|
|
|
+ return matcher.group(1);
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 封装解析的数据为净值数据
|
|
|
|
+ *
|
|
|
|
+ * @param textFieldValueMap 从正文表格中解析到的数据
|
|
|
|
+ * @param excelFieldValueMapList 从正文文本中解析到的数据
|
|
|
|
+ * @return 净值数据
|
|
|
|
+ */
|
|
|
|
+ private List<EmailFundNavDTO> buildEmailFundNavDTO(Map<String, String> textFieldValueMap, List<Map<String, String>> excelFieldValueMapList) {
|
|
|
|
+ if (MapUtil.isEmpty(textFieldValueMap) && CollUtil.isEmpty(excelFieldValueMapList)) {
|
|
|
|
+ return CollUtil.newArrayList();
|
|
|
|
+ }
|
|
|
|
+ List<EmailFundNavDTO> fundNavDTOList = CollUtil.newArrayList();
|
|
|
|
+ if (CollUtil.isNotEmpty(excelFieldValueMapList)) {
|
|
|
|
+ for (Map<String, String> excelFieldValueMap : excelFieldValueMapList) {
|
|
|
|
+ fundNavDTOList.add(buildEmailFundNavDTO(excelFieldValueMap, textFieldValueMap));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (MapUtil.isNotEmpty(textFieldValueMap) && CollUtil.isEmpty(excelFieldValueMapList)) {
|
|
|
|
+ fundNavDTOList.add(buildEmailFundNavDTO(null, textFieldValueMap));
|
|
|
|
+ }
|
|
|
|
+ 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;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ public List<TemplateDetailDTO> getTemplateDetail(EmailContentInfoDTO emailContentInfoDTO, String textContent, String filePath) {
|
|
List<TemplateDetailDTO> templateDetailDTOList = CollUtil.newArrayList();
|
|
List<TemplateDetailDTO> templateDetailDTOList = CollUtil.newArrayList();
|
|
String senderEmail = emailContentInfoDTO.getSenderEmail();
|
|
String senderEmail = emailContentInfoDTO.getSenderEmail();
|
|
- if (StrUtil.isBlank(senderEmail) || StrUtil.isBlank(filePath)) {
|
|
|
|
|
|
+ if (StrUtil.isBlank(senderEmail)) {
|
|
return templateDetailDTOList;
|
|
return templateDetailDTOList;
|
|
}
|
|
}
|
|
|
|
+ // 1-excel类型,2-正文类型
|
|
|
|
+ int type = StrUtil.isNotBlank(emailContentInfoDTO.getFilePath()) && ExcelUtil.isHTML(emailContentInfoDTO.getFilePath()) ? 2 : 1;
|
|
// 查询邮箱配置的模板Id
|
|
// 查询邮箱配置的模板Id
|
|
- List<EmailTemplateInfoDO> emailTemplateInfoDOList = emailTemplateMappingMapper.queryByEmail(senderEmail);
|
|
|
|
|
|
+ List<EmailTemplateInfoDO> emailTemplateInfoDOList = emailTemplateMappingMapper.queryByEmail(senderEmail, type);
|
|
List<Integer> templateIdList = emailTemplateInfoDOList.stream().map(EmailTemplateInfoDO::getId).collect(Collectors.toList());
|
|
List<Integer> templateIdList = emailTemplateInfoDOList.stream().map(EmailTemplateInfoDO::getId).collect(Collectors.toList());
|
|
if (CollUtil.isEmpty(templateIdList)) {
|
|
if (CollUtil.isEmpty(templateIdList)) {
|
|
return templateDetailDTOList;
|
|
return templateDetailDTOList;
|
|
}
|
|
}
|
|
- Map<Integer, Integer> templateIdDirectionMap = emailTemplateInfoDOList.stream().collect(Collectors.toMap(EmailTemplateInfoDO::getId, EmailTemplateInfoDO::getDirection));
|
|
|
|
|
|
+ Map<Integer, EmailTemplateInfoDO> templateIdDirectionMap = emailTemplateInfoDOList.stream().collect(Collectors.toMap(EmailTemplateInfoDO::getId, v -> v));
|
|
// 查询模版适用性规则 -> 判断邮件是否满足模板适用性规则
|
|
// 查询模版适用性规则 -> 判断邮件是否满足模板适用性规则
|
|
List<EmailTemplateApplicationRuleDO> templateApplicationRuleDOList = emailTemplateApplicationRuleMapper.queryByTemplateId(templateIdList);
|
|
List<EmailTemplateApplicationRuleDO> templateApplicationRuleDOList = emailTemplateApplicationRuleMapper.queryByTemplateId(templateIdList);
|
|
if (CollUtil.isEmpty(templateApplicationRuleDOList)) {
|
|
if (CollUtil.isEmpty(templateApplicationRuleDOList)) {
|
|
@@ -78,66 +309,111 @@ public class EmailTemplateService {
|
|
Integer templateId = templateIdApplicationRule.getKey();
|
|
Integer templateId = templateIdApplicationRule.getKey();
|
|
List<EmailTemplateApplicationRuleDO> applicationRuleDOList = templateIdApplicationRule.getValue();
|
|
List<EmailTemplateApplicationRuleDO> applicationRuleDOList = templateIdApplicationRule.getValue();
|
|
// 判断是否满足模板适用性规则
|
|
// 判断是否满足模板适用性规则
|
|
- boolean isMatchTemplate = isMatchTemplate(emailContentInfoDTO.getEmailTitle(), emailContentInfoDTO.getFileName(), filePath, applicationRuleDOList);
|
|
|
|
|
|
+ boolean isMatchTemplate = isMatchTemplate(textContent, emailContentInfoDTO.getEmailTitle(), emailContentInfoDTO.getFileName(), filePath, applicationRuleDOList);
|
|
if (!isMatchTemplate) {
|
|
if (!isMatchTemplate) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
TemplateDetailDTO templateDetailDTO = new TemplateDetailDTO();
|
|
TemplateDetailDTO templateDetailDTO = new TemplateDetailDTO();
|
|
templateDetailDTO.setTemplateId(templateId);
|
|
templateDetailDTO.setTemplateId(templateId);
|
|
- // 模板的数据行方向:默认为行
|
|
|
|
- Integer directionOrDefault = templateIdDirectionMap.getOrDefault(templateId, 1);
|
|
|
|
- templateDetailDTO.setDirection(directionOrDefault);
|
|
|
|
- Map<String, Pair<Integer, Integer>> fieldPositionMap = getFieldPosition(templateIdDataRuleMap.get(templateId));
|
|
|
|
- templateDetailDTO.setFieldPositionMap(fieldPositionMap);
|
|
|
|
|
|
+ EmailTemplateInfoDO emailTemplateInfoDO = templateIdDirectionMap.get(templateId);
|
|
|
|
+ templateDetailDTO.setDirection(emailTemplateInfoDO.getDirection());
|
|
|
|
+ templateDetailDTO.setType(emailTemplateInfoDO.getType());
|
|
|
|
+ templateDetailDTO.setStartIndex(emailTemplateInfoDO.getStartIndex());
|
|
|
|
+ templateDetailDTO.setEndIndex(emailTemplateInfoDO.getEndIndex());
|
|
|
|
+
|
|
|
|
+ List<EmailTemplateDataRuleDO> dataRuleDOList = templateIdDataRuleMap.get(templateId);
|
|
|
|
+ List<TemplateDataRuleDTO> dataRuleDetailList = dataRuleDOList.stream().map(e -> BeanUtil.copyProperties(e, TemplateDataRuleDTO.class)).toList();
|
|
|
|
+ templateDetailDTO.setDataRuleDetailList(dataRuleDetailList);
|
|
templateDetailDTOList.add(templateDetailDTO);
|
|
templateDetailDTOList.add(templateDetailDTO);
|
|
}
|
|
}
|
|
return templateDetailDTOList;
|
|
return templateDetailDTOList;
|
|
}
|
|
}
|
|
|
|
|
|
- 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);
|
|
|
|
|
|
+ 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)) {
|
|
|
|
|
|
- private boolean isMatchTemplate(String emailTitle, String fileName, String filePath, List<EmailTemplateApplicationRuleDO> applicationRuleDOList) {
|
|
|
|
- int notMatchCount = 0;
|
|
|
|
- for (EmailTemplateApplicationRuleDO applicationRuleDO : applicationRuleDOList) {
|
|
|
|
- if (!isMathApplicationRule(applicationRuleDO, emailTitle, fileName, filePath)) {
|
|
|
|
- notMatchCount++;
|
|
|
|
|
|
+ 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 notMatchCount == 0;
|
|
|
|
|
|
+ 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();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 判断邮件是否满足模板的适用性规则
|
|
|
|
+ *
|
|
|
|
+ * @param emailContent 邮件正文内容(已转成纯文本,以换行符分割每行内容)
|
|
|
|
+ * @param emailTitle 邮件主题
|
|
|
|
+ * @param fileName 附件名称
|
|
|
|
+ * @param filePath 文件路径(邮件正文html转成)
|
|
|
|
+ * @param applicationRuleDOList 模板配置的适用性规则列表
|
|
|
|
+ * @return true or false
|
|
|
|
+ */
|
|
|
|
+ private boolean isMatchTemplate(String emailContent, String emailTitle, String fileName,
|
|
|
|
+ String filePath, List<EmailTemplateApplicationRuleDO> applicationRuleDOList) {
|
|
|
|
+ return applicationRuleDOList.stream()
|
|
|
|
+ .allMatch(e -> isMathApplicationRule(e, emailContent, emailTitle, fileName, filePath));
|
|
}
|
|
}
|
|
|
|
|
|
- private boolean isMathApplicationRule(EmailTemplateApplicationRuleDO applicationRuleDO, String emailTitle, String fileName, String filePath) {
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 判断邮件是否满足模板的某条适用性规则
|
|
|
|
+ *
|
|
|
|
+ * @param applicationRuleDO 适用性规则
|
|
|
|
+ * @param emailContent 邮件正文内容(可为空)
|
|
|
|
+ * @param emailTitle 邮件主题
|
|
|
|
+ * @param fileName 附件名称
|
|
|
|
+ * @param filePath 文件路径(邮件正文html转成)
|
|
|
|
+ * @return true or false
|
|
|
|
+ */
|
|
|
|
+ private boolean isMathApplicationRule(EmailTemplateApplicationRuleDO applicationRuleDO, String emailContent, String emailTitle, String fileName, String filePath) {
|
|
boolean isMatch = true;
|
|
boolean isMatch = true;
|
|
Integer type = applicationRuleDO.getType();
|
|
Integer type = applicationRuleDO.getType();
|
|
String containKeyword = applicationRuleDO.getContainKeyword();
|
|
String containKeyword = applicationRuleDO.getContainKeyword();
|
|
String notContainKeyword = applicationRuleDO.getNotContainKeyword();
|
|
String notContainKeyword = applicationRuleDO.getNotContainKeyword();
|
|
if (ApplicationRuleFileConst.EMAIL_TITLE_FILE.equals(type)) {
|
|
if (ApplicationRuleFileConst.EMAIL_TITLE_FILE.equals(type)) {
|
|
- if (StrUtil.isNotBlank(containKeyword)) {
|
|
|
|
- isMatch = Arrays.stream(containKeyword.split(",")).allMatch(emailTitle::contains);
|
|
|
|
- }
|
|
|
|
- if (StrUtil.isNotBlank(notContainKeyword)) {
|
|
|
|
- isMatch = Arrays.stream(notContainKeyword.split(",")).noneMatch(emailTitle::contains) && isMatch;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (ApplicationRuleFileConst.EMAIL_FILE_NAME_FILE.equals(type)) {
|
|
|
|
- if (StrUtil.isNotBlank(containKeyword)) {
|
|
|
|
- isMatch = Arrays.stream(containKeyword.split(",")).allMatch(fileName::contains);
|
|
|
|
- }
|
|
|
|
- if (StrUtil.isNotBlank(notContainKeyword)) {
|
|
|
|
- isMatch = Arrays.stream(notContainKeyword.split(",")).noneMatch(fileName::contains) && isMatch;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (ApplicationRuleFileConst.EMAIL_EXCEL_CONTENT_FILE.equals(type)) {
|
|
|
|
|
|
+ isMatch = iskeywordMatch(emailTitle, containKeyword, notContainKeyword);
|
|
|
|
+ } else if (ApplicationRuleFileConst.EMAIL_CONTENT_FILE.equals(type)) {
|
|
|
|
+ isMatch = iskeywordMatch(emailContent, containKeyword, notContainKeyword);
|
|
|
|
+ } else if (ApplicationRuleFileConst.EMAIL_FILE_NAME_FILE.equals(type)) {
|
|
|
|
+ isMatch = iskeywordMatch(fileName, containKeyword, notContainKeyword);
|
|
|
|
+ } else if (ApplicationRuleFileConst.EMAIL_EXCEL_CONTENT_FILE.equals(type)) {
|
|
if (StrUtil.isNotBlank(fileName) && ExcelUtil.isExcel(fileName)) {
|
|
if (StrUtil.isNotBlank(fileName) && ExcelUtil.isExcel(fileName)) {
|
|
if (applicationRuleDO.getRow() == null || StrUtil.isBlank(applicationRuleDO.getColumn())) {
|
|
if (applicationRuleDO.getRow() == null || StrUtil.isBlank(applicationRuleDO.getColumn())) {
|
|
return false;
|
|
return false;
|
|
@@ -159,17 +435,30 @@ public class EmailTemplateService {
|
|
if (StrUtil.isBlank(cellValue)) {
|
|
if (StrUtil.isBlank(cellValue)) {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
- if (StrUtil.isNotBlank(containKeyword)) {
|
|
|
|
- isMatch = Arrays.stream(containKeyword.split(",")).allMatch(cellValue::contains);
|
|
|
|
- }
|
|
|
|
- if (StrUtil.isNotBlank(notContainKeyword)) {
|
|
|
|
- isMatch = Arrays.stream(notContainKeyword.split(",")).noneMatch(cellValue::contains) && isMatch;
|
|
|
|
- }
|
|
|
|
|
|
+ isMatch = iskeywordMatch(cellValue, containKeyword, notContainKeyword);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return isMatch;
|
|
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);
|
|
|
|
+ }
|
|
|
|
+ return fieldPositionMap;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将数据列转成数字型索引
|
|
|
|
+ *
|
|
|
|
+ * @param columnName 数据列名:如A,B,....
|
|
|
|
+ * @return 数据列数字型索引
|
|
|
|
+ */
|
|
public static int columnLetterToIndex(String columnName) {
|
|
public static int columnLetterToIndex(String columnName) {
|
|
int columnIndex = 0;
|
|
int columnIndex = 0;
|
|
int columnLength = columnName.length();
|
|
int columnLength = columnName.length();
|
|
@@ -184,4 +473,25 @@ public class EmailTemplateService {
|
|
return columnIndex;
|
|
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;
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|