DistributionServiceImpl.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. package com.simuwang.manage.service.impl;
  2. import cn.hutool.core.date.DateUtil;
  3. import com.alibaba.excel.EasyExcel;
  4. import com.alibaba.excel.read.listener.PageReadListener;
  5. import com.alibaba.excel.support.ExcelTypeEnum;
  6. import com.simuwang.base.common.conts.DateConst;
  7. import com.simuwang.base.common.conts.ExcelConst;
  8. import com.simuwang.base.common.enums.DistributeType;
  9. import com.simuwang.base.common.support.MybatisPage;
  10. import com.simuwang.base.common.util.DateUtils;
  11. import com.simuwang.base.common.util.ExcelUtil;
  12. import com.simuwang.base.common.util.FileUtil;
  13. import com.simuwang.base.common.util.StringUtil;
  14. import com.simuwang.base.mapper.DistributionMapper;
  15. import com.simuwang.base.mapper.FundInfoMapper;
  16. import com.simuwang.base.mapper.NavMapper;
  17. import com.simuwang.base.pojo.dos.DistributionDO;
  18. import com.simuwang.base.pojo.dos.DistributionTablePageDO;
  19. import com.simuwang.base.pojo.dos.FundInfoDO;
  20. import com.simuwang.base.pojo.dos.NavDO;
  21. import com.simuwang.base.pojo.dto.DistributionExcelData;
  22. import com.simuwang.base.pojo.dto.query.DistributionPageQuery;
  23. import com.simuwang.base.pojo.vo.*;
  24. import com.simuwang.manage.service.DistributionService;
  25. import com.simuwang.shiro.utils.UserUtils;
  26. import com.smppw.common.pojo.ResultVo;
  27. import com.smppw.common.pojo.enums.status.ResultCode;
  28. import com.smppw.common.pojo.enums.status.StatusCode;
  29. import org.apache.commons.io.FileUtils;
  30. import org.apache.poi.ss.formula.functions.Na;
  31. import org.slf4j.Logger;
  32. import org.slf4j.LoggerFactory;
  33. import org.springframework.beans.factory.annotation.Autowired;
  34. import org.springframework.beans.factory.annotation.Value;
  35. import org.springframework.stereotype.Service;
  36. import org.springframework.web.multipart.MultipartFile;
  37. import java.io.File;
  38. import java.io.InputStream;
  39. import java.math.BigDecimal;
  40. import java.util.*;
  41. import java.util.stream.Collectors;
  42. /**
  43. * FileName: DistributionServiceImpl
  44. * Author: chenjianhua
  45. * Date: 2024/9/15 14:07
  46. * Description: ${DESCRIPTION}
  47. */
  48. @Service
  49. public class DistributionServiceImpl implements DistributionService {
  50. private static final Logger logger = LoggerFactory.getLogger(DistributionServiceImpl.class);
  51. @Autowired
  52. private DistributionMapper distributionMapper;
  53. @Autowired
  54. private NavMapper navMapper;
  55. @Autowired
  56. private FundInfoMapper fundInfoMapper;
  57. @Value("${email.file.path}")
  58. private String path;
  59. @Override
  60. public MybatisPage<DistributionTablePageVO> searchDistributionList(DistributionPageQuery distributionPageQuery) {
  61. List<DistributionTablePageDO> distributionTablePageDOList = distributionMapper.searchDistributionList(distributionPageQuery);
  62. List<DistributionTablePageVO> distributionTablePageVOList = distributionTablePageDOList.stream().map(DistributionTablePageDO::toVo).collect(Collectors.toList());
  63. long total = distributionMapper.countDistributionList(distributionPageQuery);
  64. return MybatisPage.of(total,distributionTablePageVOList);
  65. }
  66. @Override
  67. public ResultVo saveDistribution(DistributionVO distributionVO) {
  68. ResultVo vo = new ResultVo(true);
  69. //判断是否存在当天净值
  70. NavDO navDO = new NavDO();
  71. navDO.setFundId(distributionVO.getFundId());
  72. navDO.setNav(distributionVO.getNav());
  73. navDO.setCreatorId(UserUtils.getLoginUser().getUserId());
  74. navDO.setUpdaterId(UserUtils.getLoginUser().getUserId());
  75. navDO.setCumulativeNavWithdrawal(distributionVO.getCumulativeNavWithdrawal());
  76. navDO.setPriceDate(DateUtils.parse(distributionVO.getDistributeDate(),DateUtils.YYYY_MM_DD));
  77. if(StringUtil.isNull(distributionVO.getNav()) || StringUtil.isNull(distributionVO.getCumulativeNavWithdrawal())){
  78. NavDO oldNav = navMapper.queryFundNav(navDO);
  79. if(StringUtil.isNull(oldNav)){
  80. vo.setData(false);
  81. vo.setMsg("当天不存在净值数据,请补充");
  82. return vo;
  83. }
  84. }
  85. DistributionDO distributionDO = new DistributionDO();
  86. distributionDO.setFundId(distributionVO.getFundId());
  87. distributionDO.setDistribution(distributionVO.getDistribution());
  88. distributionDO.setDistributeDate(DateUtils.parse(distributionVO.getDistributeDate(),DateUtils.YYYY_MM_DD));
  89. distributionDO.setDistributeType(distributionVO.getDistributeType());
  90. distributionDO.setIsvalid(1);
  91. distributionDO.setCreatorId(UserUtils.getLoginUser().getUserId());
  92. distributionDO.setUpdaterId(UserUtils.getLoginUser().getUserId());
  93. distributionDO.setUpdateTime(DateUtils.getNowDate());
  94. DistributionDO oldDistributionDO = distributionMapper.selectDistributionByDate(distributionVO.getFundId(),DateUtils.parse(distributionVO.getDistributeDate(),DateUtils.YYYY_MM_DD));
  95. if(!StringUtil.isNull(oldDistributionDO)){
  96. if(distributionVO.getId() != null && !oldDistributionDO.getId().equals(distributionVO.getId())){
  97. vo.setData(false);
  98. vo.setMsg("同一基金在同一天不能已存在分红数据");
  99. return vo;
  100. }
  101. distributionDO.setId(oldDistributionDO.getId());
  102. distributionMapper.updateDistributionById(distributionDO);
  103. }else{
  104. distributionDO.setCreateTime(DateUtils.getNowDate());
  105. distributionMapper.saveDistribution(distributionDO);
  106. }
  107. if(distributionVO.getNav() == null){
  108. return vo;
  109. }
  110. //保存净值
  111. NavDO oldNav = navMapper.queryFundNav(navDO);
  112. if(StringUtil.isNull(oldNav)){
  113. navDO.setUpdateTime(DateUtils.getNowDate());
  114. navDO.setCreateTime(DateUtils.getNowDate());
  115. navDO.setIsvalid(1);
  116. navMapper.saveNav(navDO);
  117. }else{
  118. navDO.setId(oldNav.getId());
  119. navDO.setUpdateTime(DateUtils.getNowDate());
  120. navMapper.updateNav(navDO);
  121. }
  122. return vo;
  123. }
  124. @Override
  125. public void deleteDistribution(IdListVO idListVO) {
  126. Integer userId = UserUtils.getLoginUser().getUserId();
  127. distributionMapper.deleteDistribution(idListVO.getIdList(),userId);
  128. }
  129. @Override
  130. public ResultVo uploadDistribution(MultipartFile excelFile) {
  131. ResultVo vo = new ResultVo(ResultCode.SUCCESS);
  132. File file = null;
  133. try{
  134. InputStream inputStream = excelFile.getInputStream();
  135. file = new File(path+"/upload/"+ System.currentTimeMillis()+"/"+excelFile.getOriginalFilename());
  136. FileUtils.copyInputStreamToFile(inputStream,file);
  137. List<DistributionExcelData> list = parseDistributionFile(file);
  138. vo.setData(parseResult(list));
  139. }catch (Exception e){
  140. logger.error(e.getMessage(),e);
  141. vo.setMsg("文件解析异常");
  142. vo.setData(false);
  143. return vo;
  144. }
  145. return vo;
  146. }
  147. private DistributionUploadResult parseResult(List<DistributionExcelData> list) {
  148. DistributionUploadResult result = new DistributionUploadResult();
  149. int startRow = 3;
  150. List<ExcelSuccessDataVO> successDataVOList = new ArrayList<>();
  151. List<ExcelFailDataVO> excelFailDataVOList = new ArrayList<>();
  152. for(int dataIdx=1;dataIdx<list.size(); dataIdx++){
  153. DistributionExcelData excelData = list.get(dataIdx);
  154. try{
  155. if((StringUtil.isEmpty(excelData.getFundName()) && StringUtil.isEmpty(excelData.getFundId()))
  156. || StringUtil.isEmpty(excelData.getPriceDate()) || StringUtil.isEmpty(excelData.getNav())
  157. || StringUtil.isEmpty(excelData.getDistributeType()) || StringUtil.isEmpty(excelData.getDistribution())
  158. || StringUtil.isEmpty(excelData.getCumulativeNavWithdrawal())){
  159. ExcelFailDataVO failDataVO = toExcelFailDataVO(excelData,ExcelConst.REQUIRE_FIELD,dataIdx+startRow);
  160. excelFailDataVOList.add(failDataVO);
  161. continue;
  162. }
  163. if(excelData.getDistributeType().trim().equals(ExcelConst.CASH_DIVIDENDS)){
  164. if(Double.valueOf(excelData.getDistribution()) < 0f){
  165. ExcelFailDataVO failDataVO = toExcelFailDataVO(excelData,ExcelConst.CASH_DIVIDENDS_FAIL,dataIdx+startRow);
  166. excelFailDataVOList.add(failDataVO);
  167. continue;
  168. }
  169. }else{
  170. if(Double.valueOf(excelData.getDistribution()) == 0f){
  171. ExcelFailDataVO failDataVO = toExcelFailDataVO(excelData,ExcelConst.DIVIDENDS_SPLIT_FAIL,dataIdx+startRow);
  172. excelFailDataVOList.add(failDataVO);
  173. continue;
  174. }
  175. }
  176. if(StringUtil.isNotEmpty(excelData.getFundId())){
  177. String fundName = fundInfoMapper.getFundNameByFundId(excelData.getFundId());
  178. if(StringUtil.isEmpty(excelData.getFundName())){
  179. excelData.setFundName(fundName);
  180. }
  181. if(StringUtil.isEmpty(fundName)){
  182. ExcelFailDataVO failDataVO = toExcelFailDataVO(excelData,ExcelConst.NOT_MAPPING_FUND,dataIdx+startRow);
  183. excelFailDataVOList.add(failDataVO);
  184. continue;
  185. }
  186. }else{
  187. String fundId = fundInfoMapper.queryFundIdByName(excelData.getFundName());
  188. if(StringUtil.isEmpty(fundId)){
  189. ExcelFailDataVO failDataVO = toExcelFailDataVO(excelData,ExcelConst.NOT_MAPPING_FUND,dataIdx+startRow);
  190. excelFailDataVOList.add(failDataVO);
  191. continue;
  192. }else{
  193. excelData.setFundId(fundId);
  194. }
  195. }
  196. //开始处理成功数据
  197. DistributionVO distributionVO = new DistributionVO();
  198. distributionVO.setFundId(excelData.getFundId());
  199. distributionVO.setDistributeDate(excelData.getPriceDate());
  200. distributionVO.setDistributeType(DistributeType.getDistributeTypeByInfo(excelData.getDistributeType()).getCode());
  201. distributionVO.setDistribution(BigDecimal.valueOf(Double.valueOf(excelData.getDistribution())));
  202. distributionVO.setNav(BigDecimal.valueOf(Double.valueOf(excelData.getNav())));
  203. distributionVO.setCumulativeNavWithdrawal(BigDecimal.valueOf(Double.valueOf(excelData.getCumulativeNavWithdrawal())));
  204. ResultVo vo = saveDistribution(distributionVO);
  205. if((boolean)vo.getData() == true){
  206. ExcelSuccessDataVO successDataVO = new ExcelSuccessDataVO();
  207. successDataVO.setDistribution(excelData.getDistribution());
  208. successDataVO.setFundName(excelData.getFundName());
  209. successDataVO.setPriceDate(excelData.getPriceDate());
  210. successDataVO.setDistributeType(excelData.getDistributeType());
  211. successDataVOList.add(successDataVO);
  212. }else{
  213. ExcelFailDataVO failDataVO = toExcelFailDataVO(excelData,vo.getMsg(),dataIdx+startRow);
  214. excelFailDataVOList.add(failDataVO);
  215. }
  216. }catch (Exception e){
  217. logger.error(e.getMessage(),e);
  218. ExcelFailDataVO failDataVO = toExcelFailDataVO(excelData,e.getMessage(),dataIdx+startRow);
  219. excelFailDataVOList.add(failDataVO);
  220. }
  221. }
  222. result.setSuccess(successDataVOList);
  223. result.setFail(excelFailDataVOList);
  224. result.setTotal(successDataVOList.size()+excelFailDataVOList.size());
  225. result.setFailCount(excelFailDataVOList.size());
  226. result.setSuccessCount(successDataVOList.size());
  227. return result;
  228. }
  229. private ExcelFailDataVO toExcelFailDataVO(DistributionExcelData excelData, String msg,Integer rowNum) {
  230. ExcelFailDataVO failDataVO = new ExcelFailDataVO();
  231. failDataVO.setFailReason(msg);
  232. failDataVO.setRowNum(rowNum);
  233. failDataVO.setDistribution(excelData.getDistribution());
  234. failDataVO.setFundName(excelData.getFundName());
  235. failDataVO.setPriceDate(excelData.getPriceDate());
  236. failDataVO.setDistributeType(excelData.getDistributeType());
  237. return failDataVO;
  238. }
  239. private List<DistributionExcelData> parseDistributionFile(File file) {
  240. // 创建一个 list 存储每行的数据,即 ExcelData 对象
  241. List<DistributionExcelData> list = new ArrayList<>();
  242. // 直接使用 EasyExcel 的 read 方法,同时定义表头的类型,以便将列中数据映射为 ExcelData 对象
  243. EasyExcel.read(file, DistributionExcelData.class, new PageReadListener<DistributionExcelData>(dataList -> {
  244. // 并且每行数据,并将其 add 至 list 中
  245. for (DistributionExcelData excelData : dataList) {
  246. if (excelData != null) {
  247. list.add(excelData);
  248. }
  249. }
  250. })).excelType(ExcelTypeEnum.XLSX).sheet().doRead();
  251. return list;
  252. }
  253. }