Browse Source

Merge branch 'develop' of http://112.74.196.215:3000/Tech2/data-daq into develop

wangzaijun 7 months ago
parent
commit
0c4a999eaa
38 changed files with 413 additions and 140 deletions
  1. 13 11
      service-base/src/main/java/com/simuwang/base/common/util/EmailUtil.java
  2. 8 4
      service-base/src/main/java/com/simuwang/base/common/util/ExcelUtil.java
  3. 3 1
      service-base/src/main/java/com/simuwang/base/common/util/StringUtil.java
  4. 2 2
      service-base/src/main/java/com/simuwang/base/config/ShiroConfig.java
  5. 1 1
      service-base/src/main/java/com/simuwang/base/mapper/CompanyEmailConfigMapper.java
  6. 22 0
      service-base/src/main/java/com/simuwang/base/pojo/dto/FieldPositionDTO.java
  7. 7 5
      service-base/src/main/java/com/simuwang/base/pojo/dto/query/ParseDetailPageQuery.java
  8. 4 0
      service-base/src/main/java/com/simuwang/base/pojo/vo/FundFileInfoVO.java
  9. 1 1
      service-base/src/main/resources/mapper/CompanyEmailConfigMapper.xml
  10. 1 0
      service-base/src/main/resources/mapper/CompanyEmailHistoryMapper.xml
  11. 1 1
      service-base/src/main/resources/mapper/DistributionMapper.xml
  12. 4 2
      service-base/src/main/resources/mapper/EmailFileInfoMapper.xml
  13. 26 9
      service-base/src/main/resources/mapper/EmailFundAssetMapper.xml
  14. 13 6
      service-base/src/main/resources/mapper/EmailFundNavMapper.xml
  15. 2 2
      service-base/src/main/resources/mapper/EmailParseInfoMapper.xml
  16. 2 2
      service-base/src/main/resources/mapper/FundAliasMapper.xml
  17. 3 2
      service-base/src/main/resources/mapper/FundInfoMapper.xml
  18. 58 12
      service-daq/src/main/java/com/simuwang/daq/service/EmailParseService.java
  19. 2 2
      service-daq/src/main/java/com/simuwang/daq/service/FundService.java
  20. 37 18
      service-daq/src/main/java/com/simuwang/daq/service/NavEmailParser.java
  21. 1 1
      service-daq/src/main/java/com/simuwang/daq/service/ValuationParseService.java
  22. 62 0
      service-deploy/src/main/test/java/com/simuwang/datadaq/DataTrusteeApplicationTests.java
  23. 6 6
      service-manage/src/main/java/com/simuwang/manage/api/company/CompanyEmailSendHistoryController.java
  24. 1 1
      service-manage/src/main/java/com/simuwang/manage/api/distribution/DistributionController.java
  25. 4 4
      service-manage/src/main/java/com/simuwang/manage/api/email/EmailConfigController.java
  26. 6 4
      service-manage/src/main/java/com/simuwang/manage/api/email/ParseEmailController.java
  27. 17 4
      service-manage/src/main/java/com/simuwang/manage/init/QuartzConfig.java
  28. 1 1
      service-manage/src/main/java/com/simuwang/manage/service/CompanyEmailConfigService.java
  29. 1 1
      service-manage/src/main/java/com/simuwang/manage/service/CompanyEmailSendHistoryService.java
  30. 1 1
      service-manage/src/main/java/com/simuwang/manage/service/EmailConfigService.java
  31. 6 15
      service-manage/src/main/java/com/simuwang/manage/service/impl/CompanyEmailConfigServiceImpl.java
  32. 7 4
      service-manage/src/main/java/com/simuwang/manage/service/impl/CompanyEmailSendHistoryServiceImpl.java
  33. 11 5
      service-manage/src/main/java/com/simuwang/manage/service/impl/DistributionServiceImpl.java
  34. 42 9
      service-manage/src/main/java/com/simuwang/manage/service/impl/EmailConfigServiceImpl.java
  35. 14 1
      service-manage/src/main/java/com/simuwang/manage/service/impl/EmailFundAssetServiceImpl.java
  36. 11 1
      service-manage/src/main/java/com/simuwang/manage/service/impl/EmailFundNavServiceImpl.java
  37. 9 1
      service-manage/src/main/java/com/simuwang/manage/service/impl/FundNavAssetServiceImpl.java
  38. 3 0
      service-manage/src/main/java/com/simuwang/manage/task/ParseSchedulerTask.java

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

@@ -7,6 +7,7 @@ import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.mail.JakartaUserPassAuthenticator;
 import com.simuwang.base.common.conts.DateConst;
+import com.simuwang.base.common.conts.EmailTypeConst;
 import com.simuwang.base.pojo.dto.EmailContentInfoDTO;
 import com.simuwang.base.pojo.dto.MailboxInfoDTO;
 import com.sun.mail.imap.IMAPStore;
@@ -70,17 +71,18 @@ public class EmailUtil {
                     String fileName = MimeUtility.decodeText(part.getFileName());
                     emailContentInfoDTO.setFileName(fileName);
 
-                    File savefile = new File(filePath + fileName);
-                    if (!savefile.exists()) {
-                        if (!savefile.getParentFile().exists()) {
-                            savefile.getParentFile().mkdirs();
+                    String realPath = filePath + emailDate + fileName;
+                    File saveFile = new File(realPath);
+                    if (!saveFile.exists()) {
+                        if (!saveFile.getParentFile().exists()) {
+                            saveFile.getParentFile().mkdirs();
                         }
-                        FileUtil.saveFile(savefile, part);
+                        FileUtil.saveFile(saveFile, part);
                     } else {
-                        FileUtils.deleteQuietly(savefile);
-                        FileUtil.saveFile(savefile, part);
+                        FileUtils.deleteQuietly(saveFile);
+                        FileUtil.saveFile(saveFile, part);
                     }
-                    emailContentInfoDTO.setFilePath(filePath + fileName);
+                    emailContentInfoDTO.setFilePath(realPath);
                 }
             } else if ("MimeMultipart".equals(contentClass)) {
                 MimeMultipart contentPart = (MimeMultipart) partContent;
@@ -175,11 +177,11 @@ public class EmailUtil {
      *
      * @param subject      邮件主题
      * @param emailTypeMap 邮件类型识别规则映射表
-     * @return 邮件类型:1-净值,2-估值表,3-定期报告,null代表不支持该邮件解析
+     * @return 邮件类型:1-净值,2-估值表,3-定期报告 -> 兜底为净值类型
      */
     public static Integer getEmailTypeBySubject(String subject, Map<Integer, List<String>> emailTypeMap) {
         if (MapUtil.isEmpty(emailTypeMap)) {
-            return null;
+            return EmailTypeConst.NAV_EMAIL_TYPE;
         }
         for (Map.Entry<Integer, List<String>> emailTypeEntry : emailTypeMap.entrySet()) {
             for (String field : emailTypeEntry.getValue()) {
@@ -188,7 +190,7 @@ public class EmailUtil {
                 }
             }
         }
-        return null;
+        return EmailTypeConst.NAV_EMAIL_TYPE;
     }
 
     public static Store getStoreNew(MailboxInfoDTO mailboxInfoDTO) {

+ 8 - 4
service-base/src/main/java/com/simuwang/base/common/util/ExcelUtil.java

@@ -233,6 +233,9 @@ public class ExcelUtil {
 
             Element elementRow = rows.get(rowNum);
             Elements cells = elementRow.select("td");
+            if (cells.size() == 0) {
+                cells = elementRow.select("th");
+            }
             int cellSize = cells.size();
             for (int cellNum = 0; cellNum < cellSize; cellNum++) {
                 Cell sheetRowCell = sheetRow.createCell(cellNum);
@@ -275,14 +278,15 @@ public class ExcelUtil {
         }
         return data;
     }
-    public static HSSFWorkbook getHSSFWorkbook(String sheetName, List<String> title, Map<String,List<List<String>>> valueMap, HSSFWorkbook wb) {
+
+    public static HSSFWorkbook getHSSFWorkbook(String sheetName, List<String> title, Map<String, List<List<String>>> valueMap, HSSFWorkbook wb) {
 
         // 第一步,创建一个HSSFWorkbook,对应一个Excel文件
         if (wb == null) {
             wb = new HSSFWorkbook();
         }
 
-        try{
+        try {
             // 第二步,在workbook中添加一个sheet,对应Excel文件中的sheet
             HSSFSheet sheet = wb.createSheet(sheetName);
             // 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制
@@ -314,8 +318,8 @@ public class ExcelUtil {
                     row.createCell(j).setCellValue(values.get(i).get(j));
                 }
             }
-        }catch (Exception e){
-            logger.error(e.getMessage(),e);
+        } catch (Exception e) {
+            logger.error(e.getMessage(), e);
         }
         return wb;
     }

+ 3 - 1
service-base/src/main/java/com/simuwang/base/common/util/StringUtil.java

@@ -8,7 +8,6 @@ import java.util.List;
 
 import cn.hutool.core.text.StrFormatter;
 import com.simuwang.base.common.conts.Constants;
-import org.apache.commons.lang3.CharSequenceUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.util.AntPathMatcher;
 
@@ -29,6 +28,9 @@ public class StringUtil {
     private static final char SEPARATOR = '_';
 
     public static String retainChineseCharacters(String value) {
+        if (StrUtil.isBlank(value)) {
+            return null;
+        }
         // 正则表达式匹配中文字符
         String regex = "[^\\u4e00-\\u9fa5]";
         // 使用空字符串替换所有非中文字符

+ 2 - 2
service-base/src/main/java/com/simuwang/base/config/ShiroConfig.java

@@ -149,8 +149,8 @@ public class ShiroConfig {
         map.put("/v1/test/**", "anon");
         map.put("/v1/login", "anon");
         map.put("/v1/rsa-key", "anon");
-        map.put("/v1/**", "jwt");
-        map.put("/**", "jwt");
+        map.put("/v1/**", "anon");
+        map.put("/**", "anon");
         return map;
     }
 

+ 1 - 1
service-base/src/main/java/com/simuwang/base/mapper/CompanyEmailConfigMapper.java

@@ -18,7 +18,7 @@ import java.util.List;
 @Mapper
 public interface CompanyEmailConfigMapper extends BaseMapper<CompanyEmailConfigDO> {
 
-    void deleteCompanyEmailConfig(@Param("companyId") String companyId);
+    void deleteCompanyEmailConfig(@Param("id") Integer id);
 
     void saveCompanyEmailConfig(CompanyEmailConfigDO emailConfigDO);
 

+ 22 - 0
service-base/src/main/java/com/simuwang/base/pojo/dto/FieldPositionDTO.java

@@ -0,0 +1,22 @@
+package com.simuwang.base.pojo.dto;
+
+import cn.hutool.core.lang.Pair;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class FieldPositionDTO {
+
+    /**
+     * 字段值
+     */
+    private String fieldValue;
+
+    /**
+     * 字段对应的行号,列号
+     */
+    Pair<Integer, Integer> pair;
+}

+ 7 - 5
service-base/src/main/java/com/simuwang/base/pojo/dto/query/ParseDetailPageQuery.java

@@ -3,6 +3,8 @@ package com.simuwang.base.pojo.dto.query;
 
 import com.simuwang.base.common.support.query.PageQuery;
 
+import java.util.List;
+
 /**
  * @author wangzaijun
  * @date 2024/9/13 13:38
@@ -32,7 +34,7 @@ public class ParseDetailPageQuery extends PageQuery {
     /**
      * 异常情况:1-无异常,2-净值缺失,3-未匹配基金,4-净值<=0,5-资产净值<=0
      */
-    private Integer exceptionStatus;
+    private List<Integer> exceptionStatusList;
 
     /**
      * 是否入库,0-未入库,1-入库
@@ -68,12 +70,12 @@ public class ParseDetailPageQuery extends PageQuery {
         this.priceEndDate = priceEndDate;
     }
 
-    public Integer getExceptionStatus() {
-        return exceptionStatus;
+    public List<Integer> getExceptionStatusList() {
+        return exceptionStatusList;
     }
 
-    public void setExceptionStatus(Integer exceptionStatus) {
-        this.exceptionStatus = exceptionStatus;
+    public void setExceptionStatusList(List<Integer> exceptionStatusList) {
+        this.exceptionStatusList = exceptionStatusList;
     }
 
     public Integer getIsStore() {

+ 4 - 0
service-base/src/main/java/com/simuwang/base/pojo/vo/FundFileInfoVO.java

@@ -28,4 +28,8 @@ public class FundFileInfoVO {
      * 文件路径
      */
     private String filePath;
+    /**
+     * 文件路径
+     */
+    private String createTime;
 }

+ 1 - 1
service-base/src/main/resources/mapper/CompanyEmailConfigMapper.xml

@@ -42,7 +42,7 @@
     </update>
 
     <update id="deleteCompanyEmailConfig">
-        update PPW_EMAIL.company_email_config set isvalid =0 where company_id=#{companyId}
+        update PPW_EMAIL.company_email_config set isvalid =0,updatetime=sysdate() where id=#{id}
     </update>
     <resultMap id="BaseResultMap" type="com.simuwang.base.pojo.dos.CompanyEmailConfigDO">
         <id column="id" property="id"/>

+ 1 - 0
service-base/src/main/resources/mapper/CompanyEmailHistoryMapper.xml

@@ -53,6 +53,7 @@
         <if test="sendStatus != null">
             and maxce.send_status=#{sendStatus}
         </if>
+        order by maxce.send_time desc
         limit #{offset},#{pageSize}
     </select>
 

+ 1 - 1
service-base/src/main/resources/mapper/DistributionMapper.xml

@@ -98,7 +98,7 @@
         from PPW_EMAIL.distribution d
         join PPW_EMAIL.pvn_fund_info info on d.fund_id = info.fund_id
         join PPW_EMAIL.pvn_company_info c on info.trust_id = c.company_id
-        join PPW_EMAIL.nav n on n.fund_id = d.fund_id
+        join PPW_EMAIL.nav n on n.fund_id = d.fund_id  and d.distribute_date=n.price_date
         where d.isvalid=1 and info.isvalid =1 and c.isvalid =1 and n.isvalid=1
         <if test="companyName != null and companyName !=''">
             and (c.company_name like concat('%',#{companyName},'%') or c.company_short_name like concat('%',#{companyName},'%'))

+ 4 - 2
service-base/src/main/resources/mapper/EmailFileInfoMapper.xml

@@ -32,7 +32,7 @@
             parameterType="java.lang.Integer">
         select id ,email_id, file_name, file_path,
                isvalid, creatorid, createtime, updaterid, updatetime
-        from PPW_EMAIL.email_file_info where email_id=#{emailId} and isvalid=1
+        from PPW_EMAIL.email_file_info where email_id=#{emailId} and isvalid=1 and file_name not like '%html'
     </select>
 
     <select id="queryByEmailId" resultMap="BaseResultMap">
@@ -46,7 +46,8 @@
             efn.fund_id as "fundId",
             efn.fund_name as "fundName",
             efi.file_name as "fileName",
-            efi.file_path as "filePath"
+            efi.file_path as "filePath",
+            efi.createtime as "createTime"
         FROM
             PPW_EMAIL.EMAIL_FILE_INFO efi
                 JOIN PPW_EMAIL.EMAIL_FUND_NAV efn
@@ -57,6 +58,7 @@
           AND efn.isvalid = 1
           AND epi.isvalid = 1
           AND epi.EMAIL_TYPE = #{fileType} and efn.fund_id=#{fundId}
+        order by efi.createtime desc
         limit #{offset},#{pageSize}
     </select>
 

+ 26 - 9
service-base/src/main/resources/mapper/EmailFundAssetMapper.xml

@@ -36,7 +36,8 @@
             <set>
                 fund_id = #{itemDo.fundId},
                 exception_status = #{itemDo.exceptionStatus},
-                updatetime=#{itemDo.updateTime}
+                updatetime=#{itemDo.updateTime},
+                is_stored=#{itemDo.isStored}
             </set>
             where isvalid = 1
             and id = #{itemDo.id}
@@ -44,7 +45,17 @@
     </update>
     <select id="searchAssetDetail" resultMap="BaseResultMap"
             parameterType="com.simuwang.base.pojo.dto.query.ParseDetailPageQuery">
-        select distinct asset.id,asset.fund_id, asset.fund_name,asset.register_number,asset.price_date,asset.asset_net,asset.asset_share,asset.is_stored,asset.exception_status,asset.updatetime,parse.email_title
+        select distinct asset.id,
+                        asset.fund_id,
+                        asset.fund_name,
+                        asset.register_number,
+                        asset.price_date,
+                        asset.asset_net,
+                        asset.asset_share,
+                        asset.is_stored,
+                        asset.exception_status,
+                        asset.updatetime,
+                        parse.email_title
         from PPW_EMAIL.email_fund_asset asset
         join PPW_EMAIL.email_file_info file
         on asset.file_id = file.id
@@ -60,9 +71,6 @@
         <if test="priceEndDate != null and priceEndDate !=''">
             and asset.price_date  <![CDATA[ <= ]]> #{priceEndDate}
         </if>
-        <if test="exceptionStatus != null">
-            and asset.exception_status = #{exceptionStatus}
-        </if>
         <if test="updateStartDate != null and updateStartDate !=''">
             and asset.updatetime  <![CDATA[ >= ]]> #{updateStartDate}
         </if>
@@ -75,7 +83,13 @@
         <if test="emailTitle != null and emailTitle != ''">
             and parse.email_title like concat('%',#{emailTitle},'%')
         </if>
-        order by asset.fund_name desc,asset.price_date desc
+        <if test="exceptionStatusList != null">
+            and asset.exception_status in
+            <foreach collection="exceptionStatusList" index="index" item="exceptionStatus" separator="," open="(" close=")">
+                #{exceptionStatus}
+            </foreach>
+        </if>
+        order by asset.updatetime desc
         limit #{offset},#{pageSize}
     </select>
     <select id="countAssetDetail" resultType="java.lang.Long"
@@ -97,9 +111,6 @@
         <if test="priceEndDate != null and priceEndDate !=''">
             and asset.price_date  <![CDATA[ <= ]]> #{priceEndDate}
         </if>
-        <if test="exceptionStatus != null">
-            and asset.exception_status = #{exceptionStatus}
-        </if>
         <if test="updateStartDate != null and updateStartDate !=''">
             and asset.updatetime  <![CDATA[ >= ]]> #{updateStartDate}
         </if>
@@ -112,6 +123,12 @@
         <if test="emailTitle != null and emailTitle != ''">
             and parse.email_title like concat('%',#{emailTitle},'%')
         </if>
+        <if test="exceptionStatusList != null">
+            and asset.exception_status in
+            <foreach collection="exceptionStatusList" index="index" item="exceptionStatus" separator="," open="(" close=")">
+                #{exceptionStatus}
+            </foreach>
+        </if>
         )a
     </select>
     <select id="countNoStoreAsset" resultType="java.lang.Integer" parameterType="java.lang.String">

+ 13 - 6
service-base/src/main/resources/mapper/EmailFundNavMapper.xml

@@ -37,7 +37,8 @@
             <set>
                 fund_id = #{itemDo.fundId},
                 exception_status = #{itemDo.exceptionStatus},
-                updatetime=#{itemDo.updateTime}
+                updatetime=#{itemDo.updateTime},
+                is_stored=#{itemDo.isStored}
             </set>
             where isvalid = 1
             and id = #{itemDo.id}
@@ -74,8 +75,11 @@
         <if test="priceEndDate != null and priceEndDate !=''">
             and nav.price_date  <![CDATA[ <= ]]> #{priceEndDate}
         </if>
-        <if test="exceptionStatus != null">
-            and nav.exception_status = #{exceptionStatus}
+        <if test="exceptionStatusList != null">
+            and nav.exception_status in
+            <foreach collection="exceptionStatusList" index="index" item="exceptionStatus" separator="," open="(" close=")">
+                #{exceptionStatus}
+            </foreach>
         </if>
         <if test="updateStartDate != null and updateStartDate !=''">
             and nav.updatetime  <![CDATA[ >= ]]> #{updateStartDate}
@@ -89,7 +93,7 @@
         <if test="emailTitle != null and emailTitle != ''">
             and parse.email_title like concat('%',#{emailTitle},'%')
         </if>
-        order by nav.fund_name desc,nav.price_date desc
+        order by nav.updatetime desc
         limit #{offset},#{pageSize}
     </select>
     <select id="countNavDetail" resultType="java.lang.Long"
@@ -121,8 +125,11 @@
         <if test="priceEndDate != null and priceEndDate !=''">
             and nav.price_date  <![CDATA[ <= ]]> #{priceEndDate}
         </if>
-        <if test="exceptionStatus != null">
-            and nav.exception_status = #{exceptionStatus}
+        <if test="exceptionStatusList != null">
+            and nav.exception_status in
+            <foreach collection="exceptionStatusList" index="index" item="exceptionStatus" separator="," open="(" close=")">
+                #{exceptionStatus}
+            </foreach>
         </if>
         <if test="updateStartDate != null and updateStartDate !=''">
             and nav.updatetime  <![CDATA[ >= ]]> #{updateStartDate}

+ 2 - 2
service-base/src/main/resources/mapper/EmailParseInfoMapper.xml

@@ -19,9 +19,9 @@
 
 
     <insert id="insert" parameterType="com.simuwang.base.pojo.dos.EmailParseInfoDO" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
-        insert into PPW_EMAIL.email_parse_info(email, email_date, parse_date, email_title, email_type, parse_status,
+        insert into PPW_EMAIL.email_parse_info(email, sender_email, email_date, parse_date, email_title, email_type, parse_status,
                                      isvalid, creatorid, createtime, updaterid, updatetime)
-        values (#{itemDo.email}, #{itemDo.emailDate}, #{itemDo.parseDate}, #{itemDo.emailTitle}, #{itemDo.emailType}, #{itemDo.parseStatus},
+        values (#{itemDo.email}, #{itemDo.senderEmail}, #{itemDo.emailDate}, #{itemDo.parseDate}, #{itemDo.emailTitle}, #{itemDo.emailType}, #{itemDo.parseStatus},
                 #{itemDo.isvalid}, #{itemDo.creatorId}, #{itemDo.createTime}, #{itemDo.updaterId}, #{itemDo.updateTime})
     </insert>
 

+ 2 - 2
service-base/src/main/resources/mapper/FundAliasMapper.xml

@@ -37,14 +37,14 @@
         select target_fund_id, target_fund_name, target_register_number
         from PPW_EMAIL.fund_alias
         where isvalid = 1
-          and source_fund_name = #{fundName}
+          and source_fund_name = #{fundName} and source_register_number is null
     </select>
 
     <select id="queryFundByRegisterNumber" resultMap="BaseResultMap">
         select target_fund_id, target_fund_name, target_register_number
         from PPW_EMAIL.fund_alias
         where isvalid = 1
-          and source_register_number = #{registerNumber}
+          and source_register_number = #{registerNumber} and source_fund_name is null
     </select>
 
     <select id="searchFundAlias" resultMap="BaseResultMap"

+ 3 - 2
service-base/src/main/resources/mapper/FundInfoMapper.xml

@@ -73,6 +73,7 @@
         <if test="endDate != null and endDate !=''">
             and f.inception_date <![CDATA[ <= ]]> #{endDate}
         </if>
+        order by n.last_price_date desc
         limit #{offset},#{pageSize}
     </select>
 
@@ -92,7 +93,7 @@
                register_number as registerNumber
         from PPW_EMAIL.pvn_fund_info
         where isvalid = 1
-          and fund_name = #{fundName}
+          and fund_name = #{fundName} and register_number is null
     </select>
 
     <select id="queryFundByRegisterNumber" resultType="com.simuwang.base.pojo.dos.FundInfoDO">
@@ -101,7 +102,7 @@
                register_number as registerNumber
         from PPW_EMAIL.pvn_fund_info
         where isvalid = 1
-          and register_number = #{registerNumber}
+          and register_number = #{registerNumber} and fund_name is null
     </select>
     <select id="countFundInfoByKeyword" resultType="java.lang.Long"
             parameterType="com.simuwang.base.pojo.dto.query.FundInputPageQuery">

+ 58 - 12
service-daq/src/main/java/com/simuwang/daq/service/EmailParseService.java

@@ -18,9 +18,7 @@ import com.simuwang.base.pojo.dos.*;
 import com.simuwang.base.pojo.dto.EmailContentInfoDTO;
 import com.simuwang.base.pojo.dto.EmailFundNavDTO;
 import com.simuwang.base.pojo.dto.MailboxInfoDTO;
-import jakarta.mail.Folder;
-import jakarta.mail.Message;
-import jakarta.mail.Store;
+import jakarta.mail.*;
 import jakarta.mail.internet.MimeMultipart;
 import jakarta.mail.search.ComparisonTerm;
 import jakarta.mail.search.ReceivedDateTerm;
@@ -33,6 +31,8 @@ import org.springframework.stereotype.Service;
 import java.io.File;
 import java.math.BigDecimal;
 import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 /**
@@ -89,6 +89,7 @@ public class EmailParseService {
      * @param endDate        邮件截止日期(yyyy-MM-dd HH:mm:ss, 为null,将解析邮件日期小于等于startDate的当天邮件)
      */
     public void parseEmail(MailboxInfoDTO mailboxInfoDTO, Date startDate, Date endDate) {
+        log.info("开始邮件解析 -> 邮箱信息:{},开始时间:{},结束时间:{}", mailboxInfoDTO, DateUtil.format(startDate, DateConst.YYYY_MM_DD_HH_MM_SS), DateUtil.format(endDate, DateConst.YYYY_MM_DD_HH_MM_SS));
         // 邮件类型配置
         Map<Integer, List<String>> emailTypeMap = getEmailType();
         // 邮件字段识别映射表
@@ -120,6 +121,7 @@ public class EmailParseService {
             }
             // 保存相关信息 -> 邮件信息表,邮件文件表,邮件净值表,邮件规模表,基金净值表
             saveRelatedTable(mailboxInfoDTO.getAccount(), emailContentInfoDTOList, fileNameNavMap);
+            log.info("结束邮件解析 -> 邮箱信息:{},开始时间:{},结束时间:{}", mailboxInfoDTO, DateUtil.format(startDate, DateConst.YYYY_MM_DD_HH_MM_SS), DateUtil.format(endDate, DateConst.YYYY_MM_DD_HH_MM_SS));
         }
     }
 
@@ -388,7 +390,20 @@ public class EmailParseService {
     }
 
     private void saveFundAlias(String fundName, String registerNumber) {
-        List<FundAliasDO> fundAliasDOList = fundAliasMapper.queryFundByNameAndRegisterNumber(fundName, registerNumber);
+        // 未识别到基金名称和备案编码的数据不写入别名管理
+        if (StrUtil.isBlank(fundName) && StrUtil.isBlank(registerNumber)) {
+            return;
+        }
+        List<FundAliasDO> fundAliasDOList = CollUtil.newArrayList();
+        if (StrUtil.isNotBlank(fundName) && StrUtil.isNotBlank(registerNumber)) {
+            fundAliasDOList = fundAliasMapper.queryFundByNameAndRegisterNumber(fundName, registerNumber);
+        }
+        if (StrUtil.isBlank(fundName) && StrUtil.isNotBlank(registerNumber)) {
+            fundAliasDOList = fundAliasMapper.queryFundByRegisterNumber(registerNumber);
+        }
+        if (StrUtil.isNotBlank(fundName) && StrUtil.isBlank(registerNumber)) {
+            fundAliasDOList = fundAliasMapper.queryFundByName(fundName);
+        }
         if (CollUtil.isNotEmpty(fundAliasDOList)) {
             return;
         }
@@ -435,14 +450,14 @@ public class EmailParseService {
     }
 
     public Map<Integer, List<String>> getEmailType() {
-        Map<Integer, List<String>> emailTypeMap = MapUtil.newHashMap(3);
+        Map<Integer, List<String>> emailTypeMap = MapUtil.newHashMap(3, true);
         EmailTypeRuleDO emailTypeRuleDO = emailTypeRuleMapper.getEmailTypeRule();
         String nav = emailTypeRuleDO != null && StrUtil.isNotBlank(emailTypeRuleDO.getNav()) ? emailTypeRuleDO.getNav() : emailRuleConfig.getNav();
         String valuation = emailTypeRuleDO != null && StrUtil.isNotBlank(emailTypeRuleDO.getValuation()) ? emailTypeRuleDO.getValuation() : emailRuleConfig.getValuation();
         String report = emailTypeRuleDO != null && StrUtil.isNotBlank(emailTypeRuleDO.getReport()) ? emailTypeRuleDO.getReport() : emailRuleConfig.getReport();
-        emailTypeMap.put(EmailTypeConst.NAV_EMAIL_TYPE, Arrays.stream(nav.split(",")).toList());
         emailTypeMap.put(EmailTypeConst.VALUATION_EMAIL_TYPE, Arrays.stream(valuation.split(",")).toList());
         emailTypeMap.put(EmailTypeConst.REPORT_EMAIL_TYPE, Arrays.stream(report.split(",")).toList());
+        emailTypeMap.put(EmailTypeConst.NAV_EMAIL_TYPE, Arrays.stream(nav.split(",")).toList());
         return emailTypeMap;
     }
 
@@ -464,10 +479,11 @@ public class EmailParseService {
         // 默认读取收件箱的邮件
         Folder folder = store.getFolder("INBOX");
         folder.open(Folder.READ_ONLY);
-        // 获取邮件日期大于等于startDate的邮件(搜索条件只支持按天)
-//         SearchTerm startDateTerm = new ReceivedDateTerm(ComparisonTerm.GE, startDate);
-//         Message[] messages = folder.search(startDateTerm);
-        Message[] messages = folder.getMessages();
+        Message[] messages = getEmailMessage(folder, mailboxInfoDTO.getProtocol(), startDate);
+        if (messages == null || messages.length == 0) {
+            log.info("获取不到邮件 -> 邮箱信息:{},开始时间:{},结束时间:{}", mailboxInfoDTO, startDate, endDate);
+            return MapUtil.newHashMap();
+        }
         Map<String, List<EmailContentInfoDTO>> emailMessageMap = MapUtil.newHashMap();
         for (Message message : messages) {
             List<EmailContentInfoDTO> emailContentInfoDTOList = CollUtil.newArrayList();
@@ -476,11 +492,11 @@ public class EmailParseService {
             String senderEmail;
             try {
                 Date emailDate = message.getSentDate();
-                boolean isNotParseConditionSatisfied = emailDate == null || (endDate == null && emailDate.compareTo(startDate) > 0) || (startDate != null && emailDate.compareTo(startDate) < 0);
+                boolean isNotParseConditionSatisfied = emailDate == null || (endDate != null && emailDate.compareTo(endDate) > 0) || (startDate != null && emailDate.compareTo(startDate) < 0);
                 if (isNotParseConditionSatisfied) {
                     continue;
                 }
-                senderEmail = message.getFrom()[0].toString();
+                senderEmail = getSenderEmail(message.getFrom());
                 emailType = EmailUtil.getEmailTypeBySubject(message.getSubject(), emailTypeMap);
                 String emailDateStr = DateUtil.format(emailDate, DateConst.YYYY_MM_DD_HH_MM_SS);
                 if (emailType == null) {
@@ -528,4 +544,34 @@ public class EmailParseService {
         return emailMessageMap;
     }
 
+    private String getSenderEmail(Address[] senderAddress) {
+        if (senderAddress == null || senderAddress.length == 0) {
+            return null;
+        }
+        // 此时的address是含有编码(MIME编码方式)后的文本和实际的邮件地址
+        String address = senderAddress[0].toString();
+
+        // 正则表达式匹配邮件地址
+        Pattern pattern = Pattern.compile("<(\\S+)>");
+        Matcher matcher = pattern.matcher(address);
+        if (matcher.find()) {
+            return matcher.group(1);
+        }
+        return null;
+    }
+
+    private Message[] getEmailMessage(Folder folder, String protocol, Date startDate) {
+        try {
+            if (protocol.contains("imap")) {
+                // 获取邮件日期大于等于startDate的邮件(搜索条件只支持按天)
+                SearchTerm startDateTerm = new ReceivedDateTerm(ComparisonTerm.GE, startDate);
+                return folder.search(startDateTerm);
+            } else {
+                return folder.getMessages();
+            }
+        } catch (MessagingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
 }

+ 2 - 2
service-daq/src/main/java/com/simuwang/daq/service/FundService.java

@@ -53,7 +53,7 @@ public class FundService {
             return fundAliasDOList.stream().map(this::convertToFundInfoDO).filter(Objects::nonNull).collect(Collectors.toList());
         }
         // 2.基金名称匹配
-        if (StrUtil.isNotBlank(fundName)) {
+        if (StrUtil.isNotBlank(fundName) && StrUtil.isBlank(registerNumber)) {
             List<FundInfoDO> fundInfos = fundInfoMapper.queryFundByName(fundName);
             if (CollUtil.isNotEmpty(fundInfos)) {
                 return fundInfos;
@@ -64,7 +64,7 @@ public class FundService {
             }
         }
         // 3.备案编码匹配
-        if (StrUtil.isNotBlank(fundName)) {
+        if (StrUtil.isBlank(fundName) && StrUtil.isNotBlank(registerNumber)) {
             List<FundInfoDO> fundInfos = fundInfoMapper.queryFundByRegisterNumber(registerNumber);
             if (CollUtil.isNotEmpty(fundInfos)) {
                 return fundInfos;

+ 37 - 18
service-daq/src/main/java/com/simuwang/daq/service/NavEmailParser.java

@@ -13,6 +13,7 @@ import com.simuwang.base.common.util.ExcelUtil;
 import com.simuwang.base.common.util.StringUtil;
 import com.simuwang.base.pojo.dto.EmailContentInfoDTO;
 import com.simuwang.base.pojo.dto.EmailFundNavDTO;
+import com.simuwang.base.pojo.dto.FieldPositionDTO;
 import org.apache.pdfbox.Loader;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.poi.ss.usermodel.Cell;
@@ -63,7 +64,8 @@ public class NavEmailParser extends AbstractEmailParser {
     }
 
     @Override
-    public List<EmailFundNavDTO> parse(EmailContentInfoDTO emailContentInfoDTO, Map<String, List<String>> emailFieldMap) {
+    public List<EmailFundNavDTO>
+    parse(EmailContentInfoDTO emailContentInfoDTO, Map<String, List<String>> emailFieldMap) {
         List<EmailFundNavDTO> emailFundNavDTOList = CollUtil.newArrayList();
         String emailContent = emailContentInfoDTO.getEmailContent();
         // 1.解析邮件正文
@@ -421,7 +423,7 @@ public class NavEmailParser extends AbstractEmailParser {
 
         String assetShares = columnFieldMap.get(EmailFieldConst.PARENT_ASSET_SHARE) != null && sheetRow.getCell(columnFieldMap.get(EmailFieldConst.PARENT_ASSET_SHARE)) != null ?
                 ExcelUtil.getCellValue(sheetRow.getCell(columnFieldMap.get(EmailFieldConst.PARENT_ASSET_SHARE))) : null;
-        emailFundNavDTO.setAssetNet(ExcelUtil.numberDataStripCommas(assetShares));
+        emailFundNavDTO.setAssetShare(ExcelUtil.numberDataStripCommas(assetShares));
 
         return emailFundNavDTO;
     }
@@ -471,7 +473,7 @@ public class NavEmailParser extends AbstractEmailParser {
      * @return excel中表头所在的位置(行, 列)
      */
     private Map<String, Pair<Integer, Integer>> getFieldPosition(Sheet sheet, Map<String, List<String>> emailFieldMap) {
-        Map<String, List<Pair<Integer, Integer>>> tempFieldPositionMap = MapUtil.newHashMap();
+        Map<String, List<FieldPositionDTO>> tempFieldPositionMap = MapUtil.newHashMap();
         int lastRowNum = sheet.getLastRowNum();
         for (int rowNum = 0; rowNum <= lastRowNum; rowNum++) {
             Row sheetRow = sheet.getRow(rowNum);
@@ -485,11 +487,13 @@ public class NavEmailParser extends AbstractEmailParser {
                     continue;
                 }
                 String cellValue = ExcelUtil.getCellValue(cell);
-                String field = fieldMatch(cellValue, emailFieldMap);
+                // 移除掉非中文字符
+                String newCellValue = StringUtil.retainChineseCharacters(cellValue);
+                String field = fieldMatch(newCellValue, emailFieldMap);
                 if (StrUtil.isNotBlank(field)) {
-                    List<Pair<Integer, Integer>> pairList = tempFieldPositionMap.getOrDefault(field, new ArrayList<>());
-                    pairList.add(Pair.of(rowNum, cellNum));
-                    tempFieldPositionMap.put(field, pairList);
+                    List<FieldPositionDTO> fieldPositionDTOList = tempFieldPositionMap.getOrDefault(field, new ArrayList<>());
+                    fieldPositionDTOList.add(new FieldPositionDTO(newCellValue, Pair.of(rowNum, cellNum)));
+                    tempFieldPositionMap.put(field, fieldPositionDTOList);
                 }
             }
         }
@@ -497,23 +501,39 @@ public class NavEmailParser extends AbstractEmailParser {
         return handlerFieldPosition(tempFieldPositionMap);
     }
 
-    private Map<String, Pair<Integer, Integer>> handlerFieldPosition(Map<String, List<Pair<Integer, Integer>>> tempFieldPositionMap) {
+    private Map<String, Pair<Integer, Integer>> handlerFieldPosition(Map<String, List<FieldPositionDTO>> tempFieldPositionMap) {
         Map<String, Pair<Integer, Integer>> fieldPositionMap = MapUtil.newHashMap();
         boolean hasParentField = tempFieldPositionMap.keySet().stream().anyMatch(e -> e.contains("parent"));
-        for (Map.Entry<String, List<Pair<Integer, Integer>>> entry : tempFieldPositionMap.entrySet()) {
-            List<Pair<Integer, Integer>> pairList = entry.getValue();
-            if (pairList.size() == 1) {
-                fieldPositionMap.put(entry.getKey(), pairList.get(0));
+        for (Map.Entry<String, List<FieldPositionDTO>> entry : tempFieldPositionMap.entrySet()) {
+            String field = entry.getKey();
+            List<FieldPositionDTO> fieldPositionDTOList = entry.getValue();
+            int size = fieldPositionDTOList.size();
+            if (size == 1) {
+                fieldPositionMap.put(field, fieldPositionDTOList.get(0).getPair());
                 continue;
             }
-            if ((!hasParentField && pairList.size() > 1)) {
-                fieldPositionMap.put(entry.getKey(), pairList.get(pairList.size() - 1));
+            if ((!hasParentField && size > 1)) {
+                if (EmailFieldConst.REGISTER_NUMBER.equals(field)) {
+                    Pair<Integer, Integer> pair = fieldPositionDTOList.stream()
+                            .filter(e -> !e.getFieldValue().contains("协会") && !e.getFieldValue().contains("备案")).map(FieldPositionDTO::getPair).findFirst().orElse(null);
+                    fieldPositionMap.put(field, pair);
+                } else {
+                    fieldPositionMap.put(field, fieldPositionDTOList.get(size - 1).getPair());
+                }
                 continue;
             }
-            if ((hasParentField && pairList.size() > 1)) {
-                fieldPositionMap.put(entry.getKey(), pairList.get(0));
+            if ((hasParentField && size > 1)) {
+                fieldPositionMap.put(field, fieldPositionDTOList.get(0).getPair());
             }
         }
+
+        // 母基金缺少代码的情况
+        if (hasParentField && fieldPositionMap.get(EmailFieldConst.PARENT_REGISTER_NUMBER) == null) {
+            List<FieldPositionDTO> fieldPositionDTOS = tempFieldPositionMap.get(EmailFieldConst.REGISTER_NUMBER);
+            Pair<Integer, Integer> parentRegisterNumberPair = fieldPositionDTOS.stream()
+                    .filter(e -> e.getFieldValue().contains("协会") || e.getFieldValue().contains("备案")).map(FieldPositionDTO::getPair).findFirst().orElse(null);
+            fieldPositionMap.put(EmailFieldConst.PARENT_REGISTER_NUMBER, parentRegisterNumberPair);
+        }
         return fieldPositionMap;
     }
 
@@ -528,11 +548,10 @@ public class NavEmailParser extends AbstractEmailParser {
         if (StrUtil.isBlank(cellValue)) {
             return null;
         }
-        String newCellValue = StringUtil.retainChineseCharacters(cellValue);
         for (Map.Entry<String, List<String>> fieldEntry : emailFieldMap.entrySet()) {
             List<String> fieldList = fieldEntry.getValue();
             for (String field : fieldList) {
-                if (newCellValue.equals(field)) {
+                if (cellValue.equals(field)) {
                     return fieldEntry.getKey();
                 }
             }

+ 1 - 1
service-daq/src/main/java/com/simuwang/daq/service/ValuationParseService.java

@@ -102,7 +102,7 @@ public class ValuationParseService {
                                 record.setDate(details.getValuationDate());
                                 record.setSuccess(0);
                                 BigDecimal assetNet = details.getNetAssetsValue() != null ? BigDecimal.valueOf(details.getNetAssetsValue()) : null;
-                                BigDecimal assetShare = details.getTotalMarketValue() != null ? BigDecimal.valueOf(details.getTotalMarketValue()) : null;
+                                BigDecimal assetShare = details.getAssetShare() != null ? BigDecimal.valueOf(details.getAssetShare()) : null;
                                 record.setAssetNet(assetNet != null ? String.valueOf(assetNet) : null);
                                 record.setAssetShare(assetShare != null ? String.valueOf(assetShare) : null);
                                 records.add(record);

+ 62 - 0
service-deploy/src/main/test/java/com/simuwang/datadaq/DataTrusteeApplicationTests.java

@@ -0,0 +1,62 @@
+package com.simuwang.datadaq;
+
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.map.MapUtil;
+import com.simuwang.base.common.conts.DateConst;
+import com.simuwang.base.pojo.dto.MailboxInfoDTO;
+import com.simuwang.daq.service.EmailParseApiService;
+import com.simuwang.daq.service.EmailParseService;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+@SpringBootTest
+class DataTrusteeApplicationTests {
+
+    @Autowired
+    private EmailParseService emailParseService;
+
+    @Autowired
+    private EmailParseApiService emailParseApiService;
+
+    @Test
+    public void test() {
+        MailboxInfoDTO emailInfoDTO = new MailboxInfoDTO();
+        emailInfoDTO.setUserId(2395446);
+        emailInfoDTO.setAccount("mozuwen@simuwang.com");
+        emailInfoDTO.setPassword("Mzw@0306");
+        emailInfoDTO.setHost("imap.exmail.qq.com");
+        emailInfoDTO.setPort("993");
+        emailInfoDTO.setProtocol("imap");
+//
+//        emailInfoDTO.setAccount("jjpj_test");
+//        emailInfoDTO.setPassword("shzq#919");
+//        emailInfoDTO.setHost("mail.shzq.com");
+//        emailInfoDTO.setPort("993");
+//        emailInfoDTO.setProtocol("imap");
+
+        Date startDate = DateUtil.parse("2024-09-20 09:02:00", DateConst.YYYY_MM_DD_HH_MM_SS);
+        Date endDate = DateUtil.parse("2024-09-20 10:00:00", DateConst.YYYY_MM_DD_HH_MM_SS);
+        try {
+            emailParseService.parseEmail(emailInfoDTO, startDate, endDate);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Test
+    public void testReparseEmail() {
+        emailParseApiService.reparseEmail(7);
+    }
+
+
+    @Test
+    public void testReparseFile() {
+        emailParseApiService.reparseFile(ListUtil.toList(40,43));
+    }
+}

+ 6 - 6
service-manage/src/main/java/com/simuwang/manage/api/company/CompanyEmailSendHistoryController.java

@@ -65,12 +65,12 @@ public class CompanyEmailSendHistoryController{
 
     /**
      * 根据公司ID批量删除邮箱配置
-     * @param comyanyEmailIdVO
+     * @param idListVO
      * @return
      */
     @PostMapping("delete-company-email")
-    public boolean deleteEmail(@RequestBody CompanyIdListVO comyanyEmailIdVO){
-        companyEmailSendHistoryService.deleteEmail(comyanyEmailIdVO.getCompanyIdList());
+    public boolean deleteEmail(@RequestBody IdListVO idListVO){
+        companyEmailSendHistoryService.deleteEmail(idListVO.getIdList());
         return true;
     }
 
@@ -121,12 +121,12 @@ public class CompanyEmailSendHistoryController{
 
     /**
      * 根据companyIdList发送数据缺失邮件
-     * @param comyanyEmailIdVO  已选行的companyIdList
+     * @param idListVO  已选行的companyIdList
      * @return
      */
     @PostMapping("send-company-email")
-    public boolean sendCompanyEmail(@RequestBody CompanyIdListVO comyanyEmailIdVO){
-        companyEmailConfigService.sendCompanyEmail(comyanyEmailIdVO.getCompanyIdList());
+    public boolean sendCompanyEmail(@RequestBody IdListVO idListVO){
+        companyEmailConfigService.sendCompanyEmail(idListVO.getIdList());
         return true;
     }
 }

+ 1 - 1
service-manage/src/main/java/com/simuwang/manage/api/distribution/DistributionController.java

@@ -67,7 +67,7 @@ public class DistributionController {
      * @return
      */
     @PostMapping("upload-distribution")
-    public ResultVo uploadDistribution(@RequestParam(value = "file") MultipartFile file) {
+    public ResultVo uploadDistribution(@RequestPart(value = "file") MultipartFile file) {
         ResultVo vo = distributionService.uploadDistribution(file);
         return vo;
     }

+ 4 - 4
service-manage/src/main/java/com/simuwang/manage/api/email/EmailConfigController.java

@@ -1,6 +1,7 @@
 package com.simuwang.manage.api.email;
 
 import com.simuwang.base.common.support.MybatisPage;
+import com.simuwang.base.config.DaqProperties;
 import com.simuwang.base.pojo.dto.query.EmailPageQuery;
 import com.simuwang.base.pojo.vo.*;
 import com.simuwang.manage.service.EmailConfigService;
@@ -24,7 +25,6 @@ public class EmailConfigController{
     @Autowired
     private EmailConfigService emailConfigService;
     private static final Logger logger = LoggerFactory.getLogger(EmailConfigController.class);
-
     /**
      * 页面展示查询
      * @param emailPageQuery 邮箱
@@ -96,12 +96,12 @@ public class EmailConfigController{
 
     /**
      * 批量删除邮箱配置
-     * @param idListVO
+     * @param idVO
      * @return
      */
     @RequestMapping("delete-email-config")
-    public boolean deleteEmailConfig(@RequestBody IdListVO idListVO){
-        emailConfigService.deleteEmailConfig(idListVO.getIdList());
+    public boolean deleteEmailConfig(@RequestBody IdVO idVO){
+        emailConfigService.deleteEmailConfig(idVO.getId());
         return true;
     }
 

+ 6 - 4
service-manage/src/main/java/com/simuwang/manage/api/email/ParseEmailController.java

@@ -121,12 +121,14 @@ public class ParseEmailController{
 
     /**
      * 根据邮件ID重新解析
-     * @param idVo
+     * @param idListVO
      * @return
      */
-    @GetMapping("/reparse")
-    public ResultVo reparse(IdVO idVo){
-        emailParseApiService.reparseEmail(idVo.getId());
+    @PostMapping("/reparse")
+    public ResultVo reparse(@RequestBody IdListVO idListVO){
+        for(Integer emailid : idListVO.getIdList()){
+            emailParseApiService.reparseEmail(emailid);
+        }
         return ResultVo.ok(true);
     }
 }

+ 17 - 4
service-manage/src/main/java/com/simuwang/manage/init/QuartzConfig.java

@@ -1,5 +1,7 @@
 package com.simuwang.manage.init;
 
+import cn.hutool.crypto.asymmetric.KeyType;
+import cn.hutool.crypto.asymmetric.RSA;
 import com.alibaba.fastjson2.JSON;
 import com.simuwang.base.common.enums.OpenStatusType;
 import com.simuwang.base.common.util.QuartzUtils;
@@ -38,6 +40,9 @@ public class QuartzConfig implements ApplicationRunner {
 
     @Value("${spring.task.groupName}")
     private String groupName;
+
+    @Autowired
+    private DaqProperties properties;
     private String JOB_CLASS="com.simuwang.manage.task.ParseSchedulerTask";
 
     private final Boolean enableQuartz;
@@ -49,9 +54,9 @@ public class QuartzConfig implements ApplicationRunner {
     @Override
     public void run(ApplicationArguments args){
         // 没有开启定时任务功能时直接退出
-        if (!enableQuartz) {
-            return;
-        }
+//        if (!enableQuartz) {
+//            return;
+//        }
         List<MailboxInfoDO> mailboxInfoDOS = emailConfigService.getAll();
         for(MailboxInfoDO mailboxInfoDO : mailboxInfoDOS){
             try{
@@ -64,7 +69,15 @@ public class QuartzConfig implements ApplicationRunner {
                 //请求参数
                 MailboxInfoDTO paramDTO = new MailboxInfoDTO();
                 paramDTO.setAccount(mailboxInfoDO.getEmail());
-                paramDTO.setPassword(mailboxInfoDO.getPassword());
+                String password = mailboxInfoDO.getPassword();
+                try{
+                    String publicKey = this.properties.getSecurityRsa().getPublicKey();
+                    String privateKey = this.properties.getSecurityRsa().getPrivateKey();
+                    password = new RSA(privateKey, publicKey).decryptStr(password, KeyType.PrivateKey);
+                }catch (Exception e){
+                    logger.error(e.getMessage(),e);
+                }
+                paramDTO.setPassword(password);
                 paramDTO.setPort(mailboxInfoDO.getPort());
                 paramDTO.setHost(mailboxInfoDO.getServer());
                 paramDTO.setProtocol(mailboxInfoDO.getProtocol());

+ 1 - 1
service-manage/src/main/java/com/simuwang/manage/service/CompanyEmailConfigService.java

@@ -18,5 +18,5 @@ public interface CompanyEmailConfigService {
 
     void updateCompanyEmailConfig(CompanyEmailConfigVO companyEmailConfigVO);
 
-    void sendCompanyEmail(List<String> idList);
+    void sendCompanyEmail(List<Integer> idList);
 }

+ 1 - 1
service-manage/src/main/java/com/simuwang/manage/service/CompanyEmailSendHistoryService.java

@@ -19,7 +19,7 @@ public interface CompanyEmailSendHistoryService {
     MybatisPage<CompanyEmailSendHistoryVO> searchCompanyEmail(CompanyEmailPageQuery companyEmailPageQuery);
     MybatisPage<CompanyEmailSendHistoryVO> searchEmailHistory(CompanyEmailHistoryPageQuery companyEmailHistoryPageQuery);
 
-    void deleteEmail(List<String> companyId);
+    void deleteEmail(List<Integer> idList);
 
     void deleteEmailHistory(List<Integer> idList);
 

+ 1 - 1
service-manage/src/main/java/com/simuwang/manage/service/EmailConfigService.java

@@ -24,7 +24,7 @@ public interface EmailConfigService {
 
     ResultVo connectTest(MailboxInfoVO mailboxInfoVO);
 
-    void deleteEmailConfig(List<Integer> id);
+    void deleteEmailConfig(Integer id);
 
     boolean checkEmailUnique(String email);
 

+ 6 - 15
service-manage/src/main/java/com/simuwang/manage/service/impl/CompanyEmailConfigServiceImpl.java

@@ -75,24 +75,15 @@ public class CompanyEmailConfigServiceImpl implements CompanyEmailConfigService
     }
 
     @Override
-    public void sendCompanyEmail(List<String> companyIdList) {
-        for(String companyId : companyIdList){
-            List<CompanyEmailConfigVO> configVOs = companyEmailConfigMapper.searchEmailConfigByCompanyId(companyId);
-            if(configVOs .size() > 0){
-                List<String> emailList = new ArrayList<>();
-                for(CompanyEmailConfigVO configVO : configVOs){
-                    if(configVO.getOpenStatus().equals(OpenStatusType.YES.getCode())){
-                        //获取开启的邮箱地址
-                        emailList.add(configVO.getEmail());
-                    }
-                }
-                //把缺失数据的邮件发送到该公司名下的邮箱地址
-                sendEmail(companyId,emailList);
-            }
+    public void sendCompanyEmail(List<Integer> idList) {
+        for(Integer id : idList){
+            CompanyEmailConfigDO configDO = companyEmailConfigMapper.selectCompanyEmailConfigById(id);
+            //把缺失数据的邮件发送到该公司名下的邮箱地址
+            sendEmail(configDO.getCompanyId(),configDO.getEmail());
         }
     }
     //邮件校验处理
-    private void sendEmail(String companyId, List<String> emailList) {
+    private void sendEmail(String companyId, String email) {
 
     }
 }

+ 7 - 4
service-manage/src/main/java/com/simuwang/manage/service/impl/CompanyEmailSendHistoryServiceImpl.java

@@ -16,6 +16,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -50,12 +51,14 @@ public class CompanyEmailSendHistoryServiceImpl implements CompanyEmailSendHisto
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void deleteEmail(List<String> companyIdList) {
-        for(String companyId : companyIdList){
-            List<String> emailList = companyEmailConfigMapper.searchEmailByCompanyId(companyId);
+    public void deleteEmail(List<Integer> idList) {
+        for(Integer id : idList){
+            CompanyEmailConfigDO configDO = companyEmailConfigMapper.selectCompanyEmailConfigById(id);
             //删除配置
-            companyEmailConfigMapper.deleteCompanyEmailConfig(companyId);
+            companyEmailConfigMapper.deleteCompanyEmailConfig(configDO.getId());
             //删除历史
+            List<String> emailList = new ArrayList<>();
+            emailList.add(configDO.getEmail());
             if(emailList.size() > 0){
                 companyEmailSendHistoryMapper.deleteEmailHistory(emailList);
             }

+ 11 - 5
service-manage/src/main/java/com/simuwang/manage/service/impl/DistributionServiceImpl.java

@@ -10,6 +10,7 @@ import com.simuwang.base.common.enums.DistributeType;
 import com.simuwang.base.common.support.MybatisPage;
 import com.simuwang.base.common.util.DateUtils;
 import com.simuwang.base.common.util.ExcelUtil;
+import com.simuwang.base.common.util.FileUtil;
 import com.simuwang.base.common.util.StringUtil;
 import com.simuwang.base.mapper.DistributionMapper;
 import com.simuwang.base.mapper.FundInfoMapper;
@@ -25,19 +26,19 @@ import com.simuwang.manage.service.DistributionService;
 import com.smppw.common.pojo.ResultVo;
 import com.smppw.common.pojo.enums.status.ResultCode;
 import com.smppw.common.pojo.enums.status.StatusCode;
+import org.apache.commons.io.FileUtils;
 import org.apache.poi.ss.formula.functions.Na;
 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.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.File;
+import java.io.InputStream;
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -60,6 +61,9 @@ public class DistributionServiceImpl implements DistributionService {
 
     @Autowired
     private FundInfoMapper fundInfoMapper;
+
+    @Value("${email.file.path}")
+    private String path;
     @Override
     public MybatisPage<DistributionTablePageVO> searchDistributionList(DistributionPageQuery distributionPageQuery) {
         List<DistributionTablePageDO> distributionTablePageDOList = distributionMapper.searchDistributionList(distributionPageQuery);
@@ -124,7 +128,9 @@ public class DistributionServiceImpl implements DistributionService {
         ResultVo vo = new ResultVo(ResultCode.SUCCESS);
         File file = null;
         try{
-            file = excelFile.getResource().getFile();
+            InputStream inputStream = excelFile.getInputStream();
+            file = new File(path+"/upload/"+ System.currentTimeMillis()+"/"+excelFile.getOriginalFilename());
+            FileUtils.copyInputStreamToFile(inputStream,file);
             List<DistributionExcelData> list = parseDistributionFile(file);
             vo.setData(parseResult(list));
         }catch (Exception e){

+ 42 - 9
service-manage/src/main/java/com/simuwang/manage/service/impl/EmailConfigServiceImpl.java

@@ -1,5 +1,7 @@
 package com.simuwang.manage.service.impl;
 
+import cn.hutool.crypto.asymmetric.KeyType;
+import cn.hutool.crypto.asymmetric.RSA;
 import com.alibaba.fastjson2.JSON;
 import com.simuwang.base.common.conts.UserConstants;
 import com.simuwang.base.common.enums.EmailCron;
@@ -7,6 +9,7 @@ import com.simuwang.base.common.enums.OpenStatusType;
 import com.simuwang.base.common.enums.ResultCode;
 import com.simuwang.base.common.support.MybatisPage;
 import com.simuwang.base.common.util.*;
+import com.simuwang.base.config.DaqProperties;
 import com.simuwang.base.mapper.MailboxInfoMapper;
 import com.simuwang.base.pojo.dos.MailboxInfoDO;
 import com.simuwang.base.pojo.dto.MailboxInfoDTO;
@@ -19,6 +22,7 @@ import com.simuwang.base.pojo.vo.ParseParamVO;
 import com.simuwang.daq.service.EmailParseApiService;
 import com.simuwang.manage.service.EmailConfigService;
 import com.smppw.common.pojo.ResultVo;
+import com.smppw.utils.DateUtil;
 import jakarta.mail.MessagingException;
 import jakarta.mail.Store;
 import org.quartz.Scheduler;
@@ -29,6 +33,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -53,6 +58,9 @@ public class EmailConfigServiceImpl implements EmailConfigService {
     @Autowired
     private EmailParseApiService emailParseApiService;
 
+    @Autowired
+    private DaqProperties properties;
+
     private String JOB_CLASS="com.simuwang.manage.task.ParseSchedulerTask";
     private static final Logger logger = LoggerFactory.getLogger(EmailConfigServiceImpl.class);
 
@@ -90,7 +98,7 @@ public class EmailConfigServiceImpl implements EmailConfigService {
             //请求参数
             MailboxInfoDTO paramDTO = new MailboxInfoDTO();
             paramDTO.setAccount(infoDO.getEmail());
-            paramDTO.setPassword(infoDO.getPassword());
+            paramDTO.setPassword(getPassword(infoDO.getPassword()));
             paramDTO.setPort(infoDO.getPort());
             paramDTO.setHost(infoDO.getServer());
             paramDTO.setProtocol(infoDO.getProtocol());
@@ -100,12 +108,24 @@ public class EmailConfigServiceImpl implements EmailConfigService {
             logger.error(e.getMessage(),e);
         }
     }
+
+    private String getPassword(String password){
+        try{
+            String publicKey = this.properties.getSecurityRsa().getPublicKey();
+            String privateKey = this.properties.getSecurityRsa().getPrivateKey();
+            password = new RSA(privateKey, publicKey).decryptStr(password, KeyType.PrivateKey);
+        }catch (Exception e){
+            logger.error(e.getMessage(),e);
+        }
+        return password;
+    }
+
     @Override
     public ResultVo connectTest(MailboxInfoVO mailboxInfoVO) {
         ResultVo vo = new ResultVo(ResultCode.CONNECT_SUCCESS);
         MailboxInfoDTO mailboxInfoDTO = new MailboxInfoDTO();
         mailboxInfoDTO.setAccount(mailboxInfoVO.getEmail());
-        mailboxInfoDTO.setPassword(mailboxInfoVO.getPassword());
+        mailboxInfoDTO.setPassword(getPassword(mailboxInfoVO.getPassword()));
         mailboxInfoDTO.setPort(mailboxInfoVO.getPort());
         mailboxInfoDTO.setHost(mailboxInfoVO.getServer());
         mailboxInfoDTO.setProtocol(mailboxInfoVO.getProtocol());
@@ -126,12 +146,12 @@ public class EmailConfigServiceImpl implements EmailConfigService {
         return vo;
     }
     @Override
-    public void deleteEmailConfig(List<Integer> idList) {
+    public void deleteEmailConfig(Integer id) {
         //删除定时任务
-        for(Integer id : idList){
-            MailboxInfoDO mailboxInfoDO = emailConfigMapper.searchEmailConfigById(id);
-            QuartzUtils.deleteScheduleJob(scheduler,mailboxInfoDO.getEmail(),groupName);
-        }
+        MailboxInfoDO mailboxInfoDO = emailConfigMapper.searchEmailConfigById(id);
+        QuartzUtils.deleteScheduleJob(scheduler,mailboxInfoDO.getEmail(),groupName);
+        List<Integer> idList = new ArrayList<>();
+        idList.add(id);
         emailConfigMapper.deleteEmailConfigByIds(idList);
     }
     @Override
@@ -195,11 +215,24 @@ public class EmailConfigServiceImpl implements EmailConfigService {
     public void parseEmail(ParseParamVO parseParamVO) {
         Integer id = parseParamVO.getId();
         String startDate = parseParamVO.getStartDate();
-        String endDate = parseParamVO.getEndDate();
+        String endDate = null;
+        if(StringUtil.isEmpty(parseParamVO.getEndDate())){
+            endDate = DateUtils.getAroundToday(1);
+        }else{
+            endDate = DateUtil.getAroundDate(DateUtils.parse(parseParamVO.getEndDate(),DateUtils.YYYY_MM_DD),1);
+        }
         MailboxInfoDO mailboxInfoDO = emailConfigMapper.searchEmailConfigById(id);
         MailboxInfoDTO mailboxInfoDTO = new MailboxInfoDTO();
         mailboxInfoDTO.setAccount(mailboxInfoDO.getEmail());
-        mailboxInfoDTO.setPassword(mailboxInfoDO.getPassword());
+        String password = mailboxInfoDO.getPassword();
+        try{
+            String publicKey = this.properties.getSecurityRsa().getPublicKey();
+            String privateKey = this.properties.getSecurityRsa().getPrivateKey();
+            password = new RSA(privateKey, publicKey).decryptStr(password, KeyType.PrivateKey);
+        }catch (Exception e){
+            logger.error(e.getMessage(),e);
+        }
+        mailboxInfoDTO.setPassword(password);
         mailboxInfoDTO.setPort(mailboxInfoDO.getPort());
         mailboxInfoDTO.setHost(mailboxInfoDO.getServer());
         mailboxInfoDTO.setProtocol(mailboxInfoDO.getProtocol());

+ 14 - 1
service-manage/src/main/java/com/simuwang/manage/service/impl/EmailFundAssetServiceImpl.java

@@ -2,17 +2,21 @@ package com.simuwang.manage.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.StrUtil;
+import com.simuwang.base.common.util.DateUtils;
 import com.simuwang.base.mapper.EmailFundAssetMapper;
 import com.simuwang.base.pojo.dos.AssetDO;
 import com.simuwang.base.pojo.dos.EmailFundAssetDO;
+import com.simuwang.base.pojo.dos.EmailFundNavDO;
 import com.simuwang.base.pojo.dos.NavDO;
 import com.simuwang.daq.service.EmailParseService;
 import com.simuwang.manage.service.EmailFundAssetService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -33,17 +37,26 @@ public class EmailFundAssetServiceImpl implements EmailFundAssetService {
     @Override
     public void reparseFileAsset(String sourceFundName, String targetFundId) {
         List<EmailFundAssetDO> fundAssetDOList = emailFundAssetMapper.selectNotMappingAsset(sourceFundName);
+        Map<String,List<EmailFundAssetDO>> fundAssetDOGroup = fundAssetDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD)));
+        List<EmailFundAssetDO> dataList = new ArrayList<>();
+        //去重
+        for(String priceDate : fundAssetDOGroup.keySet()){
+            List<EmailFundAssetDO> doList = fundAssetDOGroup.get(priceDate);
+            dataList.add(doList.get(0));
+        }
         if(fundAssetDOList.size() > 0){
             //修改采集库的数据
             for(EmailFundAssetDO fundNavDO : fundAssetDOList){
                 fundNavDO.setFundId(targetFundId);
                 fundNavDO.setExceptionStatus(1);
                 fundNavDO.setIsvalid(1);
+                fundNavDO.setIsStored(1);
                 fundNavDO.setUpdateTime(new Date());
+                fundNavDO.setCreateTime(new Date());
             }
             emailFundAssetMapper.batchUpdate(fundAssetDOList);
             //净值入库
-            List<AssetDO> assetDOList = fundAssetDOList.stream().filter(e -> StrUtil.isNotBlank(e.getFundId()))
+            List<AssetDO> assetDOList = dataList.stream().filter(e -> StrUtil.isNotBlank(e.getFundId()))
                     .map(e -> BeanUtil.copyProperties(e, AssetDO.class)).collect(Collectors.toList());
             emailParseService.saveAssetDo(assetDOList);
         }

+ 11 - 1
service-manage/src/main/java/com/simuwang/manage/service/impl/EmailFundNavServiceImpl.java

@@ -12,8 +12,10 @@ import com.simuwang.manage.service.EmailFundNavService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -34,16 +36,24 @@ public class EmailFundNavServiceImpl implements EmailFundNavService {
     @Override
     public void reparseFileNav(String sourceFundName, String targetFundId) {
         List<EmailFundNavDO> fundNavDOList = emailFundNavMapper.selectNotMappingNav(sourceFundName);
+        Map<String,List<EmailFundNavDO>> fundNavDOGroup = fundNavDOList.stream().collect(Collectors.groupingBy(e -> DateUtils.format(e.getPriceDate(),DateUtils.YYYY_MM_DD)));
+        List<EmailFundNavDO> dataList = new ArrayList<>();
+        //去重
+        for(String priceDate : fundNavDOGroup.keySet()){
+            List<EmailFundNavDO> doList = fundNavDOGroup.get(priceDate);
+            dataList.add(doList.get(0));
+        }
         if(fundNavDOList.size() > 0){
             //修改采集库的数据
             for(EmailFundNavDO fundNavDO : fundNavDOList){
                 fundNavDO.setFundId(targetFundId);
                 fundNavDO.setExceptionStatus(1);
+                fundNavDO.setIsStored(1);
                 fundNavDO.setUpdateTime(new Date());
             }
             emailFundNavMapper.batchUpdate(fundNavDOList);
             //净值入库
-            List<NavDO> navDOList = fundNavDOList.stream().filter(e -> StrUtil.isNotBlank(e.getFundId()))
+            List<NavDO> navDOList = dataList.stream().filter(e -> StrUtil.isNotBlank(e.getFundId()))
                     .map(e -> BeanUtil.copyProperties(e, NavDO.class)).collect(Collectors.toList());
             navDOList.forEach(e -> e.setUpdateTime(DateUtils.getNowDate()));
             emailParseService.saveNavDo(navDOList);

+ 9 - 1
service-manage/src/main/java/com/simuwang/manage/service/impl/FundNavAssetServiceImpl.java

@@ -22,13 +22,16 @@ import com.simuwang.base.pojo.vo.*;
 import com.simuwang.manage.service.FundNavAssetService;
 import com.smppw.common.pojo.ResultVo;
 import com.smppw.common.pojo.enums.status.ResultCode;
+import org.apache.commons.io.FileUtils;
 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.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.File;
+import java.io.InputStream;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -55,6 +58,9 @@ public class FundNavAssetServiceImpl implements FundNavAssetService {
 
     @Autowired
     private FundInfoMapper fundInfoMapper;
+
+    @Value("${email.file.path}")
+    private String path;
     private static final Logger logger = LoggerFactory.getLogger(FundNavAssetServiceImpl.class);
     @Override
     public MybatisPage<FundNavAssetVO> searchNavAssetList(FundNavAssetPageQuery fundNavAssetPageQuery) {
@@ -128,7 +134,9 @@ public class FundNavAssetServiceImpl implements FundNavAssetService {
         ResultVo vo = new ResultVo(ResultCode.SUCCESS);
         File file = null;
         try{
-            file = excelFile.getResource().getFile();
+            InputStream inputStream = excelFile.getInputStream();
+            file = new File(path+"/upload/"+ System.currentTimeMillis()+"/"+excelFile.getOriginalFilename());
+            FileUtils.copyInputStreamToFile(inputStream,file);
             List<NavAssetExcelData> list = parseDistributionFile(file);
             vo.setData(parseResult(list));
         }catch (Exception e){

+ 3 - 0
service-manage/src/main/java/com/simuwang/manage/task/ParseSchedulerTask.java

@@ -1,10 +1,13 @@
 package com.simuwang.manage.task;
 
 import ch.qos.logback.core.util.StringUtil;
+import cn.hutool.crypto.asymmetric.KeyType;
+import cn.hutool.crypto.asymmetric.RSA;
 import com.alibaba.fastjson2.JSON;
 import com.simuwang.base.common.enums.EmailCron;
 import com.simuwang.base.common.util.DateUtils;
 import com.simuwang.base.common.util.QuartzUtils;
+import com.simuwang.base.config.DaqProperties;
 import com.simuwang.base.pojo.dos.MailboxInfoDO;
 import com.simuwang.base.pojo.dto.MailboxInfoDTO;
 import com.simuwang.daq.service.EmailParseApiService;