|
@@ -12,6 +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.framework.mybatis.core.query.LambdaQueryWrapperX;
|
|
|
+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.admin.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.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.pay.api.order.PayOrderApi;
|
|
@@ -20,6 +36,8 @@ import cn.newfeifan.mall.module.pay.api.order.dto.PayOrderRespDTO;
|
|
|
import cn.newfeifan.mall.module.pay.enums.order.PayOrderStatusEnum;
|
|
|
import cn.newfeifan.mall.module.product.api.comment.ProductCommentApi;
|
|
|
import cn.newfeifan.mall.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
|
|
+import cn.newfeifan.mall.module.product.dal.dataobject.sku.ProductSkuDO;
|
|
|
+import cn.newfeifan.mall.module.product.dal.mysql.sku.ProductSkuMapper;
|
|
|
import cn.newfeifan.mall.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO;
|
|
|
import cn.newfeifan.mall.module.trade.controller.admin.order.vo.TradeOrderRemarkReqVO;
|
|
|
import cn.newfeifan.mall.module.trade.controller.admin.order.vo.TradeOrderUpdateAddressReqVO;
|
|
@@ -52,6 +70,7 @@ import cn.newfeifan.mall.module.trade.service.price.bo.TradePriceCalculateReqBO;
|
|
|
import cn.newfeifan.mall.module.trade.service.price.bo.TradePriceCalculateRespBO;
|
|
|
import cn.newfeifan.mall.module.trade.service.price.calculator.TradePriceCalculatorHelper;
|
|
|
import cn.newfeifan.mall.module.trade.utils.wechat.WcChatMessageUtils;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.google.gson.Gson;
|
|
|
import com.google.gson.JsonObject;
|
|
|
import com.kuaidi100.sdk.api.Subscribe;
|
|
@@ -64,16 +83,17 @@ import com.kuaidi100.sdk.request.SubscribeReq;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
+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.time.LocalDateTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Objects;
|
|
|
-import java.util.Set;
|
|
|
+import java.util.*;
|
|
|
|
|
|
import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
import static cn.newfeifan.mall.framework.common.util.collection.CollectionUtils.*;
|
|
@@ -97,6 +117,20 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|
|
@Resource
|
|
|
private TradeOrderItemMapper tradeOrderItemMapper;
|
|
|
@Resource
|
|
|
+ private PtProfitService ptProfitService;
|
|
|
+ @Resource
|
|
|
+ private PtProfitLogService ptProfitLogService;
|
|
|
+ @Resource
|
|
|
+ private IntegralService integralService;
|
|
|
+ @Resource
|
|
|
+ @Lazy
|
|
|
+ private DuserService duserService;
|
|
|
+ @Resource
|
|
|
+ @Lazy
|
|
|
+ private SharePathService sharePathService;
|
|
|
+ @Resource
|
|
|
+ private ProductSkuMapper productSkuMapper;
|
|
|
+ @Resource
|
|
|
private TradeNoRedisDAO tradeNoRedisDAO;
|
|
|
|
|
|
@Resource
|
|
@@ -126,6 +160,9 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|
|
@Value("${feifan.trade.express.kd100.key}")
|
|
|
private String key;
|
|
|
|
|
|
+ @Resource
|
|
|
+ private OrderPercentageMapper orderPercentageMapper;
|
|
|
+
|
|
|
// =================== Order ===================
|
|
|
|
|
|
@Override
|
|
@@ -959,6 +996,489 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|
|
tradeOrderMapper.updateById(order);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_PAY)
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void updateOrderPaid(Long payOrderId) {
|
|
|
+ //查询订单提成比例
|
|
|
+ QueryWrapper<OrderPercentageDO> queryWrapper = new QueryWrapper<>();
|
|
|
+ OrderPercentageDO orderPercentageDO = orderPercentageMapper.selectOne(queryWrapper);//表中只有一条记录
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 毛利 = 成本 * 0.38... (推广费用)
|
|
|
+ */
|
|
|
+ String grossProfitPerc = orderPercentageDO.getGrossProfitPerc();
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 购物本人自得 百分比
|
|
|
+ */
|
|
|
+ String grossProfitUserQuotaPerc = orderPercentageDO.getGrossProfitUserQuotaPerc();
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 推荐人(上一级) 百分比
|
|
|
+ */
|
|
|
+ String grossProfitAncestorQuotaPerc = orderPercentageDO.getGrossProfitAncestorQuotaPerc();
|
|
|
+
|
|
|
+ //add by Ben 根据支付订单id,查询所有 支付订单 对应的 订单
|
|
|
+ List<TradeOrderDO> TradeOrderDOList = tradeOrderMapper.selectList("pay_order_id", payOrderId);
|
|
|
+
|
|
|
+ //购物者ID
|
|
|
+ Long memberUserIdOfTradeOrder = TradeOrderDOList.get(0).getUserId();
|
|
|
+ //20240604 推荐人(上级用户ID)
|
|
|
+ Long ancesterUserId = tradeOrderMapper.selectAncesterByMemberUserId(memberUserIdOfTradeOrder);
|
|
|
+
|
|
|
+ for (TradeOrderDO tradeOrderDO : TradeOrderDOList) {
|
|
|
+
|
|
|
+ Long tradeOrderId = tradeOrderDO.getId();
|
|
|
+
|
|
|
+// System.out.println("#########updateOrderPaid####tradeOrderId:"+tradeOrderId);
|
|
|
+
|
|
|
+ // 1. 校验并获得交易订单(可支付)
|
|
|
+ KeyValue<TradeOrderDO, PayOrderRespDTO> orderResult = validateOrderPayable(tradeOrderId, payOrderId);
|
|
|
+
|
|
|
+ TradeOrderDO order = orderResult.getKey();
|
|
|
+ PayOrderRespDTO payOrder = orderResult.getValue();
|
|
|
+
|
|
|
+ // 2. 更新 TradeOrderDO 状态为已支付,等待发货
|
|
|
+ int updateCount = tradeOrderMapper.updateByIdAndStatus(tradeOrderId, order.getStatus(),
|
|
|
+ new TradeOrderDO().setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()).setPayStatus(true)
|
|
|
+ .setPayTime(LocalDateTime.now()).setPayChannelCode(payOrder.getChannelCode()));
|
|
|
+
|
|
|
+// System.out.println("#########updateOrderPaid####updateCount:"+updateCount);
|
|
|
+
|
|
|
+ if (updateCount == 0) {
|
|
|
+ throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID);
|
|
|
+ }
|
|
|
+
|
|
|
+ //注释 by Ben ,下面是系统原来的营销部分,和我们业务对不上,注释掉
|
|
|
+ // 3. 执行 TradeOrderHandler 的后置处理
|
|
|
+// List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(tradeOrderId);
|
|
|
+
|
|
|
+ //注释 by Ben ,下面是系统原来的营销部分,和我们业务对不上,注释掉
|
|
|
+// tradeOrderHandlers.forEach(handler -> handler.afterPayOrder(order, orderItems));
|
|
|
+
|
|
|
+ // 4. 记录订单日志
|
|
|
+ TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.UNDELIVERED.getStatus());
|
|
|
+ TradeOrderLogUtils.setUserInfo(order.getUserId(), UserTypeEnum.MEMBER.getValue());
|
|
|
+
|
|
|
+
|
|
|
+ // 5. 增加用户冻结积分 20240420
|
|
|
+
|
|
|
+
|
|
|
+ List<Long> skuList = new ArrayList<>();
|
|
|
+ //汇总各订单项利润
|
|
|
+ List<TradeOrderItemDO> TradeOrderItemList = tradeOrderItemMapper.selectList("order_id", order.getId());
|
|
|
+ for (TradeOrderItemDO tradeOrderItemDO : TradeOrderItemList) {
|
|
|
+ Long skuId = tradeOrderItemDO.getSkuId();
|
|
|
+ skuList.add(skuId);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<ProductSkuDO> productSkuDOS = productSkuMapper.selectBatchIds(skuList);
|
|
|
+ Map<Long, ProductSkuDO> skuDOMap = new HashMap<>();
|
|
|
+ for (ProductSkuDO productSkuDO : productSkuDOS) {
|
|
|
+ skuDOMap.put(productSkuDO.getId(), productSkuDO);
|
|
|
+ }
|
|
|
+
|
|
|
+ Long totalFreezeAmount = 0L;//用户总的冻结积分
|
|
|
+
|
|
|
+ Long totalAncestorFreezeAmount = 0L;//推荐人总的冻结积分
|
|
|
+
|
|
|
+ Long totalFreezeHighQuota = 0L;//冻结峰值
|
|
|
+
|
|
|
+ for (TradeOrderItemDO tradeOrderItemDO : TradeOrderItemList) {
|
|
|
+ ProductSkuDO productSkuDO = skuDOMap.get(tradeOrderItemDO.getSkuId());
|
|
|
+ //这类商品的总推广费
|
|
|
+ Integer promotionExpenses = (productSkuDO.getPrice() - productSkuDO.getCostPrice())
|
|
|
+ * tradeOrderItemDO.getCount();
|
|
|
+
|
|
|
+ //把商品项的推广费,转换为这项商品直推人获得的冻结积分
|
|
|
+ Long itemFreezeAmount =
|
|
|
+ promotionExpenses2GrossProfitAncestorQuota(promotionExpenses,
|
|
|
+ grossProfitPerc,//毛利 = 成本 * 0.38... (推广费用)
|
|
|
+ grossProfitUserQuotaPerc//消费者自得额度 百分比
|
|
|
+ );
|
|
|
+
|
|
|
+
|
|
|
+ //把商品项的推广费,转换为这项商品推荐人(上级)获得的冻结积分
|
|
|
+ Long ancestorItemFreezeAmount =
|
|
|
+ promotionExpenses2GrossProfitAncestorQuota(promotionExpenses,
|
|
|
+ grossProfitPerc,//毛利 = 成本 * 0.38... (推广费用)
|
|
|
+ grossProfitAncestorQuotaPerc//消费者自得额度 百分比
|
|
|
+ );
|
|
|
+
|
|
|
+ //峰值为毛利的十倍
|
|
|
+ BigDecimal grossProfit = new BigDecimal(promotionExpenses).multiply(new BigDecimal(grossProfitPerc)).setScale(4, RoundingMode.DOWN);
|
|
|
+ BigDecimal freezeHighQuota = grossProfit.multiply(new BigDecimal("10"));
|
|
|
+ freezeHighQuota = money2Integral(freezeHighQuota);
|
|
|
+ Long freezeHighQuotaInt = freezeHighQuota.longValue();
|
|
|
+
|
|
|
+ totalFreezeAmount += itemFreezeAmount;
|
|
|
+ totalAncestorFreezeAmount += ancestorItemFreezeAmount;
|
|
|
+ totalFreezeHighQuota += freezeHighQuotaInt;
|
|
|
+
|
|
|
+ //记录用户在此订单项获得的冻结积分
|
|
|
+ TradeOrderItemDO toid = new TradeOrderItemDO();
|
|
|
+ toid.setId(tradeOrderItemDO.getId());
|
|
|
+ toid.setIncreaseIntegral(itemFreezeAmount);
|
|
|
+ toid.setAncestorIncreaseIntegral(ancestorItemFreezeAmount);//20240504 add by Ben
|
|
|
+ toid.setFreezeHighQuota(freezeHighQuotaInt);
|
|
|
+ tradeOrderItemMapper.updateById(toid);
|
|
|
+ }
|
|
|
+
|
|
|
+ //把商品的推广费总额,转换为直推人获得的冻结积分
|
|
|
+// Integer freezeAmount = promotionExpenses2GrossProfitAncestorQuota(orderPercentageMapper,totalPromotionExpenses);
|
|
|
+
|
|
|
+ String OrderNum = order.getNo();
|
|
|
+ //修改购物者本人获得的冻结积分
|
|
|
+ integralService.updateUserIntegral(tradeOrderDO.getUserId(), tradeOrderDO.getUserId(), CaclEnum.ORDER_PAY_INTEGRAL_CONSUMER, 0L, totalFreezeAmount, tradeOrderId, OrderNum);
|
|
|
+
|
|
|
+ //修改推荐人(上级)获得的冻结积分
|
|
|
+ integralService.updateUserIntegral(tradeOrderDO.getUserId(), ancesterUserId, CaclEnum.ORDER_PAY_INTEGRAL_ANCESTER, 0L, totalAncestorFreezeAmount, tradeOrderId, OrderNum);
|
|
|
+
|
|
|
+ //修改购物者本人获得的冻结峰值
|
|
|
+ integralService.updateIntegralFreezeHighQuota(tradeOrderDO.getUserId(), tradeOrderDO.getUserId(), CaclEnum.ORDER_PAY_FREEZE_HIGH_QUOTA, totalFreezeHighQuota, tradeOrderId, OrderNum);
|
|
|
+ log.warn("[TradeOrderUpdateServiceImpl.updateOrderPaid]$$$:[tradeOrderId({}),ancesterUserId({}),totalAncestorFreezeAmount({})]" + new Date(),
|
|
|
+ tradeOrderId, ancesterUserId, totalAncestorFreezeAmount);
|
|
|
+
|
|
|
+ // 发送给微信消息给系统用户待发货消息
|
|
|
+// sentWcChatMessage(order);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 七天获得变为即算即得,后续如果恢复把这里注释即可,并打开平台定时任务得订单结算
|
|
|
+ calc(TradeOrderDOList, orderPercentageDO, JsonUtils.toJsonString(orderPercentageDO));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算订单支付成功后,订单项的冻结积分转换
|
|
|
+ *
|
|
|
+ * @param tradeOrderDOList 订单列表
|
|
|
+ * @param orderPercentageDO 参数百分比
|
|
|
+ * @param percentTemplate 计算百分比模板
|
|
|
+ */
|
|
|
+ private void calc(List<TradeOrderDO> tradeOrderDOList, OrderPercentageDO orderPercentageDO, String percentTemplate) {
|
|
|
+ // 平台收益日志
|
|
|
+ List<PtProfitLogSaveReqVO> ptProfitLogSaveReqVOS = new ArrayList<>();
|
|
|
+
|
|
|
+ // todo 修改用户身价 如何从订单中获取身价?
|
|
|
+ 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 = sharePathService.getSharePathByDescendant(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);
|
|
|
+ }
|
|
|
+
|
|
|
+ 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);
|
|
|
+ // todo 增加累计额度
|
|
|
+
|
|
|
+ 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);
|
|
|
+
|
|
|
+ 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 static Long promotionExpenses2GrossProfitAncestorQuota(
|
|
|
+ /*
|
|
|
+ 商品的推广费总额
|
|
|
+ */
|
|
|
+ Integer promotionExpenses,
|
|
|
+ /*
|
|
|
+ * 毛利 = 成本 * 0.38... (推广费用)
|
|
|
+ */
|
|
|
+ String grossProfitPerc,
|
|
|
+ /*
|
|
|
+ * 推广-推荐人/消费者本人额度 百分比
|
|
|
+ */
|
|
|
+ String grossProfitAncestorQuotaPerc
|
|
|
+ ) {
|
|
|
+
|
|
|
+ //转为BigDecimal
|
|
|
+ BigDecimal profit = new BigDecimal(String.valueOf(promotionExpenses));
|
|
|
+
|
|
|
+ // 计算毛利: 利润 * 0.38
|
|
|
+ BigDecimal grossProfit = profit.multiply(new BigDecimal(grossProfitPerc)).setScale(4, RoundingMode.DOWN);
|
|
|
+
|
|
|
+ // 计算直推人额度: 毛利 * 0.35
|
|
|
+ BigDecimal descendantQuota = grossProfit.multiply(new BigDecimal(grossProfitAncestorQuotaPerc)).setScale(4, RoundingMode.DOWN);
|
|
|
+
|
|
|
+ //把钱转为:增加的冻结积分
|
|
|
+ BigDecimal freezeAmount_bigDecimal = money2Integral(descendantQuota);
|
|
|
+
|
|
|
+ return freezeAmount_bigDecimal.longValue();
|
|
|
+ }
|
|
|
+
|
|
|
+ public static BigDecimal money2Integral(BigDecimal money) {
|
|
|
+ return money.multiply(DistriConstants.MONEY2INTEGRAL_BIG_DECIMAL);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 创建单个订单的评论
|
|
|
*
|