Bladeren bron

feat:手动发送缺失邮件优化

chenjianhua 1 maand geleden
bovenliggende
commit
8a7238b175

+ 4 - 0
service-base/src/main/java/com/simuwang/base/mapper/daq/DeletionInfoMapper.java

@@ -76,4 +76,8 @@ public interface DeletionInfoMapper {
     void updateDistributeDeletionInfoDO(DistributeDeletionInfoDO distributeDeletionInfoDO);
 
     List<EmailDeletionInfoDO> selectAssetDeletionInfoByFundId(@Param("fundId")String fundId);
+
+    List<EmailDeletionInfoDO> selectNavNotRemarkDeletionInfoByFundId(@Param("fundId")String fundId);
+
+    List<EmailDeletionInfoDO> selectAssetNotRemarkDeletionInfoByFundId(@Param("fundId")String fundId);
 }

+ 24 - 0
service-base/src/main/resources/mapper/daq/DeletionInfoMapper.xml

@@ -336,6 +336,30 @@
           and d.fund_id = #{fundId}
         order by d.deletion_type,d.deletion_date desc
     </select>
+    <select id="selectNavNotRemarkDeletionInfoByFundId"
+            resultType="com.simuwang.base.pojo.dos.EmailDeletionInfoDO">
+        select info.fund_id,info.fund_name,c.company_name,d.deletion_type,d.deletion_date,ci.id as channel_id,ci.channel_name
+        from deletion_info d
+                 join pvn_fund_info info on d.fund_id=info.fund_id
+                 join pvn_company_info c on c.company_id=info.trust_id
+                 left join channel_info ci on ci.id=d.channel_id and ci.isvalid=1
+        where d.isvalid=1 and info.isvalid=1 and c.isvalid=1 and d.remark is null
+          and d.deletion_type = 1
+          and d.fund_id = #{fundId}
+        order by d.deletion_type,d.deletion_date desc
+    </select>
+    <select id="selectAssetNotRemarkDeletionInfoByFundId"
+            resultType="com.simuwang.base.pojo.dos.EmailDeletionInfoDO">
+        select info.fund_id,info.fund_name,c.company_name,d.deletion_type,d.deletion_date,ci.id as channel_id,ci.channel_name
+        from deletion_info d
+                 join pvn_fund_info info on d.fund_id=info.fund_id
+                 join pvn_company_info c on c.company_id=info.trust_id
+                 left join channel_info ci on ci.id=d.channel_id and ci.isvalid=1
+        where d.isvalid=1 and info.isvalid=1 and c.isvalid=1 and d.remark is null
+          and d.deletion_type = 2
+          and d.fund_id = #{fundId}
+        order by d.deletion_type,d.deletion_date desc
+    </select>
     <update id="updateSendStatusByFundId">
         update deletion_info d set d.is_send=1,d.updatetime=now() where d.isvalid=1
         and d.fund_id in

+ 5 - 2
service-manage/src/main/java/com/simuwang/manage/api/company/CompanyContactInformationController.java

@@ -133,9 +133,12 @@ public class CompanyContactInformationController{
      */
     @SystemLog(value = "发送净值缺失数据")
     @PostMapping("send-company-email")
-    public boolean sendCompanyEmail(@RequestBody IdListVO idListVO){
+    public ResultVo sendCompanyEmail(@RequestBody IdListVO idListVO){
+        ResultVo vo = new ResultVo(ResultCode.SUCCESS.getCode());
         companyEmailConfigService.sendCompanyEmail(idListVO.getIdList());
-        return true;
+        vo.setData(true);
+        vo.setMsg("发送中,请稍后");
+        return vo;
     }
 
     /**

+ 274 - 2
service-manage/src/main/java/com/simuwang/manage/service/impl/CompanyEmailConfigServiceImpl.java

@@ -24,6 +24,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -152,6 +153,7 @@ public class CompanyEmailConfigServiceImpl implements CompanyEmailConfigService
     }
 
     @Override
+    @Async
     public void sendCompanyEmail(List<Integer> idList) {
         List<ContactInformationDO> configDOList = contactInformationService.selectByIdList(idList);
         Map<String,List<ContactInformationDO>> companyListMap = configDOList.stream().collect(Collectors.groupingBy(e -> e.getCompanyId()));
@@ -162,9 +164,229 @@ public class CompanyEmailConfigServiceImpl implements CompanyEmailConfigService
                 emails.append(configDO.getContactEmail()).append(";");
             }
             //把缺失数据的邮件发送到该公司名下的邮箱地址
-            sendEmail(companyId,emails.toString());
+            sendNavAssetEmail(companyId,emails.toString());
         }
     }
+
+    private void sendNavAssetEmail(String companyId, String emails) {
+        List<String> fundIdList = fundInfoMapper.getFundIdByCompanyId(companyId);
+        List<EmailDeletionInfoDO> emailDeletionInfoDOS = new ArrayList<>();
+        for (String fundId : fundIdList) {
+            getNavNotRemarkDeletion(fundId,emailDeletionInfoDOS);
+            getAssetNotRemarkDeletion(fundId,emailDeletionInfoDOS);
+        }
+        if(emailDeletionInfoDOS.size() > 0){
+            EmailTemplateDO emailTemplateDO = emailTemplateMapper.selectByCode(DELETION_TEMPLATE_CODE);
+            if(emailTemplateDO == null){
+                return;
+            }
+            String emailTitle = emailTemplateDO.getEmailTitle();
+            String emailBody = emailTemplateDO.getEmailBody().replaceAll("\r\n", "<br/>").replaceAll("\n", "<br/>");
+            try {
+                //将数据写入excel文件
+                File file = writeExcelFile(emailDeletionInfoDOS);
+                file.setWritable(true);
+                file.setReadable(true);
+                file.setExecutable(true);
+                MailboxInfoDTO dto = getFromEmailInfo();
+                try{
+                    EmailUtil.senEmail(dto,emails,List.of(file),emailBody,sysConfigMapper.selectConfigByKey("email.host")==null?"":sysConfigMapper.selectConfigByKey("email.host"),emailTitle);
+                }catch (Exception e){
+                    //有些是因为被识别为垃圾邮件导致的报错,需要在发送一次
+                    logger.error(e.getMessage(),e);
+                    EmailUtil.senEmail(dto,emails,List.of(file),emailBody,sysConfigMapper.selectConfigByKey("email.host")==null?"":sysConfigMapper.selectConfigByKey("email.host"),emailTitle);
+                }
+                //发送成功之后修改数据为已发送
+                deletionInfoMapper.updateSendStatusByFundId(fundIdList);
+                //写入发送历史
+                String[] emailList = emails.split(";");
+                for(String email : emailList){
+                    saveCompanyEmailSendHistory(companyId,email,emailTitle,1,ResultCode.SEND_SUCCESS.getMsg());
+                }
+            } catch (Exception e) {
+                String[] emailList = emails.split(";");
+                for(String email : emailList){
+                    saveCompanyEmailSendHistory(companyId,email,emailTitle,0,e.getMessage());
+                }
+                logger.error(e.getMessage(),e);
+            }
+        }
+    }
+
+    private void getAssetNotRemarkDeletion(String fundId, List<EmailDeletionInfoDO> emailDeletionInfoDOS) {
+        List<EmailDeletionInfoDO> fundEmailDeletionInfoDOList = deletionInfoMapper.selectAssetNotRemarkDeletionInfoByFundId(fundId);
+        if(fundEmailDeletionInfoDOList.isEmpty()){
+            return;
+        }
+        fundEmailDeletionInfoDOList = fundEmailDeletionInfoDOList.stream().filter(e -> e.getChannelId() != null).collect(Collectors.toList());
+        Map<Integer, List<EmailDeletionInfoDO>> channelDeletionMap = fundEmailDeletionInfoDOList.stream().collect(Collectors.groupingBy(EmailDeletionInfoDO::getChannelId));
+        FundReportFrequencyDO fundReportFrequencyDO = fundReportFrequencyMapper.getFrequencyByFundId(fundId);
+        if(fundReportFrequencyDO == null){
+            return;
+        }
+        for (Integer channelId : channelDeletionMap.keySet()) {
+            List<EmailDeletionInfoDO> channelEmailDeletionInfoDOList = channelDeletionMap.get(channelId);
+            if(channelEmailDeletionInfoDOList.isEmpty()){
+                continue;
+            }
+            //根据渠道ID和基金ID去查最新的净值日期
+            Date priceDate = assetMapper.selectMaxPriceDate(channelId,fundId);
+            if(priceDate == null){
+                FundInfoDO fundInformationDO = fundInfoMapper.searchFundDetail(fundId);
+                if(fundInformationDO != null && fundInformationDO.getInceptionDate() == null){
+                    continue;
+                }
+                try{
+                    priceDate = DateUtils.parse(fundInformationDO.getInceptionDate(),"yyyy-MM-dd");
+                }catch (Exception e){
+                    logger.error(e.getMessage(),e);
+                }
+            }
+            if(Frequency.DAY.getCode().equals(fundReportFrequencyDO.getAssetFrequency())){
+                List<DeletionTaskLogInfoDO> deletionTaskLogInfoDOList = deletionTaskLogInfoMapper.selectDeletionTaskLogInfoDO(fundId,channelId,fundReportFrequencyDO.getNavFrequency(),DateUtils.format(priceDate,"yyyy-MM-dd"),DeletionType.NAV_DELETION.getCode());
+                //最新净值不再更新,超过五次就不再发送
+                if(deletionTaskLogInfoDOList.size() >= 5){
+                    continue;
+                }
+                DeletionTaskLogInfoDO deletionTaskLogInfoDO = new DeletionTaskLogInfoDO();
+                deletionTaskLogInfoDO.setChannelId(channelId);
+                deletionTaskLogInfoDO.setFundId(fundId);
+                deletionTaskLogInfoDO.setIsvalid(1);
+                deletionTaskLogInfoDO.setCreateTime(new Date());
+                deletionTaskLogInfoDO.setUpdateTime(new Date());
+                deletionTaskLogInfoDO.setPriceDate(DateUtils.format(priceDate,"yyyy-MM-dd"));
+                deletionTaskLogInfoDO.setFrequency(fundReportFrequencyDO.getNavFrequency());
+                deletionTaskLogInfoDO.setDeletionType(DeletionType.ASSET_DELETION.getCode());
+                deletionTaskLogInfoMapper.saveDeletionTaskLogInfoDO(deletionTaskLogInfoDO);
+            }
+            if(Frequency.WEEK.getCode().equals(fundReportFrequencyDO.getAssetFrequency())){
+                List<DeletionTaskLogInfoDO> deletionTaskLogInfoDOList = deletionTaskLogInfoMapper.selectDeletionTaskLogInfoDO(fundId,channelId,fundReportFrequencyDO.getNavFrequency(),DateUtils.format(priceDate,"yyyy-MM-dd"),DeletionType.NAV_DELETION.getCode());
+                //最新净值不再更新,超过3次就不再发送
+                if(deletionTaskLogInfoDOList.size() >= 3){
+                    continue;
+                }
+                DeletionTaskLogInfoDO deletionTaskLogInfoDO = new DeletionTaskLogInfoDO();
+                deletionTaskLogInfoDO.setChannelId(channelId);
+                deletionTaskLogInfoDO.setFundId(fundId);
+                deletionTaskLogInfoDO.setIsvalid(1);
+                deletionTaskLogInfoDO.setCreateTime(new Date());
+                deletionTaskLogInfoDO.setUpdateTime(new Date());
+                deletionTaskLogInfoDO.setPriceDate(DateUtils.format(priceDate,"yyyy-MM-dd"));
+                deletionTaskLogInfoDO.setFrequency(fundReportFrequencyDO.getNavFrequency());
+                deletionTaskLogInfoDO.setDeletionType(DeletionType.ASSET_DELETION.getCode());
+                deletionTaskLogInfoMapper.saveDeletionTaskLogInfoDO(deletionTaskLogInfoDO);
+            }
+            if(Frequency.MONTH.getCode().equals(fundReportFrequencyDO.getAssetFrequency())){
+                List<DeletionTaskLogInfoDO> deletionTaskLogInfoDOList = deletionTaskLogInfoMapper.selectDeletionTaskLogInfoDO(fundId,channelId,fundReportFrequencyDO.getNavFrequency(),DateUtils.format(priceDate,"yyyy-MM-dd"),DeletionType.NAV_DELETION.getCode());
+                //最新净值不再更新,超过1次就不再发送
+                if(deletionTaskLogInfoDOList.size() >= 1){
+                    continue;
+                }
+                DeletionTaskLogInfoDO deletionTaskLogInfoDO = new DeletionTaskLogInfoDO();
+                deletionTaskLogInfoDO.setChannelId(channelId);
+                deletionTaskLogInfoDO.setFundId(fundId);
+                deletionTaskLogInfoDO.setIsvalid(1);
+                deletionTaskLogInfoDO.setCreateTime(new Date());
+                deletionTaskLogInfoDO.setUpdateTime(new Date());
+                deletionTaskLogInfoDO.setPriceDate(DateUtils.format(priceDate,"yyyy-MM-dd"));
+                deletionTaskLogInfoDO.setFrequency(fundReportFrequencyDO.getNavFrequency());
+                deletionTaskLogInfoDO.setDeletionType(DeletionType.ASSET_DELETION.getCode());
+                deletionTaskLogInfoMapper.saveDeletionTaskLogInfoDO(deletionTaskLogInfoDO);
+            }
+            for(EmailDeletionInfoDO infoDO : channelEmailDeletionInfoDOList){
+                infoDO.setDeletionType(DeletionType.getDeletionTypeByCode(Integer.valueOf(infoDO.getDeletionType())).getInfo());
+            }
+            emailDeletionInfoDOS.addAll(channelEmailDeletionInfoDOList);
+        }
+    }
+
+    private void getNavNotRemarkDeletion(String fundId, List<EmailDeletionInfoDO> emailDeletionInfoDOS) {
+        List<EmailDeletionInfoDO> fundEmailDeletionInfoDOList = deletionInfoMapper.selectNavNotRemarkDeletionInfoByFundId(fundId);
+        if(fundEmailDeletionInfoDOList.isEmpty()){
+            return;
+        }
+        fundEmailDeletionInfoDOList = fundEmailDeletionInfoDOList.stream().filter(e -> e.getChannelId() != null).collect(Collectors.toList());
+        Map<Integer, List<EmailDeletionInfoDO>> channelDeletionMap = fundEmailDeletionInfoDOList.stream().collect(Collectors.groupingBy(EmailDeletionInfoDO::getChannelId));
+        FundReportFrequencyDO fundReportFrequencyDO = fundReportFrequencyMapper.getFrequencyByFundId(fundId);
+        if(fundReportFrequencyDO == null){
+            return;
+        }
+        for (Integer channelId : channelDeletionMap.keySet()) {
+            List<EmailDeletionInfoDO> channelEmailDeletionInfoDOList = channelDeletionMap.get(channelId);
+            if(channelEmailDeletionInfoDOList.isEmpty()){
+                continue;
+            }
+            //根据渠道ID和基金ID去查最新的净值日期
+            Date priceDate = navMapper.selectMaxPriceDate(channelId,fundId);
+            if(priceDate == null){
+                FundInfoDO fundInformationDO = fundInfoMapper.searchFundDetail(fundId);
+                if(fundInformationDO != null && fundInformationDO.getInceptionDate() == null){
+                    continue;
+                }
+                try{
+                    priceDate = DateUtils.parse(fundInformationDO.getInceptionDate(),"yyyy-MM-dd");
+                }catch (Exception e){
+                    logger.error(e.getMessage(),e);
+                }
+            }
+            if(Frequency.DAY.getCode().equals(fundReportFrequencyDO.getNavFrequency())){
+                List<DeletionTaskLogInfoDO> deletionTaskLogInfoDOList = deletionTaskLogInfoMapper.selectDeletionTaskLogInfoDO(fundId,channelId,fundReportFrequencyDO.getNavFrequency(),DateUtils.format(priceDate,"yyyy-MM-dd"),DeletionType.NAV_DELETION.getCode());
+                //最新净值不再更新,超过五次就不再发送
+                if(deletionTaskLogInfoDOList.size() >= 5){
+                    continue;
+                }
+                DeletionTaskLogInfoDO deletionTaskLogInfoDO = new DeletionTaskLogInfoDO();
+                deletionTaskLogInfoDO.setChannelId(channelId);
+                deletionTaskLogInfoDO.setFundId(fundId);
+                deletionTaskLogInfoDO.setIsvalid(1);
+                deletionTaskLogInfoDO.setCreateTime(new Date());
+                deletionTaskLogInfoDO.setUpdateTime(new Date());
+                deletionTaskLogInfoDO.setPriceDate(DateUtils.format(priceDate,"yyyy-MM-dd"));
+                deletionTaskLogInfoDO.setFrequency(fundReportFrequencyDO.getNavFrequency());
+                deletionTaskLogInfoDO.setDeletionType(DeletionType.NAV_DELETION.getCode());
+                deletionTaskLogInfoMapper.saveDeletionTaskLogInfoDO(deletionTaskLogInfoDO);
+            }
+            if(Frequency.WEEK.getCode().equals(fundReportFrequencyDO.getNavFrequency())){
+                List<DeletionTaskLogInfoDO> deletionTaskLogInfoDOList = deletionTaskLogInfoMapper.selectDeletionTaskLogInfoDO(fundId,channelId,fundReportFrequencyDO.getNavFrequency(),DateUtils.format(priceDate,"yyyy-MM-dd"),DeletionType.NAV_DELETION.getCode());
+                //最新净值不再更新,超过3次就不再发送
+                if(deletionTaskLogInfoDOList.size() >= 3){
+                    continue;
+                }
+                DeletionTaskLogInfoDO deletionTaskLogInfoDO = new DeletionTaskLogInfoDO();
+                deletionTaskLogInfoDO.setChannelId(channelId);
+                deletionTaskLogInfoDO.setFundId(fundId);
+                deletionTaskLogInfoDO.setIsvalid(1);
+                deletionTaskLogInfoDO.setCreateTime(new Date());
+                deletionTaskLogInfoDO.setUpdateTime(new Date());
+                deletionTaskLogInfoDO.setPriceDate(DateUtils.format(priceDate,"yyyy-MM-dd"));
+                deletionTaskLogInfoDO.setFrequency(fundReportFrequencyDO.getNavFrequency());
+                deletionTaskLogInfoDO.setDeletionType(DeletionType.NAV_DELETION.getCode());
+                deletionTaskLogInfoMapper.saveDeletionTaskLogInfoDO(deletionTaskLogInfoDO);
+            }
+            if(Frequency.MONTH.getCode().equals(fundReportFrequencyDO.getNavFrequency())){
+                List<DeletionTaskLogInfoDO> deletionTaskLogInfoDOList = deletionTaskLogInfoMapper.selectDeletionTaskLogInfoDO(fundId,channelId,fundReportFrequencyDO.getNavFrequency(),DateUtils.format(priceDate,"yyyy-MM-dd"),DeletionType.NAV_DELETION.getCode());
+                //最新净值不再更新,超过1次就不再发送
+                if(deletionTaskLogInfoDOList.size() >= 1){
+                    continue;
+                }
+                DeletionTaskLogInfoDO deletionTaskLogInfoDO = new DeletionTaskLogInfoDO();
+                deletionTaskLogInfoDO.setChannelId(channelId);
+                deletionTaskLogInfoDO.setFundId(fundId);
+                deletionTaskLogInfoDO.setIsvalid(1);
+                deletionTaskLogInfoDO.setCreateTime(new Date());
+                deletionTaskLogInfoDO.setUpdateTime(new Date());
+                deletionTaskLogInfoDO.setPriceDate(DateUtils.format(priceDate,"yyyy-MM-dd"));
+                deletionTaskLogInfoDO.setFrequency(fundReportFrequencyDO.getNavFrequency());
+                deletionTaskLogInfoDO.setDeletionType(DeletionType.NAV_DELETION.getCode());
+                deletionTaskLogInfoMapper.saveDeletionTaskLogInfoDO(deletionTaskLogInfoDO);
+            }
+            for(EmailDeletionInfoDO infoDO : channelEmailDeletionInfoDOList){
+                infoDO.setDeletionType(DeletionType.getDeletionTypeByCode(Integer.valueOf(infoDO.getDeletionType())).getInfo());
+            }
+            emailDeletionInfoDOS.addAll(channelEmailDeletionInfoDOList);
+        }
+    }
+
     @Override
     //邮件校验处理
     public void sendEmail(String companyId, String emails) {
@@ -466,7 +688,57 @@ public class CompanyEmailConfigServiceImpl implements CompanyEmailConfigService
                 emails.append(configDO.getContactEmail()).append(";");
             }
             //把缺失数据的邮件发送到该公司名下的邮箱地址
-            sendDistributeEmail(companyId,emails.toString());
+            sendDistributeNotRemarkEmail(companyId,emails.toString());
+        }
+    }
+
+    private void sendDistributeNotRemarkEmail(String companyId, String emails) {
+        List<String> fundIdList = fundInfoMapper.getFundIdByCompanyId(companyId);
+        List<EmailDeletionInfoDO> emailDeletionInfoDOS = new ArrayList<>();
+        for (String fundId : fundIdList) {
+            List<EmailDeletionInfoDO> distributeDeletionList = deletionInfoMapper.selectDistributeDeletionInfoByFundId(fundId);
+            if(distributeDeletionList.isEmpty()){
+                continue;
+            }
+            for(EmailDeletionInfoDO infoDO : distributeDeletionList){
+                infoDO.setDeletionType(DeletionType.getDeletionTypeByCode(Integer.valueOf(infoDO.getDeletionType())).getInfo());
+            }
+            emailDeletionInfoDOS.addAll(distributeDeletionList);
+        }
+        if(emailDeletionInfoDOS.size() > 0){
+            EmailTemplateDO emailTemplateDO = emailTemplateMapper.selectByCode(DISTRIBUTION_DELETION_TEMPLATE_CODE);
+            if(emailTemplateDO == null){
+                return;
+            }
+            String emailTitle = emailTemplateDO.getEmailTitle();
+            String emailBody = emailTemplateDO.getEmailBody().replaceAll("\r\n", "<br/>").replaceAll("\n", "<br/>");
+            try {
+                //将数据写入excel文件
+                File file = writeExcelFile(emailDeletionInfoDOS);
+                file.setWritable(true);
+                file.setReadable(true);
+                file.setExecutable(true);
+                MailboxInfoDTO dto = getFromEmailInfo();
+                try{
+                    EmailUtil.senEmail(dto,emails,List.of(file),emailBody,sysConfigMapper.selectConfigByKey("email.host")==null?"":sysConfigMapper.selectConfigByKey("email.host"),emailTitle);
+                }catch (Exception e){
+                    logger.error(e.getMessage(),e);
+                    EmailUtil.senEmail(dto,emails,List.of(file),emailBody,sysConfigMapper.selectConfigByKey("email.host")==null?"":sysConfigMapper.selectConfigByKey("email.host"),emailTitle);
+                }
+                //发送成功之后修改数据为已发送
+                deletionInfoMapper.updateSendStatusByFundId(fundIdList);
+                //写入发送历史
+                String[] emailList = emails.split(";");
+                for(String email : emailList){
+                    saveCompanyEmailSendHistory(companyId,email,emailTitle,1,ResultCode.SEND_SUCCESS.getMsg());
+                }
+            } catch (Exception e) {
+                String[] emailList = emails.split(";");
+                for(String email : emailList){
+                    saveCompanyEmailSendHistory(companyId,email,emailTitle,0,e.getMessage());
+                }
+                logger.error(e.getMessage(),e);
+            }
         }
     }