ValuationParseService.java 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. package com.simuwang.daq.service;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.collection.CollectionUtil;
  4. import cn.hutool.core.date.DateTime;
  5. import cn.hutool.core.date.StopWatch;
  6. import cn.hutool.core.exceptions.ExceptionUtil;
  7. import cn.hutool.core.util.StrUtil;
  8. import com.simuwang.base.common.util.ValuationBusinessUtils;
  9. import com.simuwang.base.common.util.ValuationDataUtils;
  10. import com.simuwang.base.common.util.ValuationTableParseUtil;
  11. import com.simuwang.base.mapper.*;
  12. import com.simuwang.base.pojo.dos.*;
  13. import com.simuwang.base.pojo.valuation.*;
  14. import com.smppw.utils.BigDecimalUtils;
  15. import com.smppw.utils.DateUtil;
  16. import org.apache.commons.lang3.StringUtils;
  17. import org.slf4j.Logger;
  18. import org.slf4j.LoggerFactory;
  19. import org.springframework.beans.factory.annotation.Qualifier;
  20. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  21. import org.springframework.stereotype.Service;
  22. import java.math.BigDecimal;
  23. import java.util.*;
  24. import java.util.concurrent.*;
  25. import java.util.stream.Collectors;
  26. @Service
  27. public class ValuationParseService {
  28. private static final Logger log = LoggerFactory.getLogger(ValuationParseService.class);
  29. private final ValuationMarketCodeMapper valuationMarketCodeMapper;
  30. private final PdfValuationRecordMapper pdfValuationRecordMapper;
  31. private final ThreadPoolTaskExecutor executor;
  32. public ValuationParseService(ValuationMarketCodeMapper valuationMarketCodeMapper, PdfValuationRecordMapper pdfValuationRecordMapper,
  33. @Qualifier("valuationExecutor") ThreadPoolTaskExecutor executor) {
  34. this.valuationMarketCodeMapper = valuationMarketCodeMapper;
  35. this.pdfValuationRecordMapper = pdfValuationRecordMapper;
  36. this.executor = executor;
  37. }
  38. public List<AssetsValuationResult.Record> parseValuationExcel(List<ValuationNeedParseParam> valuationNeedParseParams) {
  39. if (CollUtil.isEmpty(valuationNeedParseParams)) {
  40. return CollUtil.newArrayList();
  41. }
  42. StopWatch stopWatch = new StopWatch();
  43. stopWatch.start("create valuation executor");
  44. stopWatch.stop();
  45. log.info("create valuation executor cost -> {}", stopWatch.prettyPrint(TimeUnit.MILLISECONDS));
  46. List<AssetsValuationResult.Record> records = CollectionUtil.newArrayList();
  47. List<Future<ValuationResult>> futureList = CollectionUtil.newArrayList();
  48. List<String> marketCodeList = valuationMarketCodeMapper.queryMarketCode();
  49. try {
  50. for (ValuationNeedParseParam valuationNeedParseParam : valuationNeedParseParams) {
  51. ParseValuationInfo parseValuationInfo;
  52. AssetsValuationResult.Record record = new AssetsValuationResult.Record();
  53. PreAssetsValuationInfo<PreAssetsValuationBase> preAssetsValuationInfo = ValuationBusinessUtils.importFile(valuationNeedParseParam);
  54. PreAssetsValuationInfo<PreAssetsValuationBase>.Error error = preAssetsValuationInfo.getError();
  55. if (error != null) {
  56. error = preAssetsValuationInfo.getError();
  57. record.setExcelName(error.getExcelName()).setMsg(error.getMsg()).setRowNum(error.getRowNum()).setColumnNum(error.getCellNum())
  58. .setSuccess(0);
  59. records.add(record);
  60. } else {
  61. AssetsValuationExcelInfo<AssetsValuationInfo> excelInfo = processDataV2(preAssetsValuationInfo);
  62. // 邮件解析 -> 需要根据备案编码和基金名称去查询对应的基金id
  63. if (StringUtils.isEmpty(valuationNeedParseParam.getFundId())) {
  64. String headInfo = excelInfo.getExtInfo().getHeadInfo();
  65. if (StringUtils.isNotEmpty(headInfo)) {
  66. AssetsValuationDetails details = excelInfo.getExtInfo();
  67. parseValuationInfo = parseRegisterNumAndFundName(headInfo);
  68. record.setParseValuationInfo(parseValuationInfo);
  69. log.info("表格:{},从表格中解析到的基金名称和备案编码:{}", valuationNeedParseParam.getOriginFileName(), parseValuationInfo.toString());
  70. record.setNav(String.valueOf(details.getNav()));
  71. record.setCumulativeNavWithdrawal(String.valueOf(details.getCumulativeNav()));
  72. record.setExcelName(valuationNeedParseParam.getOriginFileName());
  73. record.setDate(details.getValuationDate());
  74. record.setExcelName(valuationNeedParseParam.getOriginFileName());
  75. record.setDate(details.getValuationDate());
  76. record.setSuccess(1);
  77. String valuationDate = details.getValuationDate();
  78. List<AssetsValuationInfo> data = excelInfo.getData();
  79. if (CollUtil.isNotEmpty(data)) {
  80. ValuationTableDO valuationTableDO = buildValuationTableDO(details, valuationNeedParseParam);
  81. record.setValuationTableDO(valuationTableDO);
  82. Future<ValuationResult> future = executor.submit(() -> {
  83. ValuationResult valuationResult = new ValuationResult();
  84. List<CmValuationTableAttribute> valuationTableAttributes = ValuationTableParseUtil.getAttrList(data);
  85. record.setValuationTableAttributeList(valuationTableAttributes);
  86. List<FundPositionDetailDO> fundPositionDetailDOList = ValuationTableParseUtil.parseDataNew(valuationTableAttributes, valuationTableDO, marketCodeList);
  87. record.setFundPositionDetailDOList(fundPositionDetailDOList);
  88. if (CollectionUtil.isNotEmpty(fundPositionDetailDOList)) {
  89. fundPositionDetailDOList.stream().filter(p -> "202".equals(p.getSecuritiesCode())).findFirst()
  90. .ifPresent(p -> valuationResult.setCumulativeNavWithdrawal(p.getMarketValue() != null ? String.valueOf(p.getMarketValue()) : null));
  91. }
  92. valuationResult.setValuationTableAttributes(valuationTableAttributes);
  93. valuationResult.setList(fundPositionDetailDOList);
  94. valuationResult.setRecord(record);
  95. valuationResult.setValuationDate(valuationDate);
  96. return valuationResult;
  97. });
  98. futureList.add(future);
  99. }
  100. }
  101. }
  102. }
  103. }
  104. for (Future<ValuationResult> future : futureList) {
  105. try {
  106. ValuationResult r = future.get(3600, TimeUnit.SECONDS);
  107. AssetsValuationResult.Record record = r.getRecord();
  108. record.setCumulativeNavWithdrawal(record.getCumulativeNavWithdrawal());
  109. // 获取资产净值和资产份额
  110. BigDecimal assetNet = r.getList().stream().filter(e -> StrUtil.isNotBlank(e.getSecuritiesCode()) && "112".equals(e.getSecuritiesCode()))
  111. .findFirst().map(FundPositionDetailDO::getMarketValue).orElse(null);
  112. BigDecimal assetShare = r.getList().stream().filter(e -> StrUtil.isNotBlank(e.getSecuritiesCode()) && "107".equals(e.getSecuritiesCode()))
  113. .findFirst().map(FundPositionDetailDO::getMarketValue).orElse(null);
  114. record.setAssetNet(assetNet != null ? String.valueOf(assetNet) : null);
  115. record.setAssetShare(assetShare != null ? String.valueOf(assetShare) : null);
  116. records.add(record);
  117. } catch (InterruptedException | ExecutionException | TimeoutException e) {
  118. log.info("valuation excel upload future exec exception: {}", e.getMessage(), e);
  119. }
  120. }
  121. } catch (
  122. Exception exception) {
  123. log.error("parse valuation excel error ->{}", ExceptionUtil.stacktraceToString(exception));
  124. } finally {
  125. stopWatch.start("destruction valuation executor");
  126. stopWatch.stop();
  127. log.info("destruction valuation executor cost -> {}", stopWatch.prettyPrint(TimeUnit.MILLISECONDS));
  128. }
  129. //保存PDF估值表记录
  130. savePdfValuationRecord(valuationNeedParseParams, records);
  131. return records;
  132. }
  133. /**
  134. * 保存PDF估值表记录
  135. *
  136. * @param valuationNeedParseParams 估值表解析参数
  137. * @param records 估值表解析结果
  138. */
  139. private void savePdfValuationRecord(List<ValuationNeedParseParam> valuationNeedParseParams, List<AssetsValuationResult.Record> records) {
  140. if (CollUtil.isEmpty(records)) {
  141. return;
  142. }
  143. List<AssetsValuationResult.Record> pdfRecordList = records.stream().filter(e -> e.getExcelName().endsWith("pdf")).collect(Collectors.toList());
  144. if (CollUtil.isEmpty(pdfRecordList)) {
  145. return;
  146. }
  147. List<PdfValuationRecordDO> pdfValuationRecordDoList = buildCmPdfValuationRecordDo(valuationNeedParseParams, pdfRecordList);
  148. if (CollUtil.isNotEmpty(pdfValuationRecordDoList)) {
  149. pdfValuationRecordMapper.batchInsert(pdfValuationRecordDoList);
  150. }
  151. }
  152. private List<PdfValuationRecordDO> buildCmPdfValuationRecordDo(List<ValuationNeedParseParam> valuationNeedParseParams,
  153. List<AssetsValuationResult.Record> pdfRecordList) {
  154. if (CollUtil.isEmpty(pdfRecordList)) {
  155. return CollUtil.newArrayList();
  156. }
  157. Map<String, ValuationNeedParseParam> needParseParamMap = valuationNeedParseParams.stream()
  158. .collect(Collectors.toMap(ValuationNeedParseParam::getOriginFileName, v -> v));
  159. return pdfRecordList.stream().map(e -> {
  160. PdfValuationRecordDO pdfValuationRecordDo = new PdfValuationRecordDO();
  161. ValuationNeedParseParam parseParam = needParseParamMap.get(e.getExcelName());
  162. if (parseParam != null) {
  163. pdfValuationRecordDo.setUploadDate(new Date());
  164. pdfValuationRecordDo.setExcelUrl(parseParam.getFile().getAbsolutePath());
  165. pdfValuationRecordDo.setPdfUrl(parseParam.getFileUrl());
  166. pdfValuationRecordDo.setFromEmail(parseParam.getFromEmail() == 1 ? 1 : 0);
  167. }
  168. pdfValuationRecordDo.setFundId(e.getFundId());
  169. pdfValuationRecordDo.setFileName(e.getExcelName());
  170. pdfValuationRecordDo.setIsSuccess(e.getSuccess());
  171. pdfValuationRecordDo.setReason(e.getMsg());
  172. pdfValuationRecordDo.setCreatorId(0);
  173. pdfValuationRecordDo.setUpdaterId(0);
  174. pdfValuationRecordDo.setCreateTime(new Date());
  175. pdfValuationRecordDo.setUpdateTime(new Date());
  176. pdfValuationRecordDo.setIsvalid(1);
  177. return pdfValuationRecordDo;
  178. }).collect(Collectors.toList());
  179. }
  180. /**
  181. * 解析备案编码和备案编码
  182. *
  183. * @param headInfo excel第一行和第二行的内容,中间以'@'符号分隔
  184. * @return 备案编码和备案编码
  185. */
  186. public ParseValuationInfo parseRegisterNumAndFundName(String headInfo) {
  187. ParseValuationInfo info = new ParseValuationInfo();
  188. if (StringUtils.isNotEmpty(headInfo)) {
  189. List<String> contentList = Arrays.stream(headInfo.split("@")).collect(Collectors.toList());
  190. for (String content : contentList) {
  191. String registerNumber = content.length() > 6 ? content.substring(0, 6) : null;
  192. if (StrUtil.isNotBlank(registerNumber) && !ValuationDataUtils.hasChinese(registerNumber, false)) {
  193. info.setRegisterNumber(registerNumber);
  194. }
  195. if (content.contains("估值表") || content.contains("专用表")) {
  196. String originRegisterNumber = info.getRegisterNumber();
  197. String originFundName = info.getFundName();
  198. if (content.contains("___")) {
  199. List<String> collect = Arrays.stream(content.split("___")).collect(Collectors.toList());
  200. if (collect.size() == 4 && content.contains("专用表")) {
  201. info.setRegisterNumber(collect.get(1));
  202. info.setFundName(collect.get(2));
  203. } else {
  204. if (CollUtil.isNotEmpty(collect) && StrUtil.isBlank(originRegisterNumber) && !ValuationDataUtils.hasChinese(registerNumber, false)) {
  205. originRegisterNumber = collect.get(0);
  206. info.setRegisterNumber(originRegisterNumber);
  207. }
  208. originFundName = collect.size() == 2 ? collect.get(0) : originFundName;
  209. originFundName = collect.size() > 2 ? collect.get(1) : originFundName;
  210. info.setFundName(originFundName);
  211. }
  212. } else if (content.contains("__")) {
  213. List<String> collect = Arrays.stream(content.split("__")).collect(Collectors.toList());
  214. if (collect.size() == 4 && content.contains("专用表")) {
  215. info.setRegisterNumber(collect.get(1));
  216. info.setFundName(collect.get(2));
  217. } else {
  218. if (CollUtil.isNotEmpty(collect) && StrUtil.isBlank(originRegisterNumber) && !ValuationDataUtils.hasChinese(registerNumber, false)) {
  219. originRegisterNumber = collect.get(0);
  220. info.setRegisterNumber(originRegisterNumber);
  221. }
  222. originFundName = collect.size() == 2 ? collect.get(0) : originFundName;
  223. originFundName = collect.size() > 2 ? collect.get(1) : originFundName;
  224. info.setFundName(originFundName);
  225. }
  226. } else if (content.contains("_")) {
  227. List<String> collect = Arrays.stream(content.split("_")).collect(Collectors.toList());
  228. if (collect.size() == 4 && content.contains("专用表")) {
  229. info.setRegisterNumber(collect.get(1));
  230. info.setFundName(collect.get(2));
  231. } else {
  232. if (CollUtil.isNotEmpty(collect) && StrUtil.isBlank(originRegisterNumber) && !ValuationDataUtils.hasChinese(registerNumber, false)) {
  233. originRegisterNumber = collect.get(0);
  234. info.setRegisterNumber(originRegisterNumber);
  235. }
  236. originFundName = collect.size() == 2 ? collect.get(0) : originFundName;
  237. originFundName = collect.size() > 2 ? collect.get(1) : originFundName;
  238. info.setFundName(originFundName);
  239. }
  240. }
  241. }
  242. }
  243. }
  244. //兼容格式: xxx估值表@基金名称 -> 只能识别到基金名称
  245. if (StrUtil.isBlank(info.getFundName()) && StrUtil.isBlank(info.getRegisterNumber())) {
  246. List<String> contentList = Arrays.stream(headInfo.split("@")).collect(Collectors.toList());
  247. if (CollUtil.isNotEmpty(contentList) && contentList.size() >= 2) {
  248. String fundName = !contentList.get(1).contains("_") ? contentList.get(1) : null;
  249. info.setFundName(fundName);
  250. }
  251. }
  252. // 兼容格式:编码编码+基金名称+日期+估值报表四级 -> SXT974同增FOF稳增1期私募证券投资基金2024年08月02日估值报表四级
  253. if (StrUtil.isBlank(info.getFundName()) && StrUtil.isNotBlank(info.getRegisterNumber())) {
  254. int index = StrUtil.indexOfIgnoreCase(headInfo, "私募证券投资基金");
  255. // 说明找到了
  256. if (index != -1) {
  257. String shortName = headInfo.substring(0, StrUtil.indexOfIgnoreCase(headInfo, "私募证券投资基金"));
  258. String fundName = shortName.replace(info.getRegisterNumber(), "") + "私募证券投资基金";
  259. info.setFundName(fundName);
  260. }
  261. }
  262. return info;
  263. }
  264. public ValuationTableDO buildValuationTableDO(AssetsValuationDetails details, ValuationNeedParseParam valuationNeedParseParam) {
  265. ValuationTableDO tableInfo = new ValuationTableDO();
  266. tableInfo.setValuationDate(DateUtil.StringToDate(details.getValuationDate()));
  267. tableInfo.setIsAnalyzed(0);
  268. tableInfo.setIsvalid(1);
  269. tableInfo.setCreateTime(DateTime.now());
  270. tableInfo.setUpdateTime(DateTime.now());
  271. tableInfo.setCreatorId(0);
  272. tableInfo.setUpdaterId(0);
  273. tableInfo.setTotalMarketValue(BigDecimalUtils.toBigDecimal(details.getTotalMarketValue()));
  274. tableInfo.setNetAssetsValue(BigDecimalUtils.toBigDecimal(details.getNetAssetsValue()));
  275. tableInfo.setIncrement(BigDecimalUtils.toBigDecimal(details.getIncrement()));
  276. tableInfo.setTitle(details.getTitle());
  277. tableInfo.setNav(BigDecimalUtils.toBigDecimal(details.getNav()));
  278. tableInfo.setFileUrl(valuationNeedParseParam.getFileUrl());
  279. tableInfo.setHeadInfo(details.getHeadInfo());
  280. tableInfo.setTailInfo(details.getTailInfo());
  281. tableInfo.setTableType(details.getType());
  282. tableInfo.setFromEmail(valuationNeedParseParam.getFromEmail());
  283. tableInfo.setOriginalFile(valuationNeedParseParam.getOriginFileName());
  284. tableInfo.setConvertedFile(valuationNeedParseParam.getFile().getName());
  285. return tableInfo;
  286. }
  287. public AssetsValuationExcelInfo<AssetsValuationInfo> processDataV2(PreAssetsValuationInfo<PreAssetsValuationBase> info) {
  288. AssetsValuationExcelInfo<AssetsValuationInfo> avInfo = new AssetsValuationExcelInfo<>();
  289. AssetsValuationDetails extInfo = new AssetsValuationDetails();
  290. extInfo.setTailInfo(list2String(info.getFooter()));
  291. extInfo.setHeadInfo(list2String(info.getHeader().getHeaderList()));
  292. extInfo.setOriginalfile(info.getExcelOriginName());
  293. extInfo.setConvertedFile(info.getExcelNewName());
  294. extInfo.setFileUrl(info.getSavePath());
  295. extInfo.setTitle(info.getHeader().getTitle());
  296. extInfo.setType(info.getType().getId());
  297. extInfo.setNav(info.getHeader().getUnitNetValue());
  298. extInfo.setUserId(ValuationDataUtils.string2Int(info.getUserId()));
  299. extInfo.setValuationDate(new Date(info.getHeader().getValuationDate().getTime()));
  300. List<PreAssetsValuationBase> lBases = info.getData();
  301. ValuationDataUtils.removeUnderLine(lBases);
  302. List<AssetsValuationInfo> list = new ArrayList<>(lBases.size());
  303. //现在业务需要保存基金的总资产 总资产 资产净值 直接从解析结果获取
  304. Double totalMarketValue = null;
  305. // 总资产净值
  306. Double netAssetMarketValue = null;
  307. // 基金估值增值
  308. Double increment = null;
  309. // 资产份额
  310. Double assetShare = null;
  311. for (int i = 0; i < lBases.size(); i++) {
  312. PreAssetsValuationBase d = lBases.get(i);
  313. if (d.getSubjectCode() == null || d.getSubjectCode().isEmpty()) {
  314. continue;
  315. }
  316. String originalSubjectCode = d.getOriginalSubjectCode();
  317. if (ValuationDataUtils.checkMarketValue(originalSubjectCode)) {
  318. totalMarketValue = ValuationDataUtils.string2Double(d.getMarketValue());
  319. }
  320. if (ValuationDataUtils.checkAssetShare(originalSubjectCode)) {
  321. assetShare = ValuationDataUtils.string2Double(d.getMarketValue());
  322. }
  323. if (ValuationDataUtils.checkNetAssetsValue(originalSubjectCode)) {
  324. netAssetMarketValue = ValuationDataUtils.string2Double(d.getMarketValue());
  325. increment = ValuationDataUtils.string2Double(d.getValueAdded());
  326. }
  327. AssetsValuationInfo data = new AssetsValuationInfo();
  328. data.setUserId(ValuationDataUtils.string2Int(info.getUserId()));
  329. data.setSecuritiesAmount(ValuationDataUtils.string2Double(d.getAmount()));
  330. data.setHaltInfo(d.getSuspensionInfo());
  331. data.setIncrement(ValuationDataUtils.string2Double(d.getValueAdded()));
  332. data.setMarketValue(ValuationDataUtils.string2Double(d.getMarketValue()));
  333. data.setMarketValueRatio(ValuationDataUtils.string2Double(d.getRatioOfMarketValueToNetWorth()));
  334. data.setNetCost(ValuationDataUtils.string2Double(d.getCost()));
  335. data.setNetCostRatio(ValuationDataUtils.string2Double(d.getRatioOfCostToNetWorth()));
  336. data.setSubjectCode(d.getSubjectCode());
  337. data.setSecuritiesCode((d.getSecurtiesCode()));
  338. // 对于期权,如果以DR、XR开头,则剔除这两个字母
  339. if (data.getSubjectName() != null && (data.getSubjectName().startsWith("DR") || data.getSubjectName().startsWith("XR"))) {
  340. String subjectName = data.getSubjectName().replace("DR", "");
  341. data.setSubjectName(subjectName.replace("XR", ""));
  342. } else {
  343. data.setSubjectName(d.getSubjectName());
  344. }
  345. data.setUnitCost(ValuationDataUtils.string2Double(d.getUnitCost()));
  346. //寻找累计单位净值
  347. if (null == extInfo.getCumulativeNav()) {
  348. if (StringUtils.isNotEmpty(d.getSubjectCode()) && d.getSubjectCode().contains("累计单位净值")) {
  349. if (StringUtils.isNotEmpty(d.getSubjectName()) && ValuationDataUtils.isNumber(d.getSubjectName())) {
  350. extInfo.setCumulativeNav(Double.valueOf(d.getSubjectName()));
  351. }
  352. }
  353. }
  354. switch (d.getType()) {
  355. case GeneralTemplate:
  356. PreAssetsValuationGeneralTemplate general = (PreAssetsValuationGeneralTemplate) d;
  357. data.setOriginalSubjectCode(general.getOriginalSubjectCode());
  358. data.setMarketPrice(ValuationDataUtils.string2Double(general.getMarketPrice()));
  359. data.setCurrency(general.getCurrency());
  360. data.setExchangeRate(general.getExchangeRate());
  361. data.setOriCurrencyCost(ValuationDataUtils.string2Double(general.getOriCurrencyCost()));
  362. data.setOriCurrencyMarketValue(ValuationDataUtils.string2Double(general.getOriCurrencyMarketValue()));
  363. data.setOriCurrencyValueAdded(ValuationDataUtils.string2Double(general.getOriCurrencyValueAdded()));
  364. data.setSubjectLevel(general.getSubjectLevel());
  365. data.setIssuer(general.getIssuer());
  366. data.setVProjectCode(general.getvProjectCode());
  367. data.setVProjectName(general.getvProjectName());
  368. data.setCostRatioAsset(general.getCostRatioAsset());
  369. data.setMvRatioAsset(general.getMvRatioAsset());
  370. data.setSpotPrice(general.getSpotPrice());
  371. data.setRemark(general.getRemark());
  372. data.setRightsInterestsInfo(general.getRightAndInterestInfo());
  373. data.setAssumingCost(general.getAssumingCost());
  374. data.setHoldingState(general.getHoldingState());
  375. if (data.getSubjectName() != null && ValuationDataUtils.isValid(data.getSubjectCode())) {
  376. data.setSubjectCode(data.getSubjectCode().replace(".", ""));
  377. if (ValuationDataUtils.hasChinese(data.getSubjectCode(), false)) {
  378. String code = data.getSubjectCode().replace(data.getSubjectName(), "");
  379. code = ValuationDataUtils.getSubjectCode(code);
  380. if (code.length() >= 4) {
  381. data.setSubjectCode(code);
  382. } else {
  383. data.setSecType(100);
  384. }
  385. }
  386. }
  387. break;
  388. default:
  389. break;
  390. }
  391. list.add(data);
  392. }
  393. extInfo.setTotalMarketValue(totalMarketValue);
  394. extInfo.setAssetShare(assetShare);
  395. extInfo.setNetAssetsValue(netAssetMarketValue);
  396. extInfo.setIncrement(increment);
  397. avInfo.setExtInfo(extInfo);
  398. avInfo.setData(list);
  399. return avInfo;
  400. }
  401. private static String list2String(List<String> list) {
  402. if (CollUtil.isEmpty(list)) {
  403. return null;
  404. }
  405. return String.join("@", list);
  406. }
  407. }