Преглед на файлове

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")
     private Integer id;
     /**
+     * 估值表id(valuation_table.id)
+     */
+    @TableField(value = "valuation_id")
+    private Integer valuationId;
+    /**
      * 基金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")
     private Integer id;
     /**
+     * 文件id
+     */
+    @TableField(value = "file_id")
+    private Integer fileId;
+    /**
      * 基金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;
 
+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 java.util.List;
@@ -52,6 +55,19 @@ public class EmailFundNavDTO {
      */
     private Integer parseStatus;
 
+    /**
+     * 估值表信息
+     */
+    private ValuationTableDO valuationTableDO;
+    /**
+     * 估值表明细信息
+     */
+    private List<FundPositionDetailDO> fundPositionDetailDOList;
+    /**
+     * 估值表原始信息
+     */
+    private List<CmValuationTableAttribute> valuationTableAttributeList;
+
     @Override
     public boolean equals(Object 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;
 
+import com.simuwang.base.pojo.dos.FundPositionDetailDO;
+import com.simuwang.base.pojo.dos.ValuationTableDO;
+
 import java.util.List;
 
 public class AssetsValuationResult {
@@ -88,6 +91,42 @@ public class AssetsValuationResult {
 		 */
 		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() {
 			return valuationId;
 		}

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

@@ -3,6 +3,7 @@
 <mapper namespace="com.simuwang.base.mapper.FundPositionDetailMapper">
     <resultMap id="BaseResultMap" type="com.simuwang.base.pojo.dos.FundPositionDetailDO">
         <id column="id" property="id"/>
+        <result column="valuation_id" property="valuationId"/>
         <result column="fund_id" property="fundId"/>
         <result column="valuation_date" property="valuationDate"/>
         <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">
     <resultMap id="BaseResultMap" type="com.simuwang.base.pojo.dos.ValuationTableDO">
         <id column="id" property="id"/>
+        <result column="file_id" property="fileId"/>
         <result column="fund_id" property="fundId"/>
         <result column="title" property="title"/>
         <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">
         <!--@mbg.generated-->
-        insert into PPW_EMAIL.valuation_table (fund_id,
+        insert into PPW_EMAIL.valuation_table (fund_id,file_id,
         title, valuation_date, nav,
         head_info, tail_info, original_file,
         converted_file, file_url, table_type,
         isvalid, creatorid, createtime,
         updaterid, updatetime, is_analyzed,
         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},
         #{headInfo,jdbcType=VARCHAR}, #{tailInfo,jdbcType=VARCHAR}, #{originalFile,jdbcType=VARCHAR},
         #{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.collection.CollUtil;
+import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.date.DateUtil;
 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.http.HttpUtil;
 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.FileUtil;
 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.report.PythonResult;
 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.writer.ReportWriterFactory;
 import jakarta.mail.*;
@@ -68,7 +67,9 @@ public class EmailParseService {
     private final NavMapper navMapper;
     private final FundService fundService;
     private final FundAliasMapper fundAliasMapper;
-
+    private final ValuationTableMapper valuationTableMapper;
+    private final ValuationTableAttributeMapper valuationTableAttributeMapper;
+    private final FundPositionDetailMapper fundPositionDetailMapper;
 
     @Value("${email.file.path}")
     private String path;
@@ -77,12 +78,16 @@ public class EmailParseService {
     @Autowired
     private ReportWriterFactory reportWriterFactory;
 
+    public static final int stepSize = 10000;
+
     public EmailParseService(EmailTypeRuleMapper emailTypeRuleMapper, EmailRuleConfig emailRuleConfig,
                              EmailFieldMappingMapper emailFieldMapper, EmailParserFactory emailParserFactory,
                              EmailParseInfoMapper emailParseInfoMapper, EmailFileInfoMapper emailFileInfoMapper,
                              EmailFundNavMapper emailFundNavMapper, EmailFundAssetMapper emailFundAssetMapper,
                              AssetMapper assetMapper, NavMapper navMapper, FundService fundService,
-                             FundAliasMapper fundAliasMapper, DaqProperties properties) {
+                             FundAliasMapper fundAliasMapper, DaqProperties properties,
+                             ValuationTableMapper valuationTableMapper, ValuationTableAttributeMapper valuationTableAttributeMapper,
+                             FundPositionDetailMapper fundPositionDetailMapper) {
         this.emailTypeRuleMapper = emailTypeRuleMapper;
         this.emailRuleConfig = emailRuleConfig;
         this.emailFieldMapper = emailFieldMapper;
@@ -97,6 +102,9 @@ public class EmailParseService {
         this.fundAliasMapper = fundAliasMapper;
 
         this.pyBaseUrl = properties.getPyBaseUrl();
+        this.valuationTableMapper = valuationTableMapper;
+        this.valuationTableAttributeMapper = valuationTableAttributeMapper;
+        this.fundPositionDetailMapper = fundPositionDetailMapper;
     }
 
     /**
@@ -188,6 +196,7 @@ public class EmailParseService {
             }
             // 保存净值表和规模表
             saveNavAndAssetNet(fileId, fundNavDTOList, parseDate);
+            saveValuationInfo(fileId, fundNavDTOList);
         }
 
         // 更新邮件解析结果 -> 当【净值日期】和【备案编码/基金名称】能正常解读,即识别为【成功】
@@ -201,6 +210,136 @@ public class EmailParseService {
         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) {
         String fileName = emailContentInfoDTO.getFileName();
         Integer emailType = emailContentInfoDTO.getEmailType();
@@ -241,7 +380,7 @@ public class EmailParseService {
                 PythonResult<?> result = PythonReportConverter.convert(JSONUtil.parseObj(body), type);
                 reportData = result.getData();
                 if (log.isInfoEnabled()) {
-                    log.info("报告{}结果为:\n{}",params, reportData);
+                    log.info("报告{}结果为:\n{}", params, reportData);
                 }
             } catch (Exception 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.setAssetShare(record.getAssetShare());
             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);
         }
         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.exceptions.ExceptionUtil;
 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.ValuationDataUtils;
 import com.simuwang.base.common.util.ValuationTableParseUtil;
@@ -32,27 +31,16 @@ public class ValuationParseService {
 
     private static final Logger log = LoggerFactory.getLogger(ValuationParseService.class);
 
-    public static final int stepSize = 10000;
-
     private final ValuationMarketCodeMapper valuationMarketCodeMapper;
-    private final FundPositionDetailMapper fundPositionDetailMapper;
-    private final ValuationTableMapper valuationTableMapper;
-    private final FundService fundService;
     private final PdfValuationRecordMapper pdfValuationRecordMapper;
     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.fundPositionDetailMapper = fundPositionDetailMapper;
-        this.valuationTableMapper = valuationTableMapper;
-        this.fundService = fundService;
         this.pdfValuationRecordMapper = pdfValuationRecordMapper;
         this.executor = executor;
-        this.valuationTableAttributeMapper = valuationTableAttributeMapper;
     }
 
     public List<AssetsValuationResult.Record> parseValuationExcel(List<ValuationNeedParseParam> valuationNeedParseParams) {
@@ -84,105 +72,44 @@ public class ValuationParseService {
                         String headInfo = excelInfo.getExtInfo().getHeadInfo();
                         if (StringUtils.isNotEmpty(headInfo)) {
                             AssetsValuationDetails details = excelInfo.getExtInfo();
-
                             parseValuationInfo = parseRegisterNumAndFundName(headInfo);
                             record.setParseValuationInfo(parseValuationInfo);
                             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);
+                                    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);
-                                    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) {
                 try {
                     ValuationResult r = future.get(3600, TimeUnit.SECONDS);
-                    String fundId = r.getFundId();
                     AssetsValuationResult.Record record = r.getRecord();
                     record.setCumulativeNavWithdrawal(record.getCumulativeNavWithdrawal());
                     // 获取资产净值和资产份额
@@ -202,72 +128,24 @@ public class ValuationParseService {
                     record.setAssetNet(assetNet != null ? String.valueOf(assetNet) : null);
                     record.setAssetShare(assetShare != null ? String.valueOf(assetShare) : null);
                     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) {
                     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));
         } finally {
             stopWatch.start("destruction valuation executor");
             stopWatch.stop();
             log.info("destruction valuation executor cost -> {}", stopWatch.prettyPrint(TimeUnit.MILLISECONDS));
         }
+
         //保存PDF估值表记录
         savePdfValuationRecord(valuationNeedParseParams, 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估值表记录
      *
@@ -404,61 +282,8 @@ public class ValuationParseService {
         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.setIsAnalyzed(0);
         tableInfo.setIsvalid(1);
@@ -478,8 +303,7 @@ public class ValuationParseService {
         tableInfo.setFromEmail(valuationNeedParseParam.getFromEmail());
         tableInfo.setOriginalFile(valuationNeedParseParam.getOriginFileName());
         tableInfo.setConvertedFile(valuationNeedParseParam.getFile().getName());
-        valuationTableMapper.insert(tableInfo);
-        return tableInfo.getId();
+        return tableInfo;
     }
 
     public AssetsValuationExcelInfo<AssetsValuationInfo> processDataV2(PreAssetsValuationInfo<PreAssetsValuationBase> info) {