|
@@ -12,10 +12,13 @@ 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.dal.dataobject.orderpercentage.OrderPercentageDO;
|
|
|
+import cn.newfeifan.mall.module.distri.dal.mysql.orderpercentage.OrderPercentageMapper;
|
|
|
import cn.newfeifan.mall.module.distri.enums.CaclEnum;
|
|
|
import cn.newfeifan.mall.module.distri.service.integral.IntegralService;
|
|
|
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;
|
|
|
import cn.newfeifan.mall.module.pay.api.order.PayOrderApi;
|
|
|
import cn.newfeifan.mall.module.pay.api.order.dto.PayOrderCreateReqDTO;
|
|
|
import cn.newfeifan.mall.module.pay.api.order.dto.PayOrderRespDTO;
|
|
@@ -24,6 +27,7 @@ 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.system.service.user.AdminUserService;
|
|
|
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;
|
|
@@ -57,6 +61,7 @@ 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.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.google.gson.Gson;
|
|
|
import com.google.gson.JsonObject;
|
|
|
import com.kuaidi100.sdk.api.Subscribe;
|
|
@@ -75,9 +80,11 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
import javax.annotation.Resource;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
+import java.text.DecimalFormat;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
import static cn.newfeifan.mall.framework.common.util.collection.CollectionUtils.*;
|
|
@@ -136,6 +143,15 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|
|
@Resource
|
|
|
private ProductSkuMapper productSkuMapper;
|
|
|
|
|
|
+ @Resource
|
|
|
+ private OrderPercentageMapper orderPercentageMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private MemberUserService memberUserService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private AdminUserService adminUserService;
|
|
|
+
|
|
|
// =================== Order ===================
|
|
|
|
|
|
@Override
|
|
@@ -1038,6 +1054,225 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public void initializationOrderItem() {
|
|
|
+ List<TradeOrderItemDO> tradeOrderItemDOS = tradeOrderItemMapper.selectList();
|
|
|
+ for (TradeOrderItemDO tradeOrderItemDO : tradeOrderItemDOS) {
|
|
|
+ ProductSkuDO productSkuDO = productSkuMapper.selectById(tradeOrderItemDO.getSkuId());
|
|
|
+ tradeOrderItemDO.setCostPrice(productSkuDO.getCostPrice());
|
|
|
+ tradeOrderItemDO.setPromotionFee(productSkuDO.getPromotionFee());
|
|
|
+
|
|
|
+ tradeOrderItemMapper.updateById(tradeOrderItemDO);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @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);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void sentWcChatMessage(TradeOrderDO order) {
|
|
|
+ List<String> params = new ArrayList<>();
|
|
|
+ DecimalFormat df = new DecimalFormat("0.00");
|
|
|
+ String formattedPrice = df.format((double) order.getPayPrice() / 100);
|
|
|
+
|
|
|
+ params.add("¥ " + formattedPrice);
|
|
|
+ params.add(order.getNo());
|
|
|
+ params.add(memberUserService.getUser(order.getUserId()).getNickname());
|
|
|
+
|
|
|
+ List<TradeOrderItemDO> tradeOrderItemDOS = tradeOrderItemMapper.selectListByOrderId(order.getId());
|
|
|
+ List<String> productNames = tradeOrderItemDOS.stream().map(TradeOrderItemDO::getSpuName).collect(Collectors.toList());
|
|
|
+ String name = productNames.toString();
|
|
|
+
|
|
|
+ // 去除首尾的括号,并去除空格
|
|
|
+ name = name.substring(1, name.length() - 1).trim();
|
|
|
+
|
|
|
+ params.add(name);
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
+ params.add(LocalDateTime.now().format(formatter));
|
|
|
+
|
|
|
+ List<Long> adminUsers = adminUserService.getUserIdsByShop(order.getShopId());
|
|
|
+ for (Long aUserId : adminUsers) {
|
|
|
+ //发送信息
|
|
|
+ wcChatMessageUtils.sendWcChatMessage(WcChatMessageTemplateIdEnum.ORDER_NO_DELIVERY2.getTemplateId(),
|
|
|
+ params, aUserId, order.getId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ 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);
|
|
|
}
|
|
@@ -1104,4 +1339,5 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|
|
return SpringUtil.getBean(getClass());
|
|
|
}
|
|
|
|
|
|
+
|
|
|
}
|