|  | @@ -12,12 +12,22 @@ import cn.newfeifan.mall.framework.common.enums.UserTypeEnum;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.framework.common.util.json.JsonUtils;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.framework.common.util.number.MoneyUtils;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.distri.constant.DistriConstants;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.controller.admin.integral.vo.IntegralSaveReqVO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.controller.admin.ptprofit.vo.PtProfitSaveReqVO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.controller.app.ptprofitlog.vo.PtProfitLogSaveReqVO;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.distri.dal.dataobject.integral.IntegralDO;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.distri.dal.dataobject.orderpercentage.OrderPercentageDO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.dal.dataobject.ptprofit.PtProfitDO;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.dal.dataobject.sharepath.SharePathDO;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.distri.dal.mysql.integral.IntegralMapper;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.distri.dal.mysql.orderpercentage.OrderPercentageMapper;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.distri.enums.CaclEnum;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.enums.SocialStatusEnum;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.service.duser.DuserService;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.distri.service.integral.IntegralService;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.service.ptprofit.PtProfitService;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.service.ptprofitlog.PtProfitLogService;
 | 
	
		
			
				|  |  | +import cn.newfeifan.mall.module.distri.service.sharepath.SharePathService;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.member.api.address.MemberAddressApi;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.member.api.address.dto.MemberAddressRespDTO;
 | 
	
		
			
				|  |  |  import cn.newfeifan.mall.module.member.service.user.MemberUserService;
 | 
	
	
		
			
				|  | @@ -74,16 +84,19 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 | 
	
		
			
				|  |  |  import lombok.extern.slf4j.Slf4j;
 | 
	
		
			
				|  |  |  import org.jetbrains.annotations.NotNull;
 | 
	
		
			
				|  |  |  import org.springframework.beans.BeanUtils;
 | 
	
		
			
				|  |  | +import org.springframework.context.annotation.Lazy;
 | 
	
		
			
				|  |  |  import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  |  import org.springframework.transaction.annotation.Transactional;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import javax.annotation.Resource;
 | 
	
		
			
				|  |  |  import java.math.BigDecimal;
 | 
	
		
			
				|  |  | +import java.math.BigInteger;
 | 
	
		
			
				|  |  |  import java.math.RoundingMode;
 | 
	
		
			
				|  |  |  import java.text.DecimalFormat;
 | 
	
		
			
				|  |  |  import java.time.LocalDateTime;
 | 
	
		
			
				|  |  |  import java.time.format.DateTimeFormatter;
 | 
	
		
			
				|  |  |  import java.util.*;
 | 
	
		
			
				|  |  | +import java.util.concurrent.CompletableFuture;
 | 
	
		
			
				|  |  |  import java.util.stream.Collectors;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
 | 
	
	
		
			
				|  | @@ -168,6 +181,17 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 | 
	
		
			
				|  |  |      @Resource
 | 
	
		
			
				|  |  |      private AdminUserService adminUserService;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private PtProfitService ptProfitService;
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    private PtProfitLogService ptProfitLogService;
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    @Lazy
 | 
	
		
			
				|  |  | +    private SharePathService sharePathService;
 | 
	
		
			
				|  |  | +    @Resource
 | 
	
		
			
				|  |  | +    @Lazy
 | 
	
		
			
				|  |  | +    private DuserService duserService;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      // =================== Order ===================
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
	
		
			
				|  | @@ -276,8 +300,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          //把店铺id和店铺名称查出来放到map中
 | 
	
		
			
				|  |  |          List<Long> shopIds = new ArrayList<>();
 | 
	
		
			
				|  |  | -        for (Long shopid : shopSkuIds.keySet()) {
 | 
	
		
			
				|  |  | -            shopIds.add(shopid);
 | 
	
		
			
				|  |  | +        for (Long shopId : shopSkuIds.keySet()) {
 | 
	
		
			
				|  |  | +            shopIds.add(shopId);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          List<ShopDO> shopDOList = shopMapper.selectListById(shopIds);
 | 
	
		
			
				|  |  |          Map<Long, String> shopNameMap = new HashMap<>();//key为店铺id,value为店铺名
 | 
	
	
		
			
				|  | @@ -361,7 +385,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 虚拟商品自走程序
 | 
	
		
			
				|  |  |       *
 | 
	
		
			
				|  |  | -     * @param address
 | 
	
		
			
				|  |  | +     * @param address 地址
 | 
	
		
			
				|  |  |       * @param items   商品项数组
 | 
	
		
			
				|  |  |       * @return AppTradeOrderSettlementRespVO
 | 
	
		
			
				|  |  |       */
 | 
	
	
		
			
				|  | @@ -744,13 +768,13 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 | 
	
		
			
				|  |  |              // 购买增加销量
 | 
	
		
			
				|  |  |              orderItems.forEach(orderItem -> {
 | 
	
		
			
				|  |  |                          orderItem.setOrderId(order.getId());
 | 
	
		
			
				|  |  | -                ProductSkuDO sku = productSkuMapper.selectById(orderItem.getSkuId());
 | 
	
		
			
				|  |  | -                sku.setSalesCount(sku.getSalesCount() + orderItem.getCount());
 | 
	
		
			
				|  |  | -                productSkuMapper.updateById(sku);
 | 
	
		
			
				|  |  | +                        ProductSkuDO sku = productSkuMapper.selectById(orderItem.getSkuId());
 | 
	
		
			
				|  |  | +                        sku.setSalesCount(sku.getSalesCount() + orderItem.getCount());
 | 
	
		
			
				|  |  | +                        productSkuMapper.updateById(sku);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                ProductSpuDO spu = productSpuMapper.selectById(orderItem.getSpuId());
 | 
	
		
			
				|  |  | -                spu.setSalesCount(spu.getSalesCount() + orderItem.getCount());
 | 
	
		
			
				|  |  | -                productSpuMapper.updateById(spu);
 | 
	
		
			
				|  |  | +                        ProductSpuDO spu = productSpuMapper.selectById(orderItem.getSpuId());
 | 
	
		
			
				|  |  | +                        spu.setSalesCount(spu.getSalesCount() + orderItem.getCount());
 | 
	
		
			
				|  |  | +                        productSpuMapper.updateById(spu);
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |              );
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1243,9 +1267,329 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 | 
	
		
			
				|  |  |          rs.add(allTradeOrderTotalFreezeAmount);
 | 
	
		
			
				|  |  |          rs.add(newSocialStatus);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        // 七天获得变为即算即得,后续如果恢复把这里注释即可,并打开平台定时任务得订单结算
 | 
	
		
			
				|  |  | +        CompletableFuture.runAsync(() -> {
 | 
	
		
			
				|  |  | +            calc(TradeOrderDOList, orderPercentageDO, JsonUtils.toJsonString(orderPercentageDO));
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          return rs;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 计算订单支付成功后,订单项的冻结积分转换
 | 
	
		
			
				|  |  | +     * @param tradeOrderDOList 订单列表
 | 
	
		
			
				|  |  | +     * @param orderPercentageDO 参数百分比
 | 
	
		
			
				|  |  | +     * @param percentTemplate 计算百分比模板
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private void calc(List<TradeOrderDO> tradeOrderDOList, OrderPercentageDO orderPercentageDO, String percentTemplate) {
 | 
	
		
			
				|  |  | +        // 平台收益日志
 | 
	
		
			
				|  |  | +        List<PtProfitLogSaveReqVO> ptProfitLogSaveReqVOS = new ArrayList<>();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        BigDecimal oneHundred = new BigDecimal(BigInteger.ONE);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 计算,毛利中100 之外的百分比
 | 
	
		
			
				|  |  | +        BigDecimal otherOneHundred = oneHundred.subtract(new BigDecimal(orderPercentageDO.getGrossProfitUserQuotaPerc()))
 | 
	
		
			
				|  |  | +                .subtract(new BigDecimal(orderPercentageDO.getGrossProfitAncestorQuotaPerc()))
 | 
	
		
			
				|  |  | +                .subtract(new BigDecimal(orderPercentageDO.getGrossProfitPlatformQuotaPerc()));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        tradeOrderDOList.forEach(k -> {
 | 
	
		
			
				|  |  | +            PtProfitDO ptProfitDO = ptProfitService.getPtProfit();
 | 
	
		
			
				|  |  | +            // 平台收益
 | 
	
		
			
				|  |  | +            List<PtProfitSaveReqVO> ptProfitSaveReqVOS = new ArrayList<>();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            List<TradeOrderItemDO> tradeOrderItemDOS = tradeOrderItemMapper.selectListByOrderId(k.getId());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 计算
 | 
	
		
			
				|  |  | +            // 计算利润: (价格 - 成本价格) * 产品数量
 | 
	
		
			
				|  |  | +            //用户自得和直推奖不用计算,从orderItem里面获取
 | 
	
		
			
				|  |  | +            final BigDecimal[] profit = {new BigDecimal("0"), new BigDecimal("0"), new BigDecimal("0"), new BigDecimal("0")};
 | 
	
		
			
				|  |  | +            tradeOrderItemDOS.forEach(j -> {
 | 
	
		
			
				|  |  | +                BigDecimal onePrice = new BigDecimal(j.getPrice());
 | 
	
		
			
				|  |  | +                BigDecimal oneCostPrice = new BigDecimal(j.getCostPrice());
 | 
	
		
			
				|  |  | +                BigDecimal productCount = new BigDecimal(j.getCount());
 | 
	
		
			
				|  |  | +                BigDecimal oneGrossProfit = onePrice.subtract(oneCostPrice).multiply(productCount);
 | 
	
		
			
				|  |  | +                profit[0] = profit[0].add(oneGrossProfit);  // 注意这里的改动
 | 
	
		
			
				|  |  | +                profit[1] = profit[1].add(new BigDecimal(j.getIncreaseIntegral()));     //自得积分
 | 
	
		
			
				|  |  | +                profit[2] = profit[2].add(new BigDecimal(j.getAncestorIncreaseIntegral()));     //直推奖
 | 
	
		
			
				|  |  | +                profit[3] = profit[3].add(new BigDecimal(j.getFreezeHighQuota()));     //用户获得冻结最大可用额度
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                // 遍历订单项拿到订单项编号
 | 
	
		
			
				|  |  | +                //将当前订单项设置为已分配权益
 | 
	
		
			
				|  |  | +                TradeOrderItemDO item = new TradeOrderItemDO();
 | 
	
		
			
				|  |  | +                item.setId(j.getId());
 | 
	
		
			
				|  |  | +                item.setDistributeBenefit(true);
 | 
	
		
			
				|  |  | +                tradeOrderItemMapper.updateById(item);
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 计算毛利: 利润 * 1
 | 
	
		
			
				|  |  | +            BigDecimal grossProfit = profit[0].multiply(new BigDecimal(orderPercentageDO.getGrossProfitPerc())).setScale(4, RoundingMode.DOWN);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 计算平台收益
 | 
	
		
			
				|  |  | +            BigDecimal grossProfitAfterBonus = profit[0].multiply(oneHundred.subtract(new BigDecimal(orderPercentageDO.getGrossProfitPerc()))).setScale(4, RoundingMode.DOWN);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (otherOneHundred.compareTo(new BigDecimal(BigInteger.ZERO)) > 0) {
 | 
	
		
			
				|  |  | +                grossProfitAfterBonus = grossProfitAfterBonus.add(grossProfit.multiply(otherOneHundred).setScale(4, RoundingMode.DOWN));
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 用户所得: 毛利 * 0.35
 | 
	
		
			
				|  |  | +            BigDecimal descendantQuota = profit[1];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 直推奖: 毛利 * 0.3 (上一级)
 | 
	
		
			
				|  |  | +            BigDecimal ancestorQuota = profit[2];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 平台服务费: 毛利 * 0.05
 | 
	
		
			
				|  |  | +            BigDecimal platformQuota = grossProfit.multiply(new BigDecimal(orderPercentageDO.getGrossProfitPlatformQuotaPerc())).setScale(4, RoundingMode.DOWN);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 计算当前下单人的毛利的十倍
 | 
	
		
			
				|  |  | +//            BigDecimal highQuota = grossProfit.multiply(new BigDecimal("10")).setScale(4, RoundingMode.DOWN);
 | 
	
		
			
				|  |  | +            BigDecimal highQuota = profit[3];
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 乘以 10000 并转换为整数
 | 
	
		
			
				|  |  | +            Long ancestorQuotaInt = ancestorQuota.longValue();
 | 
	
		
			
				|  |  | +            Long descendantQuotaInt = descendantQuota.longValue();
 | 
	
		
			
				|  |  | +            Long highQuotaInt = highQuota.longValue();
 | 
	
		
			
				|  |  | +            Long grossProfitAfterBonusInt = grossProfitAfterBonus.multiply(new BigDecimal("10000")).setScale(0, RoundingMode.DOWN).longValue();
 | 
	
		
			
				|  |  | +            Long platformQuotaInt = platformQuota.multiply(new BigDecimal("10000")).setScale(0, RoundingMode.DOWN).longValue();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 获取当前下单人关系
 | 
	
		
			
				|  |  | +            SharePathDO sharePath = getSharePath(k.getUserId());
 | 
	
		
			
				|  |  | +            // 如果sharePath为空, 则说明没有直推人关系
 | 
	
		
			
				|  |  | +            IntegralDO integralDOAncestor = integralService.selectByUser(sharePath.getAncestor());      //父级
 | 
	
		
			
				|  |  | +            IntegralDO integralDO = integralService.selectByUser(sharePath.getDescendant());            //自己
 | 
	
		
			
				|  |  | +            IntegralDO ptIntegral = integralService.selectByUser(1L);                         //pt
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // ========== 身价计算 ==============
 | 
	
		
			
				|  |  | +            //推荐人身价计算
 | 
	
		
			
				|  |  | +            double orderAncestorSocialStatus = Double.parseDouble(orderPercentageDO.getOrderAncestorSocialStatus());
 | 
	
		
			
				|  |  | +            double ancestorSocial = k.getTotalPrice() * orderAncestorSocialStatus / 100;
 | 
	
		
			
				|  |  | +            duserService.updateDuserSocial(integralDOAncestor.getUserId(), (long) ancestorSocial, SocialStatusEnum.SHOPPING_ANCESTOR_SOCIAL.getStatus());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //自得身价计算
 | 
	
		
			
				|  |  | +            double orderUserSocialStatus = Double.parseDouble(orderPercentageDO.getOrderUserSocialStatus());
 | 
	
		
			
				|  |  | +            double descendantSocial = k.getTotalPrice() * orderUserSocialStatus / 100;
 | 
	
		
			
				|  |  | +            duserService.updateDuserSocial(integralDO.getUserId(), (long) descendantSocial, SocialStatusEnum.SHOPPING_SOCIAL.getStatus());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            /*
 | 
	
		
			
				|  |  | +            原本这里有添加到distri_order_calc表的记录,但是现在要合赢奖和(直推奖、自得奖)分开,所以现在搬走了
 | 
	
		
			
				|  |  | +             */
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // ========== 修改用户钱包 =================
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //直推奖也要限制额度
 | 
	
		
			
				|  |  | +            Long ancestorHighQuota = integralDOAncestor.getHighQuota() + new BigDecimal(orderPercentageDO.getBaseMaxQuota()).longValue();//加上基础的最大额度值
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //amount用于记录本次添加的值
 | 
	
		
			
				|  |  | +            Long amount = 0L;
 | 
	
		
			
				|  |  | +            //平台需要补回的收益
 | 
	
		
			
				|  |  | +            Long ptReplenish = ancestorQuotaInt;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            //如果直推人的可获取额度大于0,则能够获取
 | 
	
		
			
				|  |  | +            if (ancestorHighQuota.compareTo(0L) > 0) {
 | 
	
		
			
				|  |  | +                if (ancestorHighQuota.compareTo(ancestorQuotaInt) > 0) {
 | 
	
		
			
				|  |  | +                    //如果最大额度 > 直推人可获取额度,则直接获取
 | 
	
		
			
				|  |  | +                    amount = ancestorQuotaInt;
 | 
	
		
			
				|  |  | +                    //平台没有需要补回的收益
 | 
	
		
			
				|  |  | +                    ptReplenish = 0L;
 | 
	
		
			
				|  |  | +                } else {
 | 
	
		
			
				|  |  | +                    //如果最大额度 < 直推人可获取额度,则获取自己的最大额度
 | 
	
		
			
				|  |  | +                    amount = ancestorHighQuota;
 | 
	
		
			
				|  |  | +                    //用户本次没有拿到的直推奖
 | 
	
		
			
				|  |  | +                    ptReplenish = ancestorQuotaInt - ancestorHighQuota;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            changeUserWallet(integralDO, integralDOAncestor, ptIntegral, amount,
 | 
	
		
			
				|  |  | +                    descendantQuotaInt, highQuotaInt, grossProfitAfterBonusInt, platformQuotaInt, ptReplenish);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // ========== 修改平台信息 =================
 | 
	
		
			
				|  |  | +            // 每个订单计算的过程
 | 
	
		
			
				|  |  | +            // 增加平台收益
 | 
	
		
			
				|  |  | +            // 平台服务费
 | 
	
		
			
				|  |  | +            PtProfitSaveReqVO ptProfitSaveReqVO =
 | 
	
		
			
				|  |  | +                    PtProfitSaveReqVO.builder()
 | 
	
		
			
				|  |  | +                            .ptAdd(platformQuotaInt)
 | 
	
		
			
				|  |  | +                            .ptGrossAdd(grossProfitAfterBonusInt)
 | 
	
		
			
				|  |  | +                            .ptTotalAdd(platformQuotaInt + grossProfitAfterBonusInt).build();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 当直推人获取的积分额度不足时,平台收益要加回来,并生成log
 | 
	
		
			
				|  |  | +            if (ptReplenish.compareTo(0L) > 0) {
 | 
	
		
			
				|  |  | +                calcIntegral(ptProfitSaveReqVOS, ptProfitSaveReqVO, ptReplenish,
 | 
	
		
			
				|  |  | +                        k.getId(), k.getNo());
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            ptProfitSaveReqVOS.add(ptProfitSaveReqVO);
 | 
	
		
			
				|  |  | +            // ========== 增加日志记录 =================
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 平台记录
 | 
	
		
			
				|  |  | +            // 平台总收益
 | 
	
		
			
				|  |  | +            // 平台总收益
 | 
	
		
			
				|  |  | +            PtProfitLogSaveReqVO ptTotal = PtProfitLogSaveReqVO.builder()
 | 
	
		
			
				|  |  | +                    .orderId(k.getId())
 | 
	
		
			
				|  |  | +                    .profitStatus(CaclEnum.PLATFORM_TOTAL_ADD.getType())
 | 
	
		
			
				|  |  | +                    .orderNo(k.getNo())
 | 
	
		
			
				|  |  | +                    .amount(platformQuotaInt + grossProfitAfterBonusInt)
 | 
	
		
			
				|  |  | +                    .afterAmount(ptProfitDO.getPtTotalAdd() + platformQuotaInt + grossProfitAfterBonusInt)
 | 
	
		
			
				|  |  | +                    .percentTemplate(percentTemplate)
 | 
	
		
			
				|  |  | +                    .generateUserId(integralDO.getUserId())
 | 
	
		
			
				|  |  | +                    .build();
 | 
	
		
			
				|  |  | +            // 平台收益
 | 
	
		
			
				|  |  | +            PtProfitLogSaveReqVO ptGrossAddLog = PtProfitLogSaveReqVO.builder()
 | 
	
		
			
				|  |  | +                    .orderId(k.getId())
 | 
	
		
			
				|  |  | +                    .profitStatus(CaclEnum.PLATFORM_REVENUE.getType())
 | 
	
		
			
				|  |  | +                    .orderNo(k.getNo())
 | 
	
		
			
				|  |  | +                    .amount(grossProfitAfterBonusInt)
 | 
	
		
			
				|  |  | +                    .afterAmount(ptProfitDO.getPtGrossAdd() + ptProfitSaveReqVO.getPtGrossAdd())
 | 
	
		
			
				|  |  | +                    .percentTemplate(percentTemplate)
 | 
	
		
			
				|  |  | +                    .generateUserId(integralDO.getUserId())
 | 
	
		
			
				|  |  | +                    .build();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 平台服务费
 | 
	
		
			
				|  |  | +            PtProfitLogSaveReqVO ptAddLog = PtProfitLogSaveReqVO.builder()
 | 
	
		
			
				|  |  | +                    .orderId(k.getId())
 | 
	
		
			
				|  |  | +                    .profitStatus(CaclEnum.PLATFORM_SERVICE_FEE.getType())
 | 
	
		
			
				|  |  | +                    .orderNo(k.getNo())
 | 
	
		
			
				|  |  | +                    .amount(platformQuotaInt)
 | 
	
		
			
				|  |  | +                    .afterAmount(ptProfitDO.getPtAdd() + ptProfitSaveReqVO.getPtAdd())
 | 
	
		
			
				|  |  | +                    .percentTemplate(percentTemplate)
 | 
	
		
			
				|  |  | +                    .generateUserId(integralDO.getUserId())
 | 
	
		
			
				|  |  | +                    .build();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 直推奖记录
 | 
	
		
			
				|  |  | +            PtProfitLogSaveReqVO tjrLog = PtProfitLogSaveReqVO.builder()
 | 
	
		
			
				|  |  | +                    .orderId(k.getId())
 | 
	
		
			
				|  |  | +                    .profitStatus(CaclEnum.RECOMMENDED_PERSON_QUOTA.getType())
 | 
	
		
			
				|  |  | +                    .orderNo(k.getNo())
 | 
	
		
			
				|  |  | +                    .userId(sharePath.getAncestor())
 | 
	
		
			
				|  |  | +                    .amount(amount)
 | 
	
		
			
				|  |  | +                    .afterAmount(integralDOAncestor.getCurrentQuota())
 | 
	
		
			
				|  |  | +                    .freezeAmount(-amount)
 | 
	
		
			
				|  |  | +                    .afterFreezeAmount(integralDOAncestor.getFreezeQuota())
 | 
	
		
			
				|  |  | +                    .ancestorQuotaAmount(ptReplenish)
 | 
	
		
			
				|  |  | +                    .maxAvailablePointsAmount(-amount)
 | 
	
		
			
				|  |  | +                    .afterMaxAvailablePointsAmount(ancestorHighQuota - amount)
 | 
	
		
			
				|  |  | +                    .percentTemplate(percentTemplate)
 | 
	
		
			
				|  |  | +                    .generateUserId(integralDO.getUserId())
 | 
	
		
			
				|  |  | +                    .build();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 用户自得记录 + 户冻结积分转化成可用 + 扣减最高可用额度记录
 | 
	
		
			
				|  |  | +            PtProfitLogSaveReqVO ztrLog = PtProfitLogSaveReqVO.builder()
 | 
	
		
			
				|  |  | +                    .orderId(k.getId())
 | 
	
		
			
				|  |  | +                    .profitStatus(CaclEnum.DIRECT_REFERRAL_QUOTA.getType())
 | 
	
		
			
				|  |  | +                    .orderNo(k.getNo())
 | 
	
		
			
				|  |  | +                    .userId(sharePath.getDescendant())
 | 
	
		
			
				|  |  | +                    .amount(descendantQuotaInt)
 | 
	
		
			
				|  |  | +                    .afterAmount(integralDO.getCurrentQuota())
 | 
	
		
			
				|  |  | +                    .freezeAmount(-descendantQuotaInt)
 | 
	
		
			
				|  |  | +                    .afterFreezeAmount(integralDO.getFreezeQuota())
 | 
	
		
			
				|  |  | +                    .maxAvailablePointsAmount(highQuotaInt)
 | 
	
		
			
				|  |  | +                    .afterMaxAvailablePointsAmount(integralDO.getHighQuota() + new BigDecimal(orderPercentageDO.getBaseMaxQuota()).longValue())
 | 
	
		
			
				|  |  | +                    .freezeHighQuota(-highQuotaInt)
 | 
	
		
			
				|  |  | +                    .afterFreezeHighQuota(integralDO.getFreezeHighQuota())
 | 
	
		
			
				|  |  | +                    .percentTemplate(percentTemplate)
 | 
	
		
			
				|  |  | +                    .generateUserId(integralDO.getUserId())
 | 
	
		
			
				|  |  | +                    .build();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            ptProfitLogSaveReqVOS.add(ptTotal);
 | 
	
		
			
				|  |  | +            ptProfitLogSaveReqVOS.add(ptGrossAddLog);
 | 
	
		
			
				|  |  | +            ptProfitLogSaveReqVOS.add(ptAddLog);
 | 
	
		
			
				|  |  | +            ptProfitLogSaveReqVOS.add(tjrLog);
 | 
	
		
			
				|  |  | +            ptProfitLogSaveReqVOS.add(ztrLog);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            PtProfitDO ptProfit = ptProfitService.getPtProfit();
 | 
	
		
			
				|  |  | +            // 计算总积分
 | 
	
		
			
				|  |  | +            Long total = ptProfitSaveReqVOS.stream().mapToLong(PtProfitSaveReqVO::getPtTotalAdd).sum();
 | 
	
		
			
				|  |  | +            Long add = ptProfitSaveReqVOS.stream().mapToLong(PtProfitSaveReqVO::getPtAdd).sum();
 | 
	
		
			
				|  |  | +            Long grossAdd = ptProfitSaveReqVOS.stream().mapToLong(PtProfitSaveReqVO::getPtGrossAdd).sum();
 | 
	
		
			
				|  |  | +            ptProfit.setPtAdd(ptProfit.getPtAdd() + add);
 | 
	
		
			
				|  |  | +            ptProfit.setPtTotalAdd(ptProfit.getPtTotalAdd() + total);
 | 
	
		
			
				|  |  | +            ptProfit.setPtGrossAdd(ptProfit.getPtGrossAdd() + grossAdd);
 | 
	
		
			
				|  |  | +            PtProfitSaveReqVO ptProfitSaveReqVO2 = PtProfitSaveReqVO.builder()
 | 
	
		
			
				|  |  | +                    .id(ptProfitDO.getId())
 | 
	
		
			
				|  |  | +                    .ptTotalAdd(ptProfit.getPtTotalAdd())
 | 
	
		
			
				|  |  | +                    .ptAdd(ptProfit.getPtAdd())
 | 
	
		
			
				|  |  | +                    .ptGrossAdd(ptProfit.getPtGrossAdd()).build();
 | 
	
		
			
				|  |  | +            ptProfitService.updatePtProfit(ptProfitSaveReqVO2);
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 信息整合
 | 
	
		
			
				|  |  | +        ptProfitLogService.saveBatch(ptProfitLogSaveReqVOS);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 在用户获取直推奖的时候溢出的需要加入到平台,并记录log
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private void calcIntegral(List<PtProfitSaveReqVO> ptProfitSaveReqVOS, PtProfitSaveReqVO ptProfitSaveReqVO
 | 
	
		
			
				|  |  | +            , Long ancestorQuotaInt, Long orderId, String orderNo) {
 | 
	
		
			
				|  |  | +        ptProfitSaveReqVO.setPtGrossAdd(ptProfitSaveReqVO.getPtGrossAdd() + ancestorQuotaInt);
 | 
	
		
			
				|  |  | +        ptProfitSaveReqVO.setPtTotalAdd(ptProfitSaveReqVO.getPtGrossAdd() + ptProfitSaveReqVO.getPtAdd());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        PtProfitLogSaveReqVO ptProfitLog = PtProfitLogSaveReqVO.builder()
 | 
	
		
			
				|  |  | +                .orderId(orderId)
 | 
	
		
			
				|  |  | +                .profitStatus(CaclEnum.GROSS_PROFIT_ANCESTOR_QUOTA_PERC_EXCEED_MAXIMUM_LIMIT.getType())
 | 
	
		
			
				|  |  | +                .orderNo(orderNo)
 | 
	
		
			
				|  |  | +                .amount(ancestorQuotaInt)
 | 
	
		
			
				|  |  | +                .afterAmount(ptProfitSaveReqVOS.stream().mapToLong(PtProfitSaveReqVO::getPtGrossAdd).sum() + ancestorQuotaInt)
 | 
	
		
			
				|  |  | +                .build();
 | 
	
		
			
				|  |  | +        ptProfitLogService.createPtProfitLog(ptProfitLog);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /**
 | 
	
		
			
				|  |  | +     * 修改用户钱包
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param integralDO         当前用户钱包
 | 
	
		
			
				|  |  | +     * @param integralDOAncestor 推荐人钱包
 | 
	
		
			
				|  |  | +     * @param pt                 pt钱包
 | 
	
		
			
				|  |  | +     * @param ancestorQuota      推荐人额度
 | 
	
		
			
				|  |  | +     * @param descendantQuota    直推人额度
 | 
	
		
			
				|  |  | +     * @param highQuota          最大可用额度
 | 
	
		
			
				|  |  | +     * @param ptA                pt收益
 | 
	
		
			
				|  |  | +     * @param ptB                pt服务费
 | 
	
		
			
				|  |  | +     * @param ptReplenish        超出没有获取到的积分
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    private void changeUserWallet(IntegralDO integralDO, IntegralDO integralDOAncestor, IntegralDO pt,
 | 
	
		
			
				|  |  | +                                  Long ancestorQuota, Long descendantQuota, Long highQuota, Long ptA, Long ptB, Long ptReplenish) {
 | 
	
		
			
				|  |  | +        // 修改用户钱包
 | 
	
		
			
				|  |  | +        // 增加直推人额度
 | 
	
		
			
				|  |  | +        integralDO.setHighQuota(integralDO.getHighQuota() + highQuota);
 | 
	
		
			
				|  |  | +        //增加累计峰值
 | 
	
		
			
				|  |  | +        integralDO.setHighQuotaTotal(integralDO.getHighQuotaTotal() + highQuota);
 | 
	
		
			
				|  |  | +        integralDO.setFreezeHighQuota(integralDO.getFreezeHighQuota() - highQuota);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        integralDO.setCurrentQuota(integralDO.getCurrentQuota() + descendantQuota);
 | 
	
		
			
				|  |  | +        integralDO.setFreezeQuota(integralDO.getFreezeQuota() - descendantQuota);
 | 
	
		
			
				|  |  | +        // 增加推荐人额度
 | 
	
		
			
				|  |  | +        integralDOAncestor.setCurrentQuota(integralDOAncestor.getCurrentQuota() + ancestorQuota);
 | 
	
		
			
				|  |  | +        // 减少推荐人的可获取额度
 | 
	
		
			
				|  |  | +        integralDOAncestor.setHighQuota(integralDOAncestor.getHighQuota() - ancestorQuota);
 | 
	
		
			
				|  |  | +        integralDOAncestor.setAncestorQuota(integralDOAncestor.getAncestorQuota() + ancestorQuota);
 | 
	
		
			
				|  |  | +        integralDOAncestor.setFreezeQuota(integralDOAncestor.getFreezeQuota() - ancestorQuota - ptReplenish);
 | 
	
		
			
				|  |  | +        integralService.updateIntegral(cn.newfeifan.mall.framework.common.util.object.BeanUtils.toBean(integralDOAncestor, IntegralSaveReqVO.class));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 增加平台额度
 | 
	
		
			
				|  |  | +        pt.setCurrentQuota(pt.getCurrentQuota() + ptA + ptB);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +//        integralSaveReqVOS.add(BeanUtils.toBean(integralDO, IntegralSaveReqVO.class));
 | 
	
		
			
				|  |  | +//        integralSaveReqVOS.add(BeanUtils.toBean(integralDOAncestor, IntegralSaveReqVO.class));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        integralService.updateIntegral(cn.newfeifan.mall.framework.common.util.object.BeanUtils.toBean(integralDO, IntegralSaveReqVO.class));
 | 
	
		
			
				|  |  | +        integralService.updateIntegral(cn.newfeifan.mall.framework.common.util.object.BeanUtils.toBean(pt, IntegralSaveReqVO.class));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 获取当前订单的下单人的直推关系
 | 
	
		
			
				|  |  | +    public SharePathDO getSharePath(Long userId) {
 | 
	
		
			
				|  |  | +        return sharePathService.getSharePathByDescendant(userId);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      @Transactional(rollbackFor = Exception.class)
 |