package com.simuwang.daq.service; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.StrUtil; import com.simuwang.base.common.conts.EmailTypeConst; import com.simuwang.base.common.util.ExcelUtil; import com.simuwang.base.pojo.dto.EmailContentInfoDTO; import com.simuwang.base.pojo.dto.EmailFundNavDTO; import com.simuwang.base.pojo.dto.ValuationPdfTransformToExcelDTO; import com.simuwang.base.pojo.valuation.AssetsValuationResult; import com.simuwang.base.pojo.valuation.ParseValuationInfo; import com.simuwang.base.pojo.valuation.ValuationNeedParseParam; import org.springframework.stereotype.Component; import java.io.File; import java.util.*; import java.util.stream.Collectors; /** * @author mozuwen * @date 2024-09-12 * @description 估值表邮件解析器 */ @Component public class ValuationEmailParser extends AbstractEmailParser { private final ValuationParseService valuationParseService; private final PdfToExcelService pdfToExcelService; public ValuationEmailParser(ValuationParseService valuationParseService, PdfToExcelService pdfToExcelService) { this.valuationParseService = valuationParseService; this.pdfToExcelService = pdfToExcelService; } @Override public boolean isSupport(Integer emailType) { return EmailTypeConst.VALUATION_EMAIL_TYPE.equals(emailType); } @Override public List parse(EmailContentInfoDTO emailContentInfoDTO, Map> emailFieldMap) { List emailFundNavDTOList = CollUtil.newArrayList(); boolean isSatisfiedParse = emailContentInfoDTO != null && StrUtil.isNotBlank(emailContentInfoDTO.getFileName()) && (ExcelUtil.isExcel(emailContentInfoDTO.getFileName()) || ExcelUtil.isPdf(emailContentInfoDTO.getFileName()) || ExcelUtil.isZip(emailContentInfoDTO.getFileName())); if (!isSatisfiedParse) { return emailFundNavDTOList; } List valuationNeedParseParams = buildValuationNeedParseParam(emailContentInfoDTO); List recordList = valuationParseService.parseValuationExcel(valuationNeedParseParams); if (CollUtil.isNotEmpty(recordList)) { List parseSuccessList = recordList.stream() .filter(e -> e.getSuccess() == 1 || (StrUtil.isNotBlank(e.getMsg()) && "未匹配基金".equals(e.getMsg()))).collect(Collectors.toList()); List fundNavDTOList = convertToFundNavDTO(parseSuccessList); Optional.ofNullable(fundNavDTOList).ifPresent(emailFundNavDTOList::addAll); } return emailFundNavDTOList; } private List buildValuationNeedParseParam(EmailContentInfoDTO emailContentInfoDTO) { String fileName = emailContentInfoDTO.getFileName(); String filePath = emailContentInfoDTO.getFilePath(); if (StrUtil.isNotBlank(fileName) && ExcelUtil.isZip(fileName)) { List filePathList = compressedFile(filePath, fileName); if (CollUtil.isEmpty(filePathList)) { return CollUtil.newArrayList(); } List parseParamList = CollUtil.newArrayList(); for (String path : filePathList) { ValuationNeedParseParam parseParam = new ValuationNeedParseParam(); parseParam.setFile(new File(path)); parseParam.setFileUrl(path); parseParam.setOriginFileName(fileName); parseParam.setFundId(null); parseParam.setFromEmail(1); // pdf格式文件转成excel transformPdfToExcel(parseParam); parseParamList.add(parseParam); } return parseParamList; } else { File file = new File(filePath); ValuationNeedParseParam parseParam = new ValuationNeedParseParam(); parseParam.setFile(file); parseParam.setFileUrl(filePath); parseParam.setOriginFileName(fileName); parseParam.setFundId(null); parseParam.setFromEmail(1); // pdf格式文件转成excel transformPdfToExcel(parseParam); return ListUtil.toList(parseParam); } } private List compressedFile(String filePath, String fileName) { List filePathList = CollUtil.newArrayList(); String destPath = filePath.substring(0, filePath.indexOf(fileName)) + fileName.replaceAll(".zip", "").replaceAll(".ZIP", ""); List compressedFiles = ExcelUtil.extractCompressedFiles(filePath, destPath); for (String path : compressedFiles) { boolean isSatisfiedParse = ExcelUtil.isExcel(path) || ExcelUtil.isPdf(path) || ExcelUtil.isZip(path); if (!isSatisfiedParse) { continue; } if (ExcelUtil.isZip(path)) { filePathList.addAll(compressedFile(path, new File(path).getName())); } File file = new File(path); if (file.isDirectory()) { filePathList.addAll(Arrays.stream(Objects.requireNonNull(file.list())).toList()); } filePathList.add(path); } return filePathList; } private void transformPdfToExcel(ValuationNeedParseParam valuationNeedParseParam) { String originFileName = valuationNeedParseParam.getOriginFileName(); if (StrUtil.isNotBlank(originFileName) && !ExcelUtil.isPdf(originFileName)) { return; } File file = valuationNeedParseParam.getFile(); valuationNeedParseParam.setFileUrl(file.getAbsolutePath()); //将pdf文件转为excel List toExcelDTOList = pdfToExcelService.pdfToExcel(ListUtil.toList(file)); Map pdfToExcelMap = MapUtil.newHashMap(); if (CollUtil.isNotEmpty(toExcelDTOList)) { pdfToExcelMap = toExcelDTOList.stream().collect(Collectors.toMap(ValuationPdfTransformToExcelDTO::getOriginalFileName, v -> v)); } ValuationPdfTransformToExcelDTO toExcelDTO = pdfToExcelMap.get(originFileName); valuationNeedParseParam.setFile(toExcelDTO != null ? toExcelDTO.getExcelFile() : null); } private List convertToFundNavDTO(List parseSuccessList) { if (CollUtil.isEmpty(parseSuccessList)) { return null; } List emailFundNavDTOList = CollUtil.newArrayList(); // 考虑一个估值表匹配到多个基金的情况 for (AssetsValuationResult.Record record : parseSuccessList) { EmailFundNavDTO fundNavDTO = new EmailFundNavDTO(); fundNavDTO.setFundName(record.getParseValuationInfo() != null ? record.getParseValuationInfo().getFundName() : null); fundNavDTO.setRegisterNumber(record.getParseValuationInfo() != null ? record.getParseValuationInfo().getRegisterNumber() : null); fundNavDTO.setPriceDate(record.getDate()); fundNavDTO.setNav(record.getNav()); fundNavDTO.setCumulativeNavWithdrawal(record.getCumulativeNavWithdrawal()); fundNavDTO.setAssetNet(record.getAssetNet()); fundNavDTO.setAssetShare(record.getAssetShare()); fundNavDTO.setFundIdList(StrUtil.isNotBlank(record.getFundId()) ? ListUtil.toList(record.getFundId()) : null); emailFundNavDTOList.add(fundNavDTO); } return emailFundNavDTOList; } }