Browse Source

feat:基金净值采集结果明细表格支持邮件通知

mozuwen 5 months ago
parent
commit
9c30a2bab4

+ 2 - 2
service-base/src/main/java/com/simuwang/base/common/util/EmailUtil.java

@@ -349,8 +349,8 @@ public class EmailUtil {
             properties.put("mail.smtp.host", mailboxInfoDTO.getHost());
             properties.put("mail.smtp.auth", true);
             properties.setProperty("mail.smtp.port", mailboxInfoDTO.getPort());
-            properties.put("mail.smtp.ssl.enable", false);
-            properties.put("mail.smtp.ssl.required", false);
+            properties.put("mail.smtp.ssl.enable", true);
+            properties.put("mail.smtp.ssl.required", true);
             // 根据邮件的会话属性构造一个发送邮件的Session,
             JakartaUserPassAuthenticator authenticator = new JakartaUserPassAuthenticator(mailboxInfoDTO.getAccount(), mailboxInfoDTO.getPassword());
             Session session = Session.getInstance(properties, authenticator);

+ 2 - 0
service-base/src/main/java/com/simuwang/base/mapper/AssetMapper.java

@@ -25,4 +25,6 @@ public interface AssetMapper {
     void batchDeleteAsset(@Param("fundId")String sourceFundId,@Param("priceDateList") List<String> priceDateList);
 
     Long countAssetTotal();
+
+    List<AssetDO> queryAssetByFundId(@Param("fundIdList") List<String> fundIdList);
 }

+ 7 - 0
service-base/src/main/java/com/simuwang/base/pojo/dto/FundNavDataDTO.java

@@ -43,4 +43,11 @@ public class FundNavDataDTO {
     @ColumnWidth(15)
     @ExcelProperty("累计净值")
     private String cumulativeNavWithdrawal;
+
+    /**
+     * 资产净值
+     */
+    @ColumnWidth(15)
+    @ExcelProperty("资产净值")
+    private String asset;
 }

+ 9 - 0
service-base/src/main/resources/mapper/AssetMapper.xml

@@ -73,4 +73,13 @@
         select count(1) from asset where isvalid=1
     </select>
 
+    <select id="queryAssetByFundId" resultMap="BaseResultMap">
+        select fund_id, price_date, asset_net
+        from asset
+        where isvalid = 1
+        and fund_id in
+        <foreach collection="fundIdList" index="index" item="fundId" separator="," open="(" close=")">
+            #{fundId}
+        </foreach>
+    </select>
 </mapper>

+ 29 - 0
service-manage/src/main/java/com/simuwang/manage/service/EmailSystemConfigService.java

@@ -0,0 +1,29 @@
+package com.simuwang.manage.service;
+
+import com.simuwang.base.mapper.system.SysConfigMapper;
+import com.simuwang.base.pojo.dto.MailboxInfoDTO;
+import org.springframework.stereotype.Service;
+
+@Service
+public class EmailSystemConfigService {
+
+    private final SysConfigMapper sysConfigMapper;
+
+    public EmailSystemConfigService(SysConfigMapper sysConfigMapper) {
+        this.sysConfigMapper = sysConfigMapper;
+    }
+
+    public MailboxInfoDTO getFromEmailInfo() {
+        MailboxInfoDTO mailboxInfoDTO = new MailboxInfoDTO();
+        mailboxInfoDTO.setAccount(sysConfigMapper.selectConfigByKey("competition.sender.email"));
+        mailboxInfoDTO.setProtocol(sysConfigMapper.selectConfigByKey("competition.sender.protocol"));
+        mailboxInfoDTO.setPassword(sysConfigMapper.selectConfigByKey("competition.sender.password"));
+        mailboxInfoDTO.setPort(sysConfigMapper.selectConfigByKey("competition.sender.port"));
+        mailboxInfoDTO.setHost(sysConfigMapper.selectConfigByKey("competition.sender.host"));
+        return mailboxInfoDTO;
+    }
+
+    public String getRecipientEmail() {
+        return sysConfigMapper.selectConfigByKey("competition.recipient.email");
+    }
+}

+ 23 - 4
service-manage/src/main/java/com/simuwang/manage/service/impl/FundNavServiceImpl.java

@@ -2,15 +2,20 @@ package com.simuwang.manage.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.map.MapUtil;
 import com.simuwang.base.common.conts.DateConst;
+import com.simuwang.base.mapper.AssetMapper;
 import com.simuwang.base.mapper.FundInfoMapper;
 import com.simuwang.base.mapper.NavMapper;
+import com.simuwang.base.pojo.dos.AssetDO;
 import com.simuwang.base.pojo.dos.FundInfoDO;
 import com.simuwang.base.pojo.dos.NavDO;
 import com.simuwang.base.pojo.dto.FundNavDataDTO;
 import com.simuwang.manage.service.FundNavService;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
@@ -21,10 +26,12 @@ public class FundNavServiceImpl implements FundNavService {
 
     private final NavMapper navMapper;
     private final FundInfoMapper fundInfoMapper;
+    private final AssetMapper assetMapper;
 
-    public FundNavServiceImpl(NavMapper navMapper, FundInfoMapper fundInfoMapper) {
+    public FundNavServiceImpl(NavMapper navMapper, FundInfoMapper fundInfoMapper, AssetMapper assetMapper) {
         this.navMapper = navMapper;
         this.fundInfoMapper = fundInfoMapper;
+        this.assetMapper = assetMapper;
     }
 
     @Override
@@ -38,27 +45,39 @@ public class FundNavServiceImpl implements FundNavService {
         List<FundInfoDO> fundInfoDOList = fundInfoMapper.queryFundInfoByFundId(fundIdList);
         Map<String, FundInfoDO> fundIdInfoMap = fundInfoDOList.stream().collect(Collectors.toMap(FundInfoDO::getFundId, v -> v, (oldValue, newValue) -> oldValue));
 
+        List<AssetDO> assetDOList = assetMapper.queryAssetByFundId(fundIdList);
+        Map<String, List<AssetDO>> fundIdAssetMap = MapUtil.newHashMap();
+        if (CollUtil.isNotEmpty(assetDOList)) {
+            fundIdAssetMap = assetDOList.stream().collect(Collectors.groupingBy(AssetDO::getFundId));
+        }
+
         Map<String, List<NavDO>> fundIdNavMap = navDOList.stream().collect(Collectors.groupingBy(NavDO::getFundId));
         for (Map.Entry<String, List<NavDO>> fundIdNavEntry : fundIdNavMap.entrySet()) {
             String fundId = fundIdNavEntry.getKey();
             List<NavDO> fundNavDoList = fundIdNavEntry.getValue();
+            List<AssetDO> fundAssetDoList = fundIdAssetMap.get(fundId);
             FundInfoDO fundInfoDO = fundIdInfoMap.get(fundId);
-            List<FundNavDataDTO> fundNavDataDTOList = buildFundNavDataDTO(fundInfoDO, fundNavDoList);
+            List<FundNavDataDTO> fundNavDataDTOList = buildFundNavDataDTO(fundInfoDO, fundNavDoList, fundAssetDoList);
             navDataDTOList.addAll(fundNavDataDTOList);
         }
         return navDataDTOList;
     }
 
-    private List<FundNavDataDTO> buildFundNavDataDTO(FundInfoDO fundInfoDO, List<NavDO> fundNavDoList) {
+    private List<FundNavDataDTO> buildFundNavDataDTO(FundInfoDO fundInfoDO, List<NavDO> fundNavDoList, List<AssetDO> fundAssetDoList) {
         String fundName = fundInfoDO.getFundName();
         String registerNumber = fundInfoDO.getRegisterNumber();
+        Map<String, BigDecimal> priceDateAssetMap = fundAssetDoList.stream()
+                .collect(Collectors.toMap(k -> DateUtil.format(k.getPriceDate(), DateConst.YYYY_MM_DD), AssetDO::getAssetNet));
         return fundNavDoList.stream().map(e -> {
             FundNavDataDTO fundNavDataDTO = new FundNavDataDTO();
             fundNavDataDTO.setFundName(fundName);
             fundNavDataDTO.setRegisterNumber(registerNumber);
-            fundNavDataDTO.setPriceDate(e.getPriceDate() != null ? DateUtil.format(e.getPriceDate(), DateConst.YYYY_MM_DD) : null);
+            String priceDate = e.getPriceDate() != null ? DateUtil.format(e.getPriceDate(), DateConst.YYYY_MM_DD) : null;
+            fundNavDataDTO.setPriceDate(priceDate);
             fundNavDataDTO.setNav(e.getNav() != null ? String.valueOf(e.getNav()) : null);
             fundNavDataDTO.setCumulativeNavWithdrawal(e.getCumulativeNavWithdrawal() != null ? String.valueOf(e.getCumulativeNavWithdrawal()) : null);
+            BigDecimal asset = priceDateAssetMap.get(priceDate) != null ? priceDateAssetMap.get(priceDate).setScale(2, RoundingMode.HALF_UP) : null;
+            fundNavDataDTO.setAsset(asset != null ? String.valueOf(asset) : null);
             return fundNavDataDTO;
         }).sorted(Comparator.comparing(FundNavDataDTO::getPriceDate)).toList();
     }

+ 25 - 7
service-manage/src/main/java/com/simuwang/manage/task/GenerateNavDataTask.java

@@ -2,16 +2,21 @@ package com.simuwang.manage.task;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.exceptions.ExceptionUtil;
 import com.alibaba.excel.EasyExcel;
 import com.simuwang.base.common.conts.DateConst;
+import com.simuwang.base.common.util.EmailUtil;
 import com.simuwang.base.config.CompetitionConfig;
 import com.simuwang.base.pojo.dto.FundNavDataDTO;
+import com.simuwang.base.pojo.dto.MailboxInfoDTO;
+import com.simuwang.manage.service.EmailSystemConfigService;
 import com.simuwang.manage.service.FundNavService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
+import java.io.File;
 import java.util.Date;
 import java.util.List;
 
@@ -23,27 +28,40 @@ public class GenerateNavDataTask {
     private final FundNavService fundNavService;
     private final CompetitionConfig competitionConfig;
 
-    public GenerateNavDataTask(FundNavService fundNavService, CompetitionConfig competitionConfig) {
+    private final EmailSystemConfigService emailSystemConfigService;
+
+    public GenerateNavDataTask(FundNavService fundNavService, CompetitionConfig competitionConfig, EmailSystemConfigService emailSystemConfigService) {
         this.fundNavService = fundNavService;
         this.competitionConfig = competitionConfig;
+        this.emailSystemConfigService = emailSystemConfigService;
     }
 
-     @Scheduled(cron = "0 0/1 * * * ?")
+    /**
+     * 每周五 18:00 执行
+     */
+     @Scheduled(cron = "0 0 18 ? * 5")
     public void runTask() {
         List<FundNavDataDTO> navDataDTOList = fundNavService.getFungNavData();
         if (CollUtil.isEmpty(navDataDTOList)) {
             return;
         }
-        String fileName = competitionConfig.getDirectory() + "基金净值采集结果明细_" + DateUtil.format(new Date(), DateConst.YYYYMMDDHHMMSS24) + ".xlsx";
-        EasyExcel.write(fileName, FundNavDataDTO.class)
+        String filePath = competitionConfig.getDirectory() + "基金净值采集结果明细_" + DateUtil.format(new Date(), DateConst.YYYYMMDD) + ".xlsx";
+        EasyExcel.write(filePath, FundNavDataDTO.class)
                 .sheet("基金净值采集结果明细")
                 .doWrite(navDataDTOList);
-        log.info("基金净值采集结果明细表格已输出... -> 文件:{}", fileName);
+        log.info("基金净值采集结果明细表格已输出 -> 文件:{}", filePath);
 
         Integer method = competitionConfig.getMethod();
         // 通过邮件发送"基金净值采集结果明细表格"
-        if(method == 1){
-
+        if (method == 1) {
+            MailboxInfoDTO mailboxInfoDTO = emailSystemConfigService.getFromEmailInfo();
+            String ReceivingMailbox = emailSystemConfigService.getRecipientEmail();
+            try {
+                EmailUtil.senEmail(mailboxInfoDTO, ReceivingMailbox, new File(filePath), "基金净值采集结果明细", "", "基金净值采集结果明细");
+                log.info("基金净值采集结果明细表 -> 邮件已发送");
+            } catch (Exception e) {
+                log.error("邮件发送基金净值采集结果明细表异常 -> 堆栈信息:{}", ExceptionUtil.stacktraceToString(e));
+            }
         }
     }
 }