BigDecimal.add方法不生效

本文深入探讨了BigDecimal的加法操作。通过分析源码,揭示了为何直接调用add方法无法改变原有对象值的原因,强调了使用赋值操作来获取加法结果的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码一:

BigDecimal theory_score = new BigDecimal(0.0);
theory_score.add(bdJobContentAnswer.getScore());
//bdJobContentAnswer.getScore 为20.0

结果:theory_score = 0.0
代码二:

BigDecimal theory_score = new BigDecimal(0.0);
theory_score = theory_score.add(bdJobContentAnswer.getScore());

结果:theory_score = 20.0

原因:通过看BigDecimal.add()方法的源码发现

public BigDecimal add(BigDecimal augend) {
        if (this.intCompact != INFLATED) {
            if ((augend.intCompact != INFLATED)) {
                return add(this.intCompact, this.scale, augend.intCompact, augend.scale);
            } else {
                return add(this.intCompact, this.scale, augend.intVal, augend.scale);
            }
        } else {
            if ((augend.intCompact != INFLATED)) {
                return add(augend.intCompact, augend.scale, this.intVal, this.scale);
            } else {
                return add(this.intVal, this.scale, augend.intVal, augend.scale);
            }
        }
    }

add方法返回的是一个BigDecimal对象,所以是不能改变自身值得,只能用一个新对象去接收add方法改变后对象

我代码能力很差,你解释一下package com.foonsu.efenxiao.biz.handler; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.text.csv.CsvReadConfig; import cn.hutool.core.text.csv.CsvReader; import cn.hutool.core.text.csv.CsvRow; import cn.hutool.core.util.ObjectUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.foonsu.efenxiao.biz.config.CidReadListener; import com.foonsu.efenxiao.biz.feign.OrderClientWrapper; import com.foonsu.efenxiao.biz.util.OrderUtil; import com.foonsu.efenxiao.order.dto.CidOrder; import com.foonsu.efenxiao.biz.vo.ImportCidAccountVO; import com.foonsu.efenxiao.biz.vo.ProgressVo; import com.foonsu.efenxiao.common.utils.CollectionsUtil; import com.foonsu.efenxiao.order.dto.OrderDTO; import com.foonsu.efenxiao.order.dto.OrderExtendDto; import com.foonsu.efenxiao.order.dto.OrderGoodsDto; import com.foonsu.efenxiao.order.dto.OrderTradeDto; import com.foonsu.efenxiao.order.dubbo.CidClient; import com.foonsu.efenxiao.order.dubbo.OrderClient; import com.foonsu.efenxiao.order.entity.CidAccount; import com.foonsu.efenxiao.order.entity.CidAccountingDetail; import com.foonsu.efenxiao.order.entity.CidPlan; import com.foonsu.efenxiao.order.entity.Order; import com.foonsu.efenxiao.order.vo.CidAccountSearchVO; import com.foonsu.efenxiao.order.vo.CidOrderConsumption; import com.foonsu.efenxiao.order.vo.CidPlanSearchResp; import com.foonsu.efenxiao.order.vo.CidPlanSearchVo; import com.foonsu.efenxiao.order.vo.req.AdvertiserAccount; import com.foonsu.efenxiao.order.vo.req.HistoryPushAccountReq; import com.foonsu.efenxiao.platform.dubbo.GoodsClient; import com.foonsu.efenxiao.platform.entity.CidGoodsPriceHistory; import com.foonsu.efenxiao.platform.entity.PlatformGoods; import com.foonsu.efenxiao.platform.vo.PlatformGoodsSkuVO; import com.foonsu.efenxiao.platform.vo.PlatformGoodsVO; import com.foonsu.efenxiao.search.dubbo.OrderSearchClient; import com.foonsu.efenxiao.search.vo.ordersearch.*; import com.foonsu.efenxiao.webutil.progress.impl.CidImportAccountProgress; import com.foonsu.efenxiao.webutil.progress.impl.CidImportStatementProgress; import com.foonsu.framework.boot.common.utils.MD5Utils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; import org.apache.dubbo.config.annotation.DubboReference; import org.springblade.core.tool.api.R; import org.springblade.core.tool.utils.BeanUtil; import org.springblade.core.tool.utils.StringUtil; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.IOException; import java.io.InputStreamReader; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @Component @Slf4j public class CidShopBillHandler { private static final Pattern PATTERN = Pattern.compile("\\d{6}-\\d{15}"); @Resource @Qualifier("cidHandleThreadPoolTaskExecutor") ThreadPoolTaskExecutor cidHandleThreadPoolTaskExecutor; @DubboReference private OrderClient orderClient; @DubboReference private CidClient cidClient; @DubboReference private OrderSearchClient orderSearchClient; @DubboReference private GoodsClient goodsClient; @Resource private OrderClientWrapper orderClientWrapper; @Resource private CidImportStatementProgress cidImportStatementProgress; @Resource private CidImportAccountProgress cidImportAccountProgress; @Value("${cid.tenant-id}") private String tenantId; public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); public CidSearchOrderResp searchOrder(SearchOrderReq req, String tenantId) { SearchOrderBackendParam backendParam = new SearchOrderBackendParam(); backendParam.setTenantId(tenantId); EsSearchOrderResp resp = orderSearchClient.searchCidOrder(req, backendParam); CidSearchOrderResp cidSearchOrderResp = new CidSearchOrderResp(); if (!resp.getOrderNos().isEmpty()) { List<String> allOrderNos = resp.getOrderNos().stream().flatMap(Collection::stream).collect(Collectors.toList()); List<Order> ordersData = orderClientWrapper.queryByOrderNos(allOrderNos); List<CidOrderVO> cidOrderVOS = this.convertData(resp, ordersData); cidSearchOrderResp.setData(cidOrderVOS); } cidSearchOrderResp.setTotal(resp.getTotalCount().intValue()); cidSearchOrderResp.setCurrent(req.getPageNo()); cidSearchOrderResp.setSize(req.getPageSize()); cidSearchOrderResp.setPages(cidSearchOrderResp.getTotal() / req.getPageSize() + (cidSearchOrderResp.getTotal() % req.getPageSize() > 0 ? 1 : 0)); return cidSearchOrderResp; } private List<CidOrderVO> convertData(EsSearchOrderResp esSearchOrderResp, List<Order> orders) { List<CidOrderVO> cidOrderVOS = new ArrayList<>(); for (List<String> orderNos : esSearchOrderResp.getOrderNos()) { List<Order> onelineOrders = orders.stream().filter(t -> orderNos.contains(t.getOrderNo())).collect(Collectors.toList()); if (!onelineOrders.isEmpty()) { Map<String, List<Order>> tradeNoOrders = onelineOrders.stream().collect(Collectors.groupingBy(Order::getTradeNo)); for (String tradeNo : tradeNoOrders.keySet()) { List<Order> splitOrders = tradeNoOrders.get(tradeNo); List<OrderDTO> orderDTOS = OrderUtil.convertToDto(splitOrders); // cid默认单商品订单 OrderDTO orderDTO = orderDTOS.get(0); CidOrderVO cidOrderVO = new CidOrderVO(); cidOrderVO.setShopName(orderDTO.getShopName()); cidOrderVO.setJlId(orderDTO.getOrderGoodsDtoList().get(0).getBindJlId()); cidOrderVO.setTradeNo(orderDTO.getTradeNo()); cidOrderVO.setOrderNo(orderDTO.getOrderNo()); cidOrderVO.setPayAmount(orderDTO.getOrderTradeDto().getPayAmount()); CidOrderExtendVO cidOrderExtendVO = JSON.parseObject(orderDTO.getExtendInfo(), CidOrderExtendVO.class); cidOrderVO.setCidOrderExtendVO(cidOrderExtendVO); List<CidGoodsVo> goodsVos = JSON.parseArray(orderDTO.getGoods(), CidGoodsVo.class); cidOrderVO.setGoods(goodsVos); cidOrderVOS.add(cidOrderVO); } } } return cidOrderVOS; } public void compute(String tenantId, List<String> tradeNos) { Map<String, List<CidAccountingDetail>> accountDetailGroupByTradeNo = cidClient.queryAllImportCidTradeNo(tenantId, null, tradeNos) .stream().collect(Collectors.groupingBy(CidAccountingDetail::getTradeNo)); List<String> importCidTradeNos = new ArrayList<>(accountDetailGroupByTradeNo.keySet()); List<List<String>> reqsList = CollectionsUtil.splitListToThreads(importCidTradeNos, 1500, 20); for (List<String> orders : reqsList) { cidHandleThreadPoolTaskExecutor.submit(() -> { for (String order : orders) { this.handleOrder(order, tenantId, accountDetailGroupByTradeNo.get(order)); } }); } } public void compute(List<CidAccountingDetail> accountingDetails) { accountingDetails = accountingDetails.stream().sorted(Comparator.comparing(CidAccountingDetail::getTradeNo)).collect(Collectors.toList()); CollectionsUtil.batchDeal(accountingDetails, 500, accountingDetailList -> { List<CidOrder> cidOrders = new ArrayList<>(); Set<String> tradeNos = accountingDetailList.stream().map(CidAccountingDetail::getTradeNo).collect(Collectors.toSet()); Map<String, List<LocalDateTime>> occurTimeByTradeNos = cidClient.queryOccurentTimeByTradeNos(tradeNos); Map<String, List<CidAccountingDetail>> accountDetailGroupByTradeNo = accountingDetailList.stream().collect(Collectors.groupingBy(CidAccountingDetail::getTradeNo)); List<Order> orders = orderClient.queryOrderByTradeNos(new ArrayList<>(tradeNos)); if (CollectionsUtil.isEmpty(orders)) return; Map<String, Order> ordergroupbyTradeNo = orders.stream().collect(Collectors.toMap(Order::getTradeNo, Function.identity())); Map<String, String> ordersGroupByProductIdMap = orders.stream().collect(Collectors.toMap(Order::getTradeNo, order -> { List<OrderGoodsDto> orderGoodsDtos = JSONArray.parseArray(order.getGoods(), OrderGoodsDto.class); return orderGoodsDtos.get(0).getProductId(); })); List<String> skuIds = orders.stream().map(order -> { List<OrderGoodsDto> orderGoodsDtos = JSONArray.parseArray(order.getGoods(), OrderGoodsDto.class); return orderGoodsDtos.get(0).getSkuId(); }).distinct().collect(Collectors.toList()); Map<String, List<CidGoodsPriceHistory>> cidGoodsPriceGroupBySkuIdMap = goodsClient.selectCidGoodsPriceHistory(tenantId, null, skuIds) .stream().collect(Collectors.groupingBy(CidGoodsPriceHistory::getSkuId)); List<String> productIds = ordersGroupByProductIdMap.values().stream().distinct().collect(Collectors.toList()); Map<String, PlatformGoodsVO> goodsGroupByProductId = goodsClient.selectCidGoods(tenantId, productIds, null) .stream().collect(Collectors.toMap(PlatformGoodsVO::getProductId, Function.identity())); accountDetailGroupByTradeNo.forEach((tradeNo, accountDetails) -> { if (ordergroupbyTradeNo.containsKey(tradeNo)) { Order order = ordergroupbyTradeNo.get(tradeNo); String productId = ordersGroupByProductIdMap.get(tradeNo); if (goodsGroupByProductId.containsKey(productId)) { PlatformGoodsVO platformGoodsVO = goodsGroupByProductId.get(productId); OrderExtendDto orderExtendDto = computeGoodsProfit(platformGoodsVO, order, cidGoodsPriceGroupBySkuIdMap); cidOrders.addAll(covertCidOrders(accountDetails, orderExtendDto, tradeNo, platformGoodsVO.getBindJlId(), occurTimeByTradeNos.get(tradeNo))); } } }); if (cidOrders.isEmpty()) return; orderSearchClient.saveCidOrders(cidOrders); }, cidHandleThreadPoolTaskExecutor); } private CidOrder createEsCidOrder(String tenantId, String bindJlId, String tradeNO) { CidOrder esCidOrder = new CidOrder(); esCidOrder.setAccountId(bindJlId); esCidOrder.setTenantId(tenantId); esCidOrder.setTradeNo(tradeNO); return esCidOrder; } private List<CidOrder> covertCidOrders(List<CidAccountingDetail> accountDetails, OrderExtendDto orderExtendDto, String tradeNO, String bindJlId, List<LocalDateTime> occurTimes) { List<CidOrder> esCidOrders = accountDetails.stream().map(accountingDetail -> { CidOrder cidOrder = createEsCidOrder(tenantId, bindJlId, tradeNO); cidOrder.setId(accountingDetail.getUniqueId()); cidOrder.setOccurrenceTime(Collections.singletonList(LocalDateTime.parse(accountingDetail.getOccurrenceTime(), DATETIME_FORMATTER))); cidOrder.setRefundType(orderExtendDto.getRefundType()); BigDecimal incomeAmount = accountingDetail.getIncomeAmount() == null ? BigDecimal.ZERO : accountingDetail.getIncomeAmount(); BigDecimal expenditureAmount = accountingDetail.getExpenditureAmount() == null ? BigDecimal.ZERO : accountingDetail.getExpenditureAmount(); cidOrder.setOrderProfit(incomeAmount.add(expenditureAmount)); switch (accountingDetail.getAccountingType()) { case "扣款": cidOrder.setDeductionSum(accountingDetail.getExpenditureAmount()); switch (accountingDetail.getServiceType()) { case "0040002": cidOrder.setSalesCompensate(accountingDetail.getExpenditureAmount()); break; case "0040003": cidOrder.setExpressCompensate(accountingDetail.getExpenditureAmount()); break; case "0040004": cidOrder.setDelaySendGoods(accountingDetail.getExpenditureAmount()); break; case "0040005": cidOrder.setFalseSendGoods(accountingDetail.getExpenditureAmount()); break; case "0040006": cidOrder.setOutOfStock(accountingDetail.getExpenditureAmount()); } break; case "技术服务费": cidOrder.setTechnologyFee(accountingDetail.getExpenditureAmount()); break; case "多多进宝": cidOrder.setDdjb(accountingDetail.getExpenditureAmount()); } return cidOrder; }).collect(Collectors.toList()); CidOrder esCidOrder = createEsCidOrder(tenantId, bindJlId, tradeNO); esCidOrder.setOrderProfit(BigDecimal.ZERO.subtract(orderExtendDto.getPurchaseExpressFee())); esCidOrder.setId(tradeNO); esCidOrder.setOccurrenceTime(occurTimes.stream().distinct().collect(Collectors.toList())); esCidOrders.add(esCidOrder); return esCidOrders; } private OrderExtendDto computeGoodsProfit(PlatformGoodsVO platformGoods, Order order, Map<String, List<CidGoodsPriceHistory>> cidGoodsPriceGroupBySkuIdMap) { OrderTradeDto orderTradeDto = JSON.parseObject(order.getTrade(), OrderTradeDto.class); List<OrderGoodsDto> orderGoodsDtos = JSONArray.parseArray(order.getGoods(), OrderGoodsDto.class); OrderGoodsDto orderGoodsDto = orderGoodsDtos.get(0); OrderExtendDto orderExtendDto = new OrderExtendDto(); List<PlatformGoodsSkuVO> skuVOS = platformGoods.getGoodsSkuList().stream().filter(sku -> sku.getSkuId().equals(orderGoodsDto.getSkuId())).collect(Collectors.toList()); if (!skuVOS.isEmpty()) { PlatformGoodsSkuVO platformGoodsSkuVO = skuVOS.get(0); BigDecimal purchasePrice = platformGoodsSkuVO.getPurchaseUnitPrice(); BigDecimal expressFee = platformGoodsSkuVO.getExpressFee(); String skuId = platformGoodsSkuVO.getSkuId(); if (cidGoodsPriceGroupBySkuIdMap.containsKey(skuId)) { List<CidGoodsPriceHistory> cidGoodsPriceHistories = cidGoodsPriceGroupBySkuIdMap.get(skuId); for (CidGoodsPriceHistory cidGoodsPriceHistory : cidGoodsPriceHistories) { if (cidGoodsPriceHistory.getType() == 2 && DateUtil.toLocalDateTime(new Date(orderTradeDto.getSourceCreateDate())).isAfter(cidGoodsPriceHistory.getUpdateTime())) { purchasePrice = cidGoodsPriceHistory.getPrice(); } if (cidGoodsPriceHistory.getType() == 3 && DateUtil.toLocalDateTime(new Date(orderTradeDto.getSourceCreateDate())).isAfter(cidGoodsPriceHistory.getUpdateTime())) { expressFee = cidGoodsPriceHistory.getPrice(); } } } orderExtendDto.setPurchasePrice(purchasePrice == null ? BigDecimal.ZERO : purchasePrice); orderExtendDto.setExpressFee(expressFee == null ? BigDecimal.ZERO : expressFee); } if (orderGoodsDto.getRefundType() != null) { orderExtendDto.setPurchaseExpressFee(orderExtendDto.getExpressFee()); orderExtendDto.setRefundType(orderGoodsDto.getRefundType()); } else { if (orderExtendDto.getPurchasePrice() != null && orderExtendDto.getExpressFee() != null) { orderExtendDto.setPurchaseExpressFee(orderExtendDto.getPurchasePrice().add(orderExtendDto.getExpressFee())); } } return orderExtendDto; } private void handleOrder(String importCidTradeNo, String tenantId, List<CidAccountingDetail> cidAccountingDetails) { if (StringUtil.isBlank(importCidTradeNo)) { return; } List<Order> orders = orderClient.queryOrderByTradeNo(importCidTradeNo); if (orders.isEmpty()) { log.info("对账订单为空"); return; } // 默认都是单商品订单 Order order = orders.get(0); List<CidAccountingDetail> accountingDetails = cidClient.queryAccountingDetailByTradeNo(tenantId, importCidTradeNo); if (accountingDetails.isEmpty()) { log.info("对账明细为空"); return; } OrderTradeDto orderTradeDto = JSON.parseObject(order.getTrade(), OrderTradeDto.class); List<OrderGoodsDto> orderGoodsDtos = JSONArray.parseArray(order.getGoods(), OrderGoodsDto.class); OrderGoodsDto orderGoodsDto = orderGoodsDtos.get(0); List<PlatformGoodsVO> platformGoodsVOS = goodsClient.selectCidGoods(tenantId, null, null); if (platformGoodsVOS.isEmpty()) { return; } PlatformGoodsVO platformGoods = platformGoodsVOS.get(0); OrderExtendDto orderExtendDto = StringUtils.isBlank(order.getExtendInfo()) ? new OrderExtendDto() : JSON.parseObject(order.getExtendInfo(), OrderExtendDto.class); BigDecimal orderNum = BigDecimal.ZERO; BigDecimal deductionSum = BigDecimal.ZERO; BigDecimal technologyFee = BigDecimal.ZERO; BigDecimal ddjb = BigDecimal.ZERO; BigDecimal salesCompensate = BigDecimal.ZERO;// 售后补偿 BigDecimal expressCompensate = BigDecimal.ZERO;// 运费补偿 BigDecimal delaySendGoods = BigDecimal.ZERO;// 延迟发货 BigDecimal falseSendGoods = BigDecimal.ZERO;// 虚假发货 BigDecimal outOfStock = BigDecimal.ZERO;// 缺货 for (CidAccountingDetail accountingDetail : accountingDetails) { orderNum = orderNum.add(accountingDetail.getIncomeAmount()).add(accountingDetail.getExpenditureAmount()); boolean serviceFlag = false; switch (accountingDetail.getAccountingType()) { case "扣款": deductionSum = deductionSum.add(accountingDetail.getExpenditureAmount()); serviceFlag = true; break; case "技术服务费": technologyFee = technologyFee.add(accountingDetail.getExpenditureAmount()); break; case "多多进宝": ddjb = ddjb.add(accountingDetail.getExpenditureAmount()); } if (serviceFlag) { switch (accountingDetail.getServiceType()) { case "0040002": salesCompensate = salesCompensate.add(accountingDetail.getExpenditureAmount()); break; case "0040003": expressCompensate = expressCompensate.add(accountingDetail.getExpenditureAmount()); break; case "0040004": delaySendGoods = delaySendGoods.add(accountingDetail.getExpenditureAmount()); break; case "0040005": falseSendGoods = falseSendGoods.add(accountingDetail.getExpenditureAmount()); break; case "0040006": outOfStock = outOfStock.add(accountingDetail.getExpenditureAmount()); } } } orderExtendDto.setDeductionSum(deductionSum); orderExtendDto.setTechnologyFee(technologyFee); orderExtendDto.setDdjb(ddjb); orderExtendDto.setSalesCompensate(salesCompensate); orderExtendDto.setExpressCompensate(expressCompensate); orderExtendDto.setDelaySendGoods(delaySendGoods); orderExtendDto.setFalseSendGoods(falseSendGoods); orderExtendDto.setOutOfStock(outOfStock); orderExtendDto.setPurchasePrice(BigDecimal.ZERO); orderExtendDto.setExpressFee(BigDecimal.ZERO); List<PlatformGoodsSkuVO> skuVOS = platformGoods.getGoodsSkuList().stream().filter(sku -> sku.getSkuId().equals(orderGoodsDto.getSkuId())).collect(Collectors.toList()); if (!skuVOS.isEmpty()) { PlatformGoodsSkuVO platformGoodsSkuVO = skuVOS.get(0); BigDecimal purchasePrice = platformGoodsSkuVO.getPurchaseUnitPrice(); BigDecimal expressFee = platformGoodsSkuVO.getExpressFee(); List<CidGoodsPriceHistory> cidGoodsPriceHistories = goodsClient.selectCidGoodsPriceHistory(tenantId, null, null); if (!cidGoodsPriceHistories.isEmpty()) { for (CidGoodsPriceHistory cidGoodsPriceHistory : cidGoodsPriceHistories) { if (cidGoodsPriceHistory.getType() == 2 && DateUtil.toLocalDateTime(new Date(orderTradeDto.getSourceCreateDate())).isAfter(cidGoodsPriceHistory.getUpdateTime())) { purchasePrice = cidGoodsPriceHistory.getPrice(); } if (cidGoodsPriceHistory.getType() == 3 && DateUtil.toLocalDateTime(new Date(orderTradeDto.getSourceCreateDate())).isAfter(cidGoodsPriceHistory.getUpdateTime())) { expressFee = cidGoodsPriceHistory.getPrice(); } } } orderExtendDto.setPurchasePrice(purchasePrice == null ? BigDecimal.ZERO : purchasePrice); orderExtendDto.setExpressFee(expressFee == null ? BigDecimal.ZERO : expressFee); } if (orderGoodsDto.getRefundType() != null) { orderExtendDto.setPurchaseExpressFee(orderExtendDto.getExpressFee()); orderExtendDto.setRefundType(orderGoodsDto.getRefundType()); } else { if (orderExtendDto.getPurchasePrice() != null && orderExtendDto.getExpressFee() != null) { orderExtendDto.setPurchaseExpressFee(orderExtendDto.getPurchasePrice().add(orderExtendDto.getExpressFee())); } } orderExtendDto.setOrderSum(orderNum); orderExtendDto.setOrderProfit(orderExtendDto.getOrderSum().subtract(orderExtendDto.getPurchaseExpressFee())); orderGoodsDtos.get(0).setBindJlId(platformGoods.getBindJlId()); order.setGoods(JSON.toJSONString(orderGoodsDtos)); order.setExtendInfo(JSON.toJSONString(orderExtendDto)); orderClient.updateCidOrder(order); orderSearchClient.saveCidOrders(orderExtendDto, tenantId, accountingDetails, platformGoods.getBindJlId(), importCidTradeNo); } public void importFile(MultipartFile file, String tenantId, String taskId) { ProgressVo progressVo = new ProgressVo(); R<ProgressVo> result = R.data(progressVo); try { progressVo.setTotalCount(0); progressVo.setAllHasDone(false); cidImportStatementProgress.saveProgress(taskId, result); CsvReader csvReader = new CsvReader(new InputStreamReader(file.getInputStream(), "GBK"), new CsvReadConfig()); List<CsvRow> rows = csvReader.read().getRows(); int size = rows.size(); log.info("文件行数:{}", size); if (size == 0) { log.info("文件为空"); progressVo.setTotalCount(0); progressVo.setAllHasDone(true); cidImportStatementProgress.saveProgress(taskId, result); return; } this.handlerAccountingDetail(rows, tenantId, taskId); } catch (IOException e) { log.error("导入失败", e); throw new RuntimeException(e); } } private void handlerAccountingDetail(List<CsvRow> rows, String tenantId, String taskId) { LocalDateTime importFileTime = LocalDateTime.now(); log.info("执行处理:{}", rows.size()); AtomicInteger atomicInteger = new AtomicInteger(0); List<CidAccountingDetail> accountingDetails = new ArrayList<>(); try { for (CsvRow row : rows) { try { // log.info("row:{}", row); if (row.size() != 7) { continue; } if (StringUtil.isBlank(row.get(1))) { continue; } if ("商户订单号".equals(row.get(0))) { continue; } atomicInteger.getAndIncrement(); CidAccountingDetail accountingDetail = new CidAccountingDetail(); accountingDetail.setTenantId(tenantId); String tradeNo = row.get(0); if (StringUtil.isBlank(tradeNo)) { Matcher matcher = PATTERN.matcher(row.get(5)); if (matcher.find()) { tradeNo = matcher.group(); } else { continue; } } accountingDetail.setTradeNo(tradeNo); accountingDetail.setOccurrenceTime(row.get(1)); accountingDetail.setIncomeAmount(new BigDecimal(row.get(2))); accountingDetail.setExpenditureAmount(new BigDecimal(row.get(3))); accountingDetail.setAccountingType(row.get(4)); accountingDetail.setRemark(row.get(5)); String[] service = row.get(6).split("\\|"); accountingDetail.setServiceType(service[0]); accountingDetail.setServiceDesc(service[1]); accountingDetail.setCreateTime(importFileTime); String uniqueId = MD5Utils.encryptMD5(accountingDetail.getTradeNo() + accountingDetail.getOccurrenceTime() + accountingDetail.getAccountingType()); accountingDetail.setUniqueId(uniqueId); accountingDetails.add(accountingDetail); } catch (Exception e) { throw new RuntimeException(e); } } if (accountingDetails.isEmpty()) return; CountDownLatch countDownLatch = new CountDownLatch(accountingDetails.size() / 200 + 1); for (int j = 0; j < accountingDetails.size(); j += 200) { List<CidAccountingDetail> cidAccountList = accountingDetails.subList(j, Math.min(j + 200, accountingDetails.size())); cidHandleThreadPoolTaskExecutor.submit(() -> { cidClient.batchSaveAccountingDetail(cidAccountList); countDownLatch.countDown(); }); } countDownLatch.await(); compute(accountingDetails); } catch (Exception e) { throw new RuntimeException(e); } } public void importAccount(MultipartFile file, String tenantId, String taskId) { LocalDateTime importTime = LocalDateTime.now(); ProgressVo progressVo = new ProgressVo(); R<ProgressVo> result = R.data(progressVo); try { progressVo.setTotalCount(0); progressVo.setAllHasDone(false); cidImportAccountProgress.saveProgress(taskId, result); CidReadListener cidReadListener = new CidReadListener(); cidReadListener.setTenantId(tenantId); EasyExcel.read(file.getInputStream(), ImportCidAccountVO.class, cidReadListener).sheet().doRead(); int size = cidReadListener.getCachedDataList().size(); log.info("账户文件行数:{}", size); if (size == 0) { progressVo.setTotalCount(0); progressVo.setAllHasDone(true); cidImportAccountProgress.saveProgress(taskId, result); log.info("文件为空"); return; } int threadHandlerNum = size / 5 + (size % 5 > 0 ? 1 : 0); int fromIdx = 0; for (int i = 0; i < 5; i++) { List<CidAccount> cidAccounts = cidReadListener.getCachedDataList().subList(fromIdx, size - fromIdx >= threadHandlerNum ? fromIdx + threadHandlerNum : size); cidHandleThreadPoolTaskExecutor.submit(() -> { for (int j = 0; j < cidAccounts.size(); j += 100) { List<CidAccount> cidAccountList = cidAccounts.subList(j, Math.min(j + 100, cidAccounts.size())); cidClient.batchSaveCidAccount(cidAccountList); } log.info("处理账户完成:{}", cidAccounts.size()); return "任务完成"; }); fromIdx += cidAccounts.size(); } try { Thread.sleep(5000); } catch (InterruptedException e) { throw new RuntimeException(e); } log.info("处理账户完成, 调用生成报表:{}", importTime); this.generatePlan(tenantId, taskId, importTime, size); } catch (IOException e) { log.error("导入报表失败:{}", e.getMessage(), e); throw new RuntimeException(e); } } public void generatePlan(String tenantId, String taskId, LocalDateTime importTime, int insertCidAccountCount) { log.info("生成cid报表开始"); CidAccountSearchVO cidAccountSearchVO = new CidAccountSearchVO(); cidAccountSearchVO.setTenantId(tenantId); cidAccountSearchVO.setImportTime(importTime); Long size = 0L; for (int i = 1; i <= 10; i++) { size = cidClient.queryCidAccountCount(cidAccountSearchVO); log.info("计算cidAccount中,查询数据:{}", size); if (insertCidAccountCount == size) { break; } try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } if (size > 0L) { log.info("查询到{}条数据", size); AtomicInteger num = new AtomicInteger(0); ProgressVo progressVo = new ProgressVo(); progressVo.setTotalCount(size.intValue()); R<ProgressVo> result = R.data(progressVo); progressVo.setSuccessCount(num.get()); cidImportAccountProgress.saveProgress(taskId, result); Long finalSize = size; int pages = 1; int pageNo = 1; do { cidAccountSearchVO.setPageNo(pageNo); Page<CidAccount> cidAccountPage = cidClient.queryCidAccountPage(cidAccountSearchVO); pages = (int) cidAccountPage.getPages(); cidHandleThreadPoolTaskExecutor.submit(() -> { log.info("处理数量:{}", cidAccountPage.getRecords().size()); this.handleGroupPlan(cidAccountPage.getRecords(), taskId, finalSize.intValue(), num); }); pageNo++; } while (pageNo <= pages); } log.info("生成cid报表完成"); } private void handleGroupPlan(List<CidAccount> cidAccounts, String taskId, int accountListSize, AtomicInteger num) { ProgressVo progressVo = new ProgressVo(); progressVo.setTotalCount(accountListSize); R<ProgressVo> result = R.data(progressVo); for (CidAccount cidAccount : cidAccounts) { List<PlatformGoods> platformGoodsList = goodsClient.queryGoodsByAccountId(cidAccount.getTenantId(), cidAccount.getAccountId()); this.handlePlan(() -> { CidPlan cidPlan = new CidPlan(); cidPlan.setTenantId(cidAccount.getTenantId()); cidPlan.setAccountName(cidAccount.getAccount()); cidPlan.setChannel("巨量引擎"); cidPlan.setJlId(cidAccount.getAccountId()); cidPlan.setTotalConsumption(cidAccount.getConsume()); return cidPlan; }, platformGoodsList, null); num.getAndIncrement(); progressVo.setSuccessCount(num.get()); cidImportAccountProgress.saveProgress(taskId, result); } } private void handlePlan(Supplier<CidPlan> cidPlanSupplier, List<PlatformGoods> platformGoodsList, CidPlanSearchVo cidPlanSearchVo) { CidPlan cidPlan = cidPlanSupplier.get(); CidPlan result = orderSearchClient.statisticsCidOrder(cidPlan, DateUtil.toLocalDateTime(cidPlanSearchVo.getStartTime()), DateUtil.toLocalDateTime(cidPlanSearchVo.getEndTime())); BeanUtil.copyProperties(result, cidPlan); if (CollectionUtil.isNotEmpty(platformGoodsList)) { log.info("计划:{},没有找到商品", cidPlan.getJlId()); PlatformGoods platformGoods = platformGoodsList.get(0); cidPlan.setSalePrice(platformGoods.getSaleUnitPrice()); cidPlan.setPurchasePrice(platformGoods.getPurchaseUnitPrice()); cidPlan.setExpressFee(platformGoods.getExpressFee()); } } private List<CidOrderVO> filterOrderByDate(CidPlanSearchVo cidPlanSearchVo, List<CidOrderVO> orders) { if (cidPlanSearchVo == null) return orders; List<String> tradeNos = cidClient.selectOrderByTradeNoAndTime( orders.stream().map(CidOrderVO::getTradeNo).collect(Collectors.toList()), cidPlanSearchVo); //orderS过滤掉不包含tradeNo的订单 return orders.stream().filter(cidOrderVO -> tradeNos.contains(cidOrderVO.getTradeNo())).collect(Collectors.toList()); } private void handleOrder(List<CidOrderVO> data, Map<String, BigDecimal> param, Map<String, BigDecimal> deductionDetail, Map<String, Integer> orderParam) { int count = (int) data.stream().filter(cidOrderVO -> cidOrderVO.getCidOrderExtendVO().getRefundType() != null).count(); orderParam.put("refundOrderNum", orderParam.get("refundOrderNum") + count); orderParam.put("orderNum", orderParam.get("orderNum") + data.size()); for (CidOrderVO cidOrderVO : data) { if (cidOrderVO.getCidOrderExtendVO().getDeductionSum() != null) { param.put("deductionSum", param.get("deductionSum").add(cidOrderVO.getCidOrderExtendVO().getDeductionSum())); } if (cidOrderVO.getCidOrderExtendVO().getTechnologyFee() != null) { param.put("technologyFee", param.get("technologyFee").add(cidOrderVO.getCidOrderExtendVO().getTechnologyFee())); } if (cidOrderVO.getCidOrderExtendVO().getDdjb() != null) { param.put("ddjb", param.get("ddjb").add(cidOrderVO.getCidOrderExtendVO().getDdjb())); } if (cidOrderVO.getCidOrderExtendVO().getOrderProfit() != null) { param.put("profit", param.get("profit").add(cidOrderVO.getCidOrderExtendVO().getOrderProfit())); } if (cidOrderVO.getCidOrderExtendVO().getSalesCompensate() != null) { deductionDetail.put("salesCompensate", deductionDetail.get("salesCompensate").add(cidOrderVO.getCidOrderExtendVO().getSalesCompensate())); } if (cidOrderVO.getCidOrderExtendVO().getExpressCompensate() != null) { deductionDetail.put("expressCompensate", deductionDetail.get("expressCompensate").add(cidOrderVO.getCidOrderExtendVO().getExpressCompensate())); } if (cidOrderVO.getCidOrderExtendVO().getDelaySendGoods() != null) { deductionDetail.put("delaySendGoods", deductionDetail.get("delaySendGoods").add(cidOrderVO.getCidOrderExtendVO().getDelaySendGoods())); } if (cidOrderVO.getCidOrderExtendVO().getFalseSendGoods() != null) { deductionDetail.put("falseSendGoods", deductionDetail.get("falseSendGoods").add(cidOrderVO.getCidOrderExtendVO().getFalseSendGoods())); } if (cidOrderVO.getCidOrderExtendVO().getOutOfStock() != null) { deductionDetail.put("outOfStock", deductionDetail.get("outOfStock").add(cidOrderVO.getCidOrderExtendVO().getOutOfStock())); } } } public CidPlanSearchResp searchPlan(CidPlanSearchVo cidPlanSearchVo) { CidPlanSearchResp cidPlanSearchResp = new CidPlanSearchResp(); Page<CidPlan> cidPlanPage = cidClient.queryCidPlanPage(cidPlanSearchVo); List<CidPlan> cidPlans = cidPlanPage.getRecords(); if (ObjectUtil.isAllNotEmpty(cidPlanSearchVo.getStartTime(), cidPlanSearchVo.getEndTime())) { realTimeCompute(cidPlans, cidPlanSearchVo); } BigDecimal currentProfit = cidPlans.stream().map(CidPlan::getProfit).reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2, RoundingMode.HALF_UP); cidPlanSearchResp.setCurrentProfit(currentProfit); cidPlanSearchResp.setData(cidPlanPage); CidPlan result = orderSearchClient.statisticsCidOrder(new CidPlan(), DateUtil.toLocalDateTime(cidPlanSearchVo.getStartTime()), DateUtil.toLocalDateTime(cidPlanSearchVo.getEndTime())); cidPlanSearchResp.setTotalProfit(result.getProfit()); return cidPlanSearchResp; } private void realTimeCompute(List<CidPlan> cidPlans, CidPlanSearchVo cidPlanSearchVo) { if (CollectionsUtil.isEmpty(cidPlans)) return; computeCidPlan(cidPlans, cidPlanSearchVo, cidPlans.stream().map(CidPlan::getJlId).collect(Collectors.toList())); } private void computeCidPlan(List<CidPlan> cidPlans, CidPlanSearchVo cidPlanSearchVo, List<String> accountIds) { Map<String, List<PlatformGoods>> goodsMapGroupByBindJlId = goodsClient.queryGoodsByAccountIds(cidPlanSearchVo.getTenantId(), accountIds) .stream().collect(Collectors.groupingBy(PlatformGoods::getBindJlId)); CountDownLatch countDownLatch = new CountDownLatch(cidPlans.size()); cidPlans.forEach(cidPlan -> cidHandleThreadPoolTaskExecutor.execute(() -> { this.handlePlan(() -> cidPlan, goodsMapGroupByBindJlId.get(cidPlan.getJlId()), cidPlanSearchVo); countDownLatch.countDown(); })); try { countDownLatch.await(); } catch (InterruptedException e) { log.error("realTimeCompute error: {}", e.getMessage()); } } @Transactional(rollbackFor = Exception.class) public Boolean pushAccount(List<AdvertiserAccount> data) { List<String> accountIds = data.stream().map(AdvertiserAccount::getAdvertiserId).collect(Collectors.toList()); Map<String, List<PlatformGoods>> goodsMapGroupByBindJlId = goodsClient.queryGoodsByAccountIds(tenantId, accountIds) .stream().collect(Collectors.groupingBy(PlatformGoods::getBindJlId)); Map<String, CidPlan> cidPlanMap = cidClient.queryCidPlans(tenantId, accountIds).stream().collect(Collectors.toMap(CidPlan::getJlId, Function.identity())); CopyOnWriteArrayList<CidPlan> cidPlansList = new CopyOnWriteArrayList<>(); CountDownLatch count = new CountDownLatch(accountIds.size()); List<CidAccount> cidAccounts = data.stream().map(account -> { CidAccount cidAccount = account.mapToCidAccount(new HashMap<>(), tenantId); cidHandleThreadPoolTaskExecutor.execute(() -> { String accountId = cidAccount.getAccountId(); this.handlePlan(() -> dealHistoryPlan(cidAccount, cidPlanMap, cidPlansList), goodsMapGroupByBindJlId.get(accountId), null); count.countDown(); }); return cidAccount; }).collect(Collectors.toList()); cidClient.batchSaveCidPlan(cidPlansList); orderSearchClient.saveCidConsumption(convertEsCidOrderConsumption(data, new Date())); return cidClient.batchSaveCidAccount(cidAccounts); } private CidPlan dealHistoryPlan(CidAccount cidAccount, Map<String, CidPlan> cidPlanMap, CopyOnWriteArrayList<CidPlan> cidPlansList) { String accountId = cidAccount.getAccountId(); List<CidPlan.HistoryTotalConsumption> historyTotalConsumptions = cidPlanMap.containsKey(accountId) && CollectionsUtil.isNotEmpty(cidPlanMap.get(accountId).getHistoryTotalConsumptions()) ? cidPlanMap.get(accountId).getHistoryTotalConsumptions() : new ArrayList<>(); String today = DateUtil.formatDate(new Date()); BigDecimal consume = cidAccount.getConsume(); CidPlan.HistoryTotalConsumption todayData = new CidPlan.HistoryTotalConsumption(DateUtil.parseDate(today), consume); if (historyTotalConsumptions.isEmpty() || cidPlanMap.get(accountId).getHistoryTotalConsumptions().stream() .noneMatch(historyTotalConsumption -> today.equals(DateUtil.formatDate(historyTotalConsumption.getDate())))) { historyTotalConsumptions.add(todayData); } CidPlan cidPlan = new CidPlan(); cidPlan.setTenantId(cidAccount.getTenantId()); cidPlan.setAccountName(cidAccount.getAccount()); cidPlan.setChannel("巨量引擎"); cidPlan.setJlId(accountId); cidPlan.setTotalConsumption(consume); cidPlan.setHistoryTotalConsumption(JSON.toJSONString(historyTotalConsumptions)); cidPlansList.add(cidPlan); return cidPlan; } @Transactional(rollbackFor = Exception.class) public void pushHistoryData(HistoryPushAccountReq historyPushAccountReq) { String day = historyPushAccountReq.getDate(); DateTime time = DateUtil.parseDate(day); List<AdvertiserAccount> advertiserAccounts = historyPushAccountReq.getData(); List<String> accountIds = advertiserAccounts.stream().map(AdvertiserAccount::getAdvertiserId).collect(Collectors.toList()); Map<String, BigDecimal> historyDataMap = advertiserAccounts.stream().collect(Collectors.toMap(AdvertiserAccount::getAdvertiserId, AdvertiserAccount::getStatCost)); List<CidPlan> cidPlans = cidClient.queryCidPlans(tenantId, accountIds); cidPlans.forEach(cidPlan -> { BigDecimal consume = historyDataMap.get(cidPlan.getJlId()); CidPlan.HistoryTotalConsumption todayData = new CidPlan.HistoryTotalConsumption(time, consume); List<CidPlan.HistoryTotalConsumption> historyTotalConsumptions = cidPlan.getHistoryTotalConsumptions(); if (CollectionsUtil.isNotEmpty(historyTotalConsumptions)) { if (historyTotalConsumptions.stream() .noneMatch(consumption -> day.equals(DateUtil.formatDate(consumption.getDate())))) { historyTotalConsumptions.add(todayData); historyTotalConsumptions.sort(Comparator.comparing(CidPlan.HistoryTotalConsumption::getDate)); cidPlan.setHistoryTotalConsumption(JSON.toJSONString(historyTotalConsumptions)); } } else { cidPlan.setHistoryTotalConsumption(JSON.toJSONString(Collections.singleton(todayData))); } }); if (!cidPlans.isEmpty()) { cidClient.batchSaveCidPlan(cidPlans); orderSearchClient.saveCidConsumption(convertEsCidOrderConsumption(advertiserAccounts, time)); } } private List<CidOrderConsumption> convertEsCidOrderConsumption(List<AdvertiserAccount> advertiserAccounts, Date time) { return advertiserAccounts.stream().map(advertiserAccount -> new CidOrderConsumption(advertiserAccount, time.toInstant() .atZone(ZoneId.systemDefault()) .toLocalDate())).collect(Collectors.toList()); } public void syncData(String accountId) { CollectionsUtil.batchDealWholeData(pageNo -> { Page<CidPlan> cidPlanPage = cidClient.queryCidPlanPage(new CidPlanSearchVo(pageNo, 1000, tenantId, accountId)); List<CidPlan> cidPlans = cidPlanPage.getRecords(); log.info("cidPlans:{}", JSON.toJSONString(cidPlans)); List<CidOrderConsumption> cidOrderConsumptions = cidPlans.stream().flatMap(cidPlan -> cidPlan.getHistoryTotalConsumptions().stream() .filter(historyTotalConsumption -> BigDecimal.ZERO.compareTo(historyTotalConsumption.getTotalConsumption()) < 0) .map(historyTotalConsumption -> new CidOrderConsumption(cidPlan.getJlId(), historyTotalConsumption)) ).collect(Collectors.toList()); log.info("cidOrderConsumptions:{}", JSON.toJSONString(cidOrderConsumptions)); if (CollectionUtil.isNotEmpty(cidOrderConsumptions)) { orderSearchClient.saveCidConsumption(cidOrderConsumptions); } return cidPlans; }); } } 并且告诉我每一行为什么这样写
最新发布
07-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值