浏览代码

feat:邮件解析-调整估值表数据存储逻辑

mozuwen 7 月之前
父节点
当前提交
dddf1daf02

+ 5 - 0
service-base/src/main/java/com/simuwang/base/pojo/dos/FundPositionDetailDO.java

@@ -17,6 +17,11 @@ public class FundPositionDetailDO {
     @TableId(value = "id")
     @TableId(value = "id")
     private Integer id;
     private Integer id;
     /**
     /**
+     * 估值表id(valuation_table.id)
+     */
+    @TableField(value = "valuation_id")
+    private Integer valuationId;
+    /**
      * 基金ID
      * 基金ID
      */
      */
     @TableField(value = "fund_id")
     @TableField(value = "fund_id")

+ 5 - 0
service-base/src/main/java/com/simuwang/base/pojo/dos/ValuationTableDO.java

@@ -17,6 +17,11 @@ public class ValuationTableDO {
     @TableId(value = "id")
     @TableId(value = "id")
     private Integer id;
     private Integer id;
     /**
     /**
+     * 文件id
+     */
+    @TableField(value = "file_id")
+    private Integer fileId;
+    /**
      * 基金id
      * 基金id
      */
      */
     @TableField(value = "fund_id")
     @TableField(value = "fund_id")

+ 16 - 0
service-base/src/main/java/com/simuwang/base/pojo/dto/EmailFundNavDTO.java

@@ -1,5 +1,8 @@
 package com.simuwang.base.pojo.dto;
 package com.simuwang.base.pojo.dto;
 
 
+import com.simuwang.base.pojo.dos.FundPositionDetailDO;
+import com.simuwang.base.pojo.dos.ValuationTableDO;
+import com.simuwang.base.pojo.valuation.CmValuationTableAttribute;
 import lombok.Data;
 import lombok.Data;
 
 
 import java.util.List;
 import java.util.List;
@@ -52,6 +55,19 @@ public class EmailFundNavDTO {
      */
      */
     private Integer parseStatus;
     private Integer parseStatus;
 
 
+    /**
+     * 估值表信息
+     */
+    private ValuationTableDO valuationTableDO;
+    /**
+     * 估值表明细信息
+     */
+    private List<FundPositionDetailDO> fundPositionDetailDOList;
+    /**
+     * 估值表原始信息
+     */
+    private List<CmValuationTableAttribute> valuationTableAttributeList;
+
     @Override
     @Override
     public boolean equals(Object o) {
     public boolean equals(Object o) {
         if (this == o) {
         if (this == o) {

+ 39 - 0
service-base/src/main/java/com/simuwang/base/pojo/valuation/AssetsValuationResult.java

@@ -1,5 +1,8 @@
 package com.simuwang.base.pojo.valuation;
 package com.simuwang.base.pojo.valuation;
 
 
+import com.simuwang.base.pojo.dos.FundPositionDetailDO;
+import com.simuwang.base.pojo.dos.ValuationTableDO;
+
 import java.util.List;
 import java.util.List;
 
 
 public class AssetsValuationResult {
 public class AssetsValuationResult {
@@ -88,6 +91,42 @@ public class AssetsValuationResult {
 		 */
 		 */
 		private String assetShare;
 		private String assetShare;
 
 
+		private ValuationTableDO valuationTableDO;
+
+		/**
+		 * 估值表明细信息
+		 */
+		private List<FundPositionDetailDO> fundPositionDetailDOList;
+
+		/**
+		 * 估值表原始信息
+		 */
+		private List<CmValuationTableAttribute> valuationTableAttributeList;
+
+		public ValuationTableDO getValuationTableDO() {
+			return valuationTableDO;
+		}
+
+		public void setValuationTableDO(ValuationTableDO valuationTableDO) {
+			this.valuationTableDO = valuationTableDO;
+		}
+
+		public List<FundPositionDetailDO> getFundPositionDetailDOList() {
+			return fundPositionDetailDOList;
+		}
+
+		public void setFundPositionDetailDOList(List<FundPositionDetailDO> fundPositionDetailDOList) {
+			this.fundPositionDetailDOList = fundPositionDetailDOList;
+		}
+
+		public List<CmValuationTableAttribute> getValuationTableAttributeList() {
+			return valuationTableAttributeList;
+		}
+
+		public void setValuationTableAttributeList(List<CmValuationTableAttribute> valuationTableAttributeList) {
+			this.valuationTableAttributeList = valuationTableAttributeList;
+		}
+
 		public Integer getValuationId() {
 		public Integer getValuationId() {
 			return valuationId;
 			return valuationId;
 		}
 		}

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

@@ -3,6 +3,7 @@
 <mapper namespace="com.simuwang.base.mapper.FundPositionDetailMapper">
 <mapper namespace="com.simuwang.base.mapper.FundPositionDetailMapper">
     <resultMap id="BaseResultMap" type="com.simuwang.base.pojo.dos.FundPositionDetailDO">
     <resultMap id="BaseResultMap" type="com.simuwang.base.pojo.dos.FundPositionDetailDO">
         <id column="id" property="id"/>
         <id column="id" property="id"/>
+        <result column="valuation_id" property="valuationId"/>
         <result column="fund_id" property="fundId"/>
         <result column="fund_id" property="fundId"/>
         <result column="valuation_date" property="valuationDate"/>
         <result column="valuation_date" property="valuationDate"/>
         <result column="level" property="level"/>
         <result column="level" property="level"/>

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

@@ -3,6 +3,7 @@
 <mapper namespace="com.simuwang.base.mapper.ValuationTableMapper">
 <mapper namespace="com.simuwang.base.mapper.ValuationTableMapper">
     <resultMap id="BaseResultMap" type="com.simuwang.base.pojo.dos.ValuationTableDO">
     <resultMap id="BaseResultMap" type="com.simuwang.base.pojo.dos.ValuationTableDO">
         <id column="id" property="id"/>
         <id column="id" property="id"/>
+        <result column="file_id" property="fileId"/>
         <result column="fund_id" property="fundId"/>
         <result column="fund_id" property="fundId"/>
         <result column="title" property="title"/>
         <result column="title" property="title"/>
         <result column="valuation_date" property="valuationDate"/>
         <result column="valuation_date" property="valuationDate"/>
@@ -37,14 +38,14 @@
 
 
     <insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.simuwang.base.pojo.dos.ValuationTableDO" useGeneratedKeys="true">
     <insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.simuwang.base.pojo.dos.ValuationTableDO" useGeneratedKeys="true">
         <!--@mbg.generated-->
         <!--@mbg.generated-->
-        insert into PPW_EMAIL.valuation_table (fund_id,
+        insert into PPW_EMAIL.valuation_table (fund_id,file_id,
         title, valuation_date, nav,
         title, valuation_date, nav,
         head_info, tail_info, original_file,
         head_info, tail_info, original_file,
         converted_file, file_url, table_type,
         converted_file, file_url, table_type,
         isvalid, creatorid, createtime,
         isvalid, creatorid, createtime,
         updaterid, updatetime, is_analyzed,
         updaterid, updatetime, is_analyzed,
         total_market_value,net_assets_value,increment,from_email)
         total_market_value,net_assets_value,increment,from_email)
-        values (#{fundId,jdbcType=VARCHAR},
+        values (#{fundId,jdbcType=VARCHAR},#{fileId,jdbcType=INTEGER},
         #{title,jdbcType=VARCHAR}, #{valuationDate,jdbcType=DATE}, #{nav,jdbcType=DECIMAL},
         #{title,jdbcType=VARCHAR}, #{valuationDate,jdbcType=DATE}, #{nav,jdbcType=DECIMAL},
         #{headInfo,jdbcType=VARCHAR}, #{tailInfo,jdbcType=VARCHAR}, #{originalFile,jdbcType=VARCHAR},
         #{headInfo,jdbcType=VARCHAR}, #{tailInfo,jdbcType=VARCHAR}, #{originalFile,jdbcType=VARCHAR},
         #{convertedFile,jdbcType=VARCHAR}, #{fileUrl,jdbcType=VARCHAR}, #{tableType,jdbcType=TINYINT},
         #{convertedFile,jdbcType=VARCHAR}, #{fileUrl,jdbcType=VARCHAR}, #{tableType,jdbcType=TINYINT},

+ 146 - 7
service-daq/src/main/java/com/simuwang/daq/service/EmailParseService.java

@@ -2,6 +2,7 @@ package com.simuwang.daq.service;
 
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.exceptions.ExceptionUtil;
 import cn.hutool.core.exceptions.ExceptionUtil;
@@ -9,10 +10,7 @@ import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.http.HttpUtil;
 import cn.hutool.http.HttpUtil;
 import cn.hutool.json.JSONUtil;
 import cn.hutool.json.JSONUtil;
-import com.simuwang.base.common.conts.DateConst;
-import com.simuwang.base.common.conts.EmailParseStatusConst;
-import com.simuwang.base.common.conts.EmailTypeConst;
-import com.simuwang.base.common.conts.NavParseStatusConst;
+import com.simuwang.base.common.conts.*;
 import com.simuwang.base.common.util.EmailUtil;
 import com.simuwang.base.common.util.EmailUtil;
 import com.simuwang.base.common.util.FileUtil;
 import com.simuwang.base.common.util.FileUtil;
 import com.simuwang.base.config.DaqProperties;
 import com.simuwang.base.config.DaqProperties;
@@ -24,6 +22,7 @@ import com.simuwang.base.pojo.dto.EmailFundNavDTO;
 import com.simuwang.base.pojo.dto.MailboxInfoDTO;
 import com.simuwang.base.pojo.dto.MailboxInfoDTO;
 import com.simuwang.base.pojo.dto.report.PythonResult;
 import com.simuwang.base.pojo.dto.report.PythonResult;
 import com.simuwang.base.pojo.dto.report.ReportData;
 import com.simuwang.base.pojo.dto.report.ReportData;
+import com.simuwang.base.pojo.valuation.CmValuationTableAttribute;
 import com.simuwang.daq.components.PythonReportConverter;
 import com.simuwang.daq.components.PythonReportConverter;
 import com.simuwang.daq.components.writer.ReportWriterFactory;
 import com.simuwang.daq.components.writer.ReportWriterFactory;
 import jakarta.mail.*;
 import jakarta.mail.*;
@@ -68,7 +67,9 @@ public class EmailParseService {
     private final NavMapper navMapper;
     private final NavMapper navMapper;
     private final FundService fundService;
     private final FundService fundService;
     private final FundAliasMapper fundAliasMapper;
     private final FundAliasMapper fundAliasMapper;
-
+    private final ValuationTableMapper valuationTableMapper;
+    private final ValuationTableAttributeMapper valuationTableAttributeMapper;
+    private final FundPositionDetailMapper fundPositionDetailMapper;
 
 
     @Value("${email.file.path}")
     @Value("${email.file.path}")
     private String path;
     private String path;
@@ -77,12 +78,16 @@ public class EmailParseService {
     @Autowired
     @Autowired
     private ReportWriterFactory reportWriterFactory;
     private ReportWriterFactory reportWriterFactory;
 
 
+    public static final int stepSize = 10000;
+
     public EmailParseService(EmailTypeRuleMapper emailTypeRuleMapper, EmailRuleConfig emailRuleConfig,
     public EmailParseService(EmailTypeRuleMapper emailTypeRuleMapper, EmailRuleConfig emailRuleConfig,
                              EmailFieldMappingMapper emailFieldMapper, EmailParserFactory emailParserFactory,
                              EmailFieldMappingMapper emailFieldMapper, EmailParserFactory emailParserFactory,
                              EmailParseInfoMapper emailParseInfoMapper, EmailFileInfoMapper emailFileInfoMapper,
                              EmailParseInfoMapper emailParseInfoMapper, EmailFileInfoMapper emailFileInfoMapper,
                              EmailFundNavMapper emailFundNavMapper, EmailFundAssetMapper emailFundAssetMapper,
                              EmailFundNavMapper emailFundNavMapper, EmailFundAssetMapper emailFundAssetMapper,
                              AssetMapper assetMapper, NavMapper navMapper, FundService fundService,
                              AssetMapper assetMapper, NavMapper navMapper, FundService fundService,
-                             FundAliasMapper fundAliasMapper, DaqProperties properties) {
+                             FundAliasMapper fundAliasMapper, DaqProperties properties,
+                             ValuationTableMapper valuationTableMapper, ValuationTableAttributeMapper valuationTableAttributeMapper,
+                             FundPositionDetailMapper fundPositionDetailMapper) {
         this.emailTypeRuleMapper = emailTypeRuleMapper;
         this.emailTypeRuleMapper = emailTypeRuleMapper;
         this.emailRuleConfig = emailRuleConfig;
         this.emailRuleConfig = emailRuleConfig;
         this.emailFieldMapper = emailFieldMapper;
         this.emailFieldMapper = emailFieldMapper;
@@ -97,6 +102,9 @@ public class EmailParseService {
         this.fundAliasMapper = fundAliasMapper;
         this.fundAliasMapper = fundAliasMapper;
 
 
         this.pyBaseUrl = properties.getPyBaseUrl();
         this.pyBaseUrl = properties.getPyBaseUrl();
+        this.valuationTableMapper = valuationTableMapper;
+        this.valuationTableAttributeMapper = valuationTableAttributeMapper;
+        this.fundPositionDetailMapper = fundPositionDetailMapper;
     }
     }
 
 
     /**
     /**
@@ -188,6 +196,7 @@ public class EmailParseService {
             }
             }
             // 保存净值表和规模表
             // 保存净值表和规模表
             saveNavAndAssetNet(fileId, fundNavDTOList, parseDate);
             saveNavAndAssetNet(fileId, fundNavDTOList, parseDate);
+            saveValuationInfo(fileId, fundNavDTOList);
         }
         }
 
 
         // 更新邮件解析结果 -> 当【净值日期】和【备案编码/基金名称】能正常解读,即识别为【成功】
         // 更新邮件解析结果 -> 当【净值日期】和【备案编码/基金名称】能正常解读,即识别为【成功】
@@ -201,6 +210,136 @@ public class EmailParseService {
         emailParseInfoMapper.updateParseStatus(emailId, emailParseStatus);
         emailParseInfoMapper.updateParseStatus(emailId, emailParseStatus);
     }
     }
 
 
+    private void saveValuationInfo(Integer fileId, List<EmailFundNavDTO> fundNavDTOList) {
+        if (CollUtil.isEmpty(fundNavDTOList)) {
+            return;
+        }
+        for (EmailFundNavDTO fundNavDTO : fundNavDTOList) {
+            ValuationTableDO valuationTableDO = fundNavDTO.getValuationTableDO();
+            if (valuationTableDO == null) {
+                continue;
+            }
+            List<String> fundIdList = fundNavDTO.getFundIdList();
+            valuationTableDO.setFileId(fileId);
+
+            List<FundPositionDetailDO> fundPositionDetailDOList = fundNavDTO.getFundPositionDetailDOList();
+            List<CmValuationTableAttribute> valuationTableAttributeList = fundNavDTO.getValuationTableAttributeList();
+            if (CollUtil.isEmpty(fundIdList)) {
+                int valuationId = valuationTableMapper.insert(valuationTableDO);
+                saveValuationTableAttribute(valuationId, valuationTableAttributeList);
+                fundPositionDetailDOList.forEach(e -> e.setValuationId(valuationId));
+                saveFundPositionDetail(fundPositionDetailDOList, null, fundNavDTO.getPriceDate());
+                continue;
+            }
+            for (String fundId : fundIdList) {
+                valuationTableDO.setFundId(fundId);
+                int valuationId = valuationTableMapper.insert(valuationTableDO);
+                fundPositionDetailDOList.forEach(e -> {
+                    e.setFundId(fundId);
+                    e.setValuationId(valuationId);
+                });
+                saveValuationTableAttribute(valuationId, valuationTableAttributeList);
+                saveFundPositionDetail(fundPositionDetailDOList, null, fundNavDTO.getPriceDate());
+            }
+        }
+    }
+
+    public void saveFundPositionDetail(List<FundPositionDetailDO> fundPositionDetails, String fundId, String valuationDate) {
+        int subBegin = 0;
+        int subEnd = stepSize;
+        int insertNum = 0;
+        int hasStock = 0;
+        int hasBond = 0;
+        int hasFuture = 0;
+        if (CollectionUtil.isNotEmpty(fundPositionDetails)) {
+            //插入持仓数据 cm_fund_position_detail(记录数较多,得分批)
+            // 先删除原先的数据 然后写入数据
+            fundPositionDetailMapper.deleteUnUsed(fundId, valuationDate);
+            // 将最终结果写入 cm_fund_position_detail
+            while (subBegin < fundPositionDetails.size()) {
+                List<FundPositionDetailDO> segment = fundPositionDetails.subList(subBegin, Math.min(subEnd, fundPositionDetails.size()));
+                for (FundPositionDetailDO fundPositionDetail : segment) {
+                    //实收信托、实收资本对应的编码为107
+                    if (StrUtil.isNotBlank(fundPositionDetail.getSecuritiesName()) && "实收信托".equals(fundPositionDetail.getSecuritiesName().trim())) {
+                        fundPositionDetail.setSubjectCode("107");
+                        fundPositionDetail.setSecuritiesCode("107");
+                    }
+                    //设置创建者id,在拿取最近修改人时有用
+                    fundPositionDetail.setCreatorId(0);
+                    if (fundPositionDetail.getLevel() != null && fundPositionDetail.getLevel() >= 4) {
+                        Integer secType = fundPositionDetail.getSecType();
+                        Integer subType = fundPositionDetail.getSubType();
+                        if (secType != null && subType != null) {
+                            if (secType == HoldingType.Stock.getId() && subType == HoldingType.Stock.getId()) {
+                                hasStock = 1;
+                            }
+                            // 正逆回购不属于债券
+                            String subjectCode = fundPositionDetail.getSubjectCode();
+                            String[] SALE_CODES = {"2202", "1202"};
+                            if (secType == HoldingType.Bond.getId() && !StrUtil.containsAny(subjectCode, SALE_CODES)) {
+                                hasBond = 1;
+                            }
+                            if (secType == HoldingType.Future.getId() || secType == HoldingType.Option.getId()) {
+                                hasFuture = 1;
+                            }
+                        }
+                    }
+                }
+                insertNum += fundPositionDetailMapper.insertMulti(segment);
+                subBegin = subEnd;
+                subEnd += stepSize;
+            }
+        }
+        // 更新 cm_user_valuation_table
+        if (insertNum > 0) {
+            valuationTableMapper.updateUpdateAnalyzed(fundId, valuationDate, hasStock, hasBond, hasFuture);
+        }
+    }
+
+    private void saveValuationTableAttribute(Integer valuationId, List<CmValuationTableAttribute> valuationTableAttributes) {
+        if (valuationId == null || CollUtil.isEmpty(valuationTableAttributes)) {
+            return;
+        }
+        List<ValuationTableAttributeDO> valuationTableAttributeDOList = buildValuationTableAttributeDO(valuationId, valuationTableAttributes);
+        valuationTableAttributeMapper.deleteByValuationId(valuationId);
+        if (CollUtil.isNotEmpty(valuationTableAttributeDOList)) {
+            valuationTableAttributeMapper.batchInsert(valuationTableAttributeDOList);
+        }
+    }
+
+    private List<ValuationTableAttributeDO> buildValuationTableAttributeDO(Integer valuationId, List<CmValuationTableAttribute> valuationTableAttributes) {
+        if (CollUtil.isEmpty(valuationTableAttributes)) {
+            return CollUtil.newArrayList();
+        }
+        return valuationTableAttributes.stream().map(e -> {
+            ValuationTableAttributeDO tableAttributeDO = new ValuationTableAttributeDO();
+            tableAttributeDO.setValuationId(valuationId);
+            tableAttributeDO.setSubjectCode(e.getOriginalSubjectCode());
+            tableAttributeDO.setSubjectName(e.getSubjectName());
+            tableAttributeDO.setCurrency(e.getCurrency());
+            tableAttributeDO.setExchangeRate(e.getExchangeRate());
+            tableAttributeDO.setSecuritiesAmount(e.getSecuritiesAmount());
+            tableAttributeDO.setUnitCost(e.getUnitCost());
+            tableAttributeDO.setOriCurrencyCost(e.getOCurrencyCost());
+            tableAttributeDO.setNetCost(e.getNetCost());
+            tableAttributeDO.setNetCostRatio(e.getNetCostRatio());
+            tableAttributeDO.setMarketPrice(e.getMarketPrice());
+            tableAttributeDO.setOriCurrencyMarketValue(e.getOCurrencyMarketValue());
+            tableAttributeDO.setMarketValue(e.getMarketValue());
+            tableAttributeDO.setMarketValueRatio(e.getMarketValueRatio());
+            tableAttributeDO.setOriCurrencyIncrement(e.getOCurrencyMarketValue());
+            tableAttributeDO.setIncrement(e.getIncrement());
+            tableAttributeDO.setHaltInfo(e.getHaltInfo());
+            tableAttributeDO.setRightsInterestsInfo(e.getRightsInterestsInfo());
+            tableAttributeDO.setIsvalid(1);
+            tableAttributeDO.setCreatorId(0);
+            tableAttributeDO.setUpdaterId(0);
+            tableAttributeDO.setCreateTime(new Date());
+            tableAttributeDO.setUpdateTime(new Date());
+            return tableAttributeDO;
+        }).collect(Collectors.toList());
+    }
+
     private ReportData requestPyAndResult(int fileId, EmailContentInfoDTO emailContentInfoDTO) {
     private ReportData requestPyAndResult(int fileId, EmailContentInfoDTO emailContentInfoDTO) {
         String fileName = emailContentInfoDTO.getFileName();
         String fileName = emailContentInfoDTO.getFileName();
         Integer emailType = emailContentInfoDTO.getEmailType();
         Integer emailType = emailContentInfoDTO.getEmailType();
@@ -241,7 +380,7 @@ public class EmailParseService {
                 PythonResult<?> result = PythonReportConverter.convert(JSONUtil.parseObj(body), type);
                 PythonResult<?> result = PythonReportConverter.convert(JSONUtil.parseObj(body), type);
                 reportData = result.getData();
                 reportData = result.getData();
                 if (log.isInfoEnabled()) {
                 if (log.isInfoEnabled()) {
-                    log.info("报告{}结果为:\n{}",params, reportData);
+                    log.info("报告{}结果为:\n{}", params, reportData);
                 }
                 }
             } catch (Exception e) {
             } catch (Exception e) {
                 log.error("请求python的报告解析接口报错\n{}", ExceptionUtil.stacktraceToString(e));
                 log.error("请求python的报告解析接口报错\n{}", ExceptionUtil.stacktraceToString(e));

+ 3 - 0
service-daq/src/main/java/com/simuwang/daq/service/ValuationEmailParser.java

@@ -151,6 +151,9 @@ public class ValuationEmailParser extends AbstractEmailParser {
             fundNavDTO.setAssetNet(record.getAssetNet());
             fundNavDTO.setAssetNet(record.getAssetNet());
             fundNavDTO.setAssetShare(record.getAssetShare());
             fundNavDTO.setAssetShare(record.getAssetShare());
             fundNavDTO.setFundIdList(StrUtil.isNotBlank(record.getFundId()) ? ListUtil.toList(record.getFundId()) : null);
             fundNavDTO.setFundIdList(StrUtil.isNotBlank(record.getFundId()) ? ListUtil.toList(record.getFundId()) : null);
+            fundNavDTO.setValuationTableDO(record.getValuationTableDO());
+            fundNavDTO.setValuationTableAttributeList(record.getValuationTableAttributeList());
+            fundNavDTO.setFundPositionDetailDOList(record.getFundPositionDetailDOList());
             emailFundNavDTOList.add(fundNavDTO);
             emailFundNavDTOList.add(fundNavDTO);
         }
         }
         return emailFundNavDTOList;
         return emailFundNavDTOList;

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

@@ -6,7 +6,6 @@ import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.StopWatch;
 import cn.hutool.core.date.StopWatch;
 import cn.hutool.core.exceptions.ExceptionUtil;
 import cn.hutool.core.exceptions.ExceptionUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.StrUtil;
-import com.simuwang.base.common.conts.HoldingType;
 import com.simuwang.base.common.util.ValuationBusinessUtils;
 import com.simuwang.base.common.util.ValuationBusinessUtils;
 import com.simuwang.base.common.util.ValuationDataUtils;
 import com.simuwang.base.common.util.ValuationDataUtils;
 import com.simuwang.base.common.util.ValuationTableParseUtil;
 import com.simuwang.base.common.util.ValuationTableParseUtil;
@@ -32,27 +31,16 @@ public class ValuationParseService {
 
 
     private static final Logger log = LoggerFactory.getLogger(ValuationParseService.class);
     private static final Logger log = LoggerFactory.getLogger(ValuationParseService.class);
 
 
-    public static final int stepSize = 10000;
-
     private final ValuationMarketCodeMapper valuationMarketCodeMapper;
     private final ValuationMarketCodeMapper valuationMarketCodeMapper;
-    private final FundPositionDetailMapper fundPositionDetailMapper;
-    private final ValuationTableMapper valuationTableMapper;
-    private final FundService fundService;
     private final PdfValuationRecordMapper pdfValuationRecordMapper;
     private final PdfValuationRecordMapper pdfValuationRecordMapper;
     private final ThreadPoolTaskExecutor executor;
     private final ThreadPoolTaskExecutor executor;
-    private final ValuationTableAttributeMapper valuationTableAttributeMapper;
 
 
-    public ValuationParseService(ValuationMarketCodeMapper valuationMarketCodeMapper, FundPositionDetailMapper fundPositionDetailMapper,
-                                 ValuationTableMapper valuationTableMapper, FundService fundService,
-                                 PdfValuationRecordMapper pdfValuationRecordMapper, @Qualifier("valuationExecutor") ThreadPoolTaskExecutor executor,
-                                 ValuationTableAttributeMapper valuationTableAttributeMapper) {
+
+    public ValuationParseService(ValuationMarketCodeMapper valuationMarketCodeMapper, PdfValuationRecordMapper pdfValuationRecordMapper,
+                                 @Qualifier("valuationExecutor") ThreadPoolTaskExecutor executor) {
         this.valuationMarketCodeMapper = valuationMarketCodeMapper;
         this.valuationMarketCodeMapper = valuationMarketCodeMapper;
-        this.fundPositionDetailMapper = fundPositionDetailMapper;
-        this.valuationTableMapper = valuationTableMapper;
-        this.fundService = fundService;
         this.pdfValuationRecordMapper = pdfValuationRecordMapper;
         this.pdfValuationRecordMapper = pdfValuationRecordMapper;
         this.executor = executor;
         this.executor = executor;
-        this.valuationTableAttributeMapper = valuationTableAttributeMapper;
     }
     }
 
 
     public List<AssetsValuationResult.Record> parseValuationExcel(List<ValuationNeedParseParam> valuationNeedParseParams) {
     public List<AssetsValuationResult.Record> parseValuationExcel(List<ValuationNeedParseParam> valuationNeedParseParams) {
@@ -84,105 +72,44 @@ public class ValuationParseService {
                         String headInfo = excelInfo.getExtInfo().getHeadInfo();
                         String headInfo = excelInfo.getExtInfo().getHeadInfo();
                         if (StringUtils.isNotEmpty(headInfo)) {
                         if (StringUtils.isNotEmpty(headInfo)) {
                             AssetsValuationDetails details = excelInfo.getExtInfo();
                             AssetsValuationDetails details = excelInfo.getExtInfo();
-
                             parseValuationInfo = parseRegisterNumAndFundName(headInfo);
                             parseValuationInfo = parseRegisterNumAndFundName(headInfo);
                             record.setParseValuationInfo(parseValuationInfo);
                             record.setParseValuationInfo(parseValuationInfo);
                             log.info("表格:{},从表格中解析到的基金名称和备案编码:{}", valuationNeedParseParam.getOriginFileName(), parseValuationInfo.toString());
                             log.info("表格:{},从表格中解析到的基金名称和备案编码:{}", valuationNeedParseParam.getOriginFileName(), parseValuationInfo.toString());
 
 
-                            List<FundInfoDO> fundInfoDOList = fundService.getFundInfoByNamesAndCode(parseValuationInfo.getFundName(), parseValuationInfo.getRegisterNumber());
-                            log.info("表格:{}, 匹配上的基金:{}", valuationNeedParseParam.getOriginFileName(), fundInfoDOList);
-                            if (CollUtil.isEmpty(fundInfoDOList)) {
-                                // 未匹配基金的情况 -> 不保存估值表信息
-                                record.setNav(String.valueOf(details.getNav()));
-                                record.setCumulativeNavWithdrawal(String.valueOf(details.getCumulativeNav()));
-                                record.setExcelName(valuationNeedParseParam.getOriginFileName());
-                                record.setDate(details.getValuationDate());
-                                record.setExcelName(valuationNeedParseParam.getOriginFileName());
-                                record.setMsg("未匹配基金");
-                                record.setDate(details.getValuationDate());
-                                record.setSuccess(0);
-                                BigDecimal assetNet = details.getNetAssetsValue() != null ? BigDecimal.valueOf(details.getNetAssetsValue()) : 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);
-                            } else {
-                                for (FundInfoDO fundInfoDO : fundInfoDOList) {
-                                    String fundId = fundInfoDO.getFundId();
-                                    AssetsValuationResult.Record singleFundRecord = new AssetsValuationResult.Record();
-                                    singleFundRecord.setExcelName(valuationNeedParseParam.getOriginFileName());
-                                    singleFundRecord.setDate(details.getValuationDate());
-                                    singleFundRecord.setSuccess(1);
-                                    singleFundRecord.setFundId(fundId);
-                                    singleFundRecord.setCumulativeNavWithdrawal(String.valueOf(details.getCumulativeNav()));
-                                    singleFundRecord.setNav(String.valueOf(details.getNav()));
-                                    singleFundRecord.setParseValuationInfo(parseValuationInfo);
-                                    String valuationDate = details.getValuationDate();
-                                    List<AssetsValuationInfo> data = excelInfo.getData();
-                                    if (CollUtil.isNotEmpty(data)) {
-                                        ValuationTableDO tableInfo = new ValuationTableDO();
-                                        Integer valuationId = trans2UserValuationDoAndWrite(details, fundId, tableInfo, valuationNeedParseParam);
-                                        singleFundRecord.setValuationId(valuationId);
-                                        Future<ValuationResult> future = executor.submit(() -> {
-                                            ValuationResult valuationResult = new ValuationResult();
-                                            valuationResult.setFundId(fundId);
-                                            List<CmValuationTableAttribute> valuationTableAttributes = ValuationTableParseUtil.getAttrList(data);
-                                            List<FundPositionDetailDO> fundPositionDetailDOList = ValuationTableParseUtil.parseDataNew(valuationTableAttributes, tableInfo, marketCodeList);
-                                            if (CollectionUtil.isNotEmpty(fundPositionDetailDOList)) {
-                                                fundPositionDetailDOList.stream().filter(p -> "202".equals(p.getSecuritiesCode())).findFirst()
-                                                        .ifPresent(p -> valuationResult.setCumulativeNavWithdrawal(p.getMarketValue() != null ? String.valueOf(p.getMarketValue()) : null));
-                                            }
-                                            valuationResult.setValuationTableAttributes(valuationTableAttributes);
-                                            valuationResult.setList(fundPositionDetailDOList);
-                                            valuationResult.setRecord(singleFundRecord);
-                                            valuationResult.setValuationDate(valuationDate);
-                                            return valuationResult;
-                                        });
-                                        futureList.add(future);
-                                    }
-                                }
-                            }
-                        }
-                    } else {
-                        String fundId = valuationNeedParseParam.getFundId();
-                        AssetsValuationDetails details = excelInfo.getExtInfo();
-                        record.setNav(String.valueOf(details.getNav()));
-                        record.setCumulativeNavWithdrawal(String.valueOf(details.getCumulativeNav()));
-                        record.setExcelName(valuationNeedParseParam.getOriginFileName());
-                        record.setDate(details.getValuationDate());
-                        record.setSuccess(1);
-                        record.setFundId(fundId);
-                        String valuationDate = details.getValuationDate();
-                        List<AssetsValuationInfo> data = excelInfo.getData();
-                        if (CollectionUtil.isNotEmpty(data)) {
-                            ValuationTableDO tableInfo = new ValuationTableDO();
-                            Integer valuationId = trans2UserValuationDoAndWrite(details, fundId, tableInfo, valuationNeedParseParam);
-                            record.setValuationId(valuationId);
-                            Future<ValuationResult> future = executor.submit(() -> {
-                                long startTime = System.currentTimeMillis();
-                                ValuationResult valuationResult = new ValuationResult();
-                                valuationResult.setFundId(fundId);
-                                valuationResult.setUserId(0);
-                                List<FundPositionDetailDO> fundPositionDetailDOList = CollUtil.newArrayList();
-                                try {
+                            record.setNav(String.valueOf(details.getNav()));
+                            record.setCumulativeNavWithdrawal(String.valueOf(details.getCumulativeNav()));
+                            record.setExcelName(valuationNeedParseParam.getOriginFileName());
+                            record.setDate(details.getValuationDate());
+                            record.setExcelName(valuationNeedParseParam.getOriginFileName());
+                            record.setDate(details.getValuationDate());
+                            record.setSuccess(1);
+
+                            String valuationDate = details.getValuationDate();
+                            List<AssetsValuationInfo> data = excelInfo.getData();
+                            if (CollUtil.isNotEmpty(data)) {
+                                ValuationTableDO valuationTableDO = buildValuationTableDO(details, valuationNeedParseParam);
+                                record.setValuationTableDO(valuationTableDO);
+
+                                Future<ValuationResult> future = executor.submit(() -> {
+                                    ValuationResult valuationResult = new ValuationResult();
                                     List<CmValuationTableAttribute> valuationTableAttributes = ValuationTableParseUtil.getAttrList(data);
                                     List<CmValuationTableAttribute> valuationTableAttributes = ValuationTableParseUtil.getAttrList(data);
+                                    record.setValuationTableAttributeList(valuationTableAttributes);
+
+                                    List<FundPositionDetailDO> fundPositionDetailDOList = ValuationTableParseUtil.parseDataNew(valuationTableAttributes, valuationTableDO, marketCodeList);
+                                    record.setFundPositionDetailDOList(fundPositionDetailDOList);
+
+                                    if (CollectionUtil.isNotEmpty(fundPositionDetailDOList)) {
+                                        fundPositionDetailDOList.stream().filter(p -> "202".equals(p.getSecuritiesCode())).findFirst()
+                                                .ifPresent(p -> valuationResult.setCumulativeNavWithdrawal(p.getMarketValue() != null ? String.valueOf(p.getMarketValue()) : null));
+                                    }
                                     valuationResult.setValuationTableAttributes(valuationTableAttributes);
                                     valuationResult.setValuationTableAttributes(valuationTableAttributes);
-                                    fundPositionDetailDOList = ValuationTableParseUtil.parseDataNew(valuationTableAttributes, tableInfo, marketCodeList);
-                                } catch (Exception e) {
-                                    log.info("Exception: {}", ExceptionUtil.stacktraceToString(e));
-                                }
-                                if (CollectionUtil.isNotEmpty(fundPositionDetailDOList)) {
-                                    fundPositionDetailDOList.stream().filter(p -> "202".equals(p.getSecuritiesCode())).findFirst()
-                                            .ifPresent(p -> valuationResult.setCumulativeNavWithdrawal(p.getMarketValue() != null ? String.valueOf(p.getMarketValue()) : null));
-                                }
-                                valuationResult.setList(fundPositionDetailDOList);
-                                valuationResult.setRecord(record);
-                                valuationResult.setValuationDate(valuationDate);
-                                long endTime = System.currentTimeMillis();
-                                log.info("end parse -> {},spend time -> {}", record.excelName, (endTime - startTime) + "ms");
-                                return valuationResult;
-                            });
-                            futureList.add(future);
+                                    valuationResult.setList(fundPositionDetailDOList);
+                                    valuationResult.setRecord(record);
+                                    valuationResult.setValuationDate(valuationDate);
+                                    return valuationResult;
+                                });
+                                futureList.add(future);
+                            }
                         }
                         }
                     }
                     }
                 }
                 }
@@ -191,7 +118,6 @@ public class ValuationParseService {
             for (Future<ValuationResult> future : futureList) {
             for (Future<ValuationResult> future : futureList) {
                 try {
                 try {
                     ValuationResult r = future.get(3600, TimeUnit.SECONDS);
                     ValuationResult r = future.get(3600, TimeUnit.SECONDS);
-                    String fundId = r.getFundId();
                     AssetsValuationResult.Record record = r.getRecord();
                     AssetsValuationResult.Record record = r.getRecord();
                     record.setCumulativeNavWithdrawal(record.getCumulativeNavWithdrawal());
                     record.setCumulativeNavWithdrawal(record.getCumulativeNavWithdrawal());
                     // 获取资产净值和资产份额
                     // 获取资产净值和资产份额
@@ -202,72 +128,24 @@ public class ValuationParseService {
                     record.setAssetNet(assetNet != null ? String.valueOf(assetNet) : null);
                     record.setAssetNet(assetNet != null ? String.valueOf(assetNet) : null);
                     record.setAssetShare(assetShare != null ? String.valueOf(assetShare) : null);
                     record.setAssetShare(assetShare != null ? String.valueOf(assetShare) : null);
                     records.add(record);
                     records.add(record);
-                    Integer valuationId = record.getValuationId();
-                    List<CmValuationTableAttribute> valuationTableAttributes = r.getValuationTableAttributes();
-                    // 保存估值表原始信息
-                    saveValuationTableAttribute(valuationId, valuationTableAttributes);
-                    // 保存估值表持仓明细信息
-                    saveFundPositionDetail(r.getList(), fundId, r.getValuationDate());
                 } catch (InterruptedException | ExecutionException | TimeoutException e) {
                 } catch (InterruptedException | ExecutionException | TimeoutException e) {
                     log.info("valuation excel upload future exec exception: {}", e.getMessage(), e);
                     log.info("valuation excel upload future exec exception: {}", e.getMessage(), e);
                 }
                 }
             }
             }
-        } catch (Exception exception) {
+        } catch (
+                Exception exception) {
             log.error("parse valuation excel error ->{}", ExceptionUtil.stacktraceToString(exception));
             log.error("parse valuation excel error ->{}", ExceptionUtil.stacktraceToString(exception));
         } finally {
         } finally {
             stopWatch.start("destruction valuation executor");
             stopWatch.start("destruction valuation executor");
             stopWatch.stop();
             stopWatch.stop();
             log.info("destruction valuation executor cost -> {}", stopWatch.prettyPrint(TimeUnit.MILLISECONDS));
             log.info("destruction valuation executor cost -> {}", stopWatch.prettyPrint(TimeUnit.MILLISECONDS));
         }
         }
+
         //保存PDF估值表记录
         //保存PDF估值表记录
         savePdfValuationRecord(valuationNeedParseParams, records);
         savePdfValuationRecord(valuationNeedParseParams, records);
         return records;
         return records;
     }
     }
 
 
-    private void saveValuationTableAttribute(Integer valuationId, List<CmValuationTableAttribute> valuationTableAttributes) {
-        if (valuationId == null || CollUtil.isEmpty(valuationTableAttributes)) {
-            return;
-        }
-        List<ValuationTableAttributeDO> valuationTableAttributeDOList = buildValuationTableAttributeDO(valuationId, valuationTableAttributes);
-        valuationTableAttributeMapper.deleteByValuationId(valuationId);
-        if (CollUtil.isNotEmpty(valuationTableAttributeDOList)) {
-            valuationTableAttributeMapper.batchInsert(valuationTableAttributeDOList);
-        }
-    }
-
-    private List<ValuationTableAttributeDO> buildValuationTableAttributeDO(Integer valuationId, List<CmValuationTableAttribute> valuationTableAttributes) {
-        if (CollUtil.isEmpty(valuationTableAttributes)) {
-            return CollUtil.newArrayList();
-        }
-        return valuationTableAttributes.stream().map(e -> {
-            ValuationTableAttributeDO tableAttributeDO = new ValuationTableAttributeDO();
-            tableAttributeDO.setValuationId(valuationId);
-            tableAttributeDO.setSubjectCode(e.getOriginalSubjectCode());
-            tableAttributeDO.setSubjectName(e.getSubjectName());
-            tableAttributeDO.setCurrency(e.getCurrency());
-            tableAttributeDO.setExchangeRate(e.getExchangeRate());
-            tableAttributeDO.setSecuritiesAmount(e.getSecuritiesAmount());
-            tableAttributeDO.setUnitCost(e.getUnitCost());
-            tableAttributeDO.setOriCurrencyCost(e.getOCurrencyCost());
-            tableAttributeDO.setNetCost(e.getNetCost());
-            tableAttributeDO.setNetCostRatio(e.getNetCostRatio());
-            tableAttributeDO.setMarketPrice(e.getMarketPrice());
-            tableAttributeDO.setOriCurrencyMarketValue(e.getOCurrencyMarketValue());
-            tableAttributeDO.setMarketValue(e.getMarketValue());
-            tableAttributeDO.setMarketValueRatio(e.getMarketValueRatio());
-            tableAttributeDO.setOriCurrencyIncrement(e.getOCurrencyMarketValue());
-            tableAttributeDO.setIncrement(e.getIncrement());
-            tableAttributeDO.setHaltInfo(e.getHaltInfo());
-            tableAttributeDO.setRightsInterestsInfo(e.getRightsInterestsInfo());
-            tableAttributeDO.setIsvalid(1);
-            tableAttributeDO.setCreatorId(0);
-            tableAttributeDO.setUpdaterId(0);
-            tableAttributeDO.setCreateTime(new Date());
-            tableAttributeDO.setUpdateTime(new Date());
-            return tableAttributeDO;
-        }).collect(Collectors.toList());
-    }
-
     /**
     /**
      * 保存PDF估值表记录
      * 保存PDF估值表记录
      *
      *
@@ -404,61 +282,8 @@ public class ValuationParseService {
         return info;
         return info;
     }
     }
 
 
-    public void saveFundPositionDetail(List<FundPositionDetailDO> fundPositionDetails, String fundId, String valuationDate) {
-        int subBegin = 0;
-        int subEnd = stepSize;
-        int insertNum = 0;
-        int hasStock = 0;
-        int hasBond = 0;
-        int hasFuture = 0;
-        if (CollectionUtil.isNotEmpty(fundPositionDetails)) {
-            //插入持仓数据 cm_fund_position_detail(记录数较多,得分批)
-            // 先删除原先的数据 然后写入数据
-            fundPositionDetailMapper.deleteUnUsed(fundId, valuationDate);
-            // 将最终结果写入 cm_fund_position_detail
-            while (subBegin < fundPositionDetails.size()) {
-                List<FundPositionDetailDO> segment = fundPositionDetails.subList(subBegin, Math.min(subEnd, fundPositionDetails.size()));
-                for (FundPositionDetailDO fundPositionDetail : segment) {
-                    //实收信托、实收资本对应的编码为107
-                    if (StrUtil.isNotBlank(fundPositionDetail.getSecuritiesName()) && "实收信托".equals(fundPositionDetail.getSecuritiesName().trim())) {
-                        fundPositionDetail.setSubjectCode("107");
-                        fundPositionDetail.setSecuritiesCode("107");
-                    }
-                    //设置创建者id,在拿取最近修改人时有用
-                    fundPositionDetail.setCreatorId(0);
-                    if (fundPositionDetail.getLevel() != null && fundPositionDetail.getLevel() >= 4) {
-                        Integer secType = fundPositionDetail.getSecType();
-                        Integer subType = fundPositionDetail.getSubType();
-                        if (secType != null && subType != null) {
-                            if (secType == HoldingType.Stock.getId() && subType == HoldingType.Stock.getId()) {
-                                hasStock = 1;
-                            }
-                            // 正逆回购不属于债券
-                            String subjectCode = fundPositionDetail.getSubjectCode();
-                            String[] SALE_CODES = {"2202", "1202"};
-                            if (secType == HoldingType.Bond.getId() && !StrUtil.containsAny(subjectCode, SALE_CODES)) {
-                                hasBond = 1;
-                            }
-                            if (secType == HoldingType.Future.getId() || secType == HoldingType.Option.getId()) {
-                                hasFuture = 1;
-                            }
-                        }
-                    }
-                }
-                insertNum += fundPositionDetailMapper.insertMulti(segment);
-                subBegin = subEnd;
-                subEnd += stepSize;
-            }
-        }
-        // 更新 cm_user_valuation_table
-        if (insertNum > 0) {
-            valuationTableMapper.updateUpdateAnalyzed(fundId, valuationDate, hasStock, hasBond, hasFuture);
-        }
-    }
-
-    public Integer trans2UserValuationDoAndWrite(AssetsValuationDetails details, String fundId, ValuationTableDO tableInfo, ValuationNeedParseParam valuationNeedParseParam) {
-        valuationTableMapper.unValid(fundId, details.getValuationDate());
-        tableInfo.setFundId(fundId);
+    public ValuationTableDO buildValuationTableDO(AssetsValuationDetails details, ValuationNeedParseParam valuationNeedParseParam) {
+        ValuationTableDO tableInfo = new ValuationTableDO();
         tableInfo.setValuationDate(DateUtil.StringToDate(details.getValuationDate()));
         tableInfo.setValuationDate(DateUtil.StringToDate(details.getValuationDate()));
         tableInfo.setIsAnalyzed(0);
         tableInfo.setIsAnalyzed(0);
         tableInfo.setIsvalid(1);
         tableInfo.setIsvalid(1);
@@ -478,8 +303,7 @@ public class ValuationParseService {
         tableInfo.setFromEmail(valuationNeedParseParam.getFromEmail());
         tableInfo.setFromEmail(valuationNeedParseParam.getFromEmail());
         tableInfo.setOriginalFile(valuationNeedParseParam.getOriginFileName());
         tableInfo.setOriginalFile(valuationNeedParseParam.getOriginFileName());
         tableInfo.setConvertedFile(valuationNeedParseParam.getFile().getName());
         tableInfo.setConvertedFile(valuationNeedParseParam.getFile().getName());
-        valuationTableMapper.insert(tableInfo);
-        return tableInfo.getId();
+        return tableInfo;
     }
     }
 
 
     public AssetsValuationExcelInfo<AssetsValuationInfo> processDataV2(PreAssetsValuationInfo<PreAssetsValuationBase> info) {
     public AssetsValuationExcelInfo<AssetsValuationInfo> processDataV2(PreAssetsValuationInfo<PreAssetsValuationBase> info) {