Sfoglia il codice sorgente

分销:根据商品,计算推广员可以得到的佣金

owen 1 anno fa
parent
commit
9856e17974

+ 10 - 0
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java

@@ -137,4 +137,14 @@ public class ProductSpuRespDTO {
      */
     private Integer clickCount;
 
+
+    // ========== 分销相关字段 =========
+
+    /**
+     * 分销类型
+     *
+     * false - 默认
+     * true - 自行设置
+     */
+    private Boolean subCommissionType;
 }

+ 1 - 9
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java

@@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBroke
 import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert;
 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO;
 import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService;
-import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.extern.slf4j.Slf4j;
@@ -31,8 +30,6 @@ import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLogi
 @Validated
 @Slf4j
 public class AppBrokerageRecordController {
-    @Resource
-    private BrokerageUserService brokerageUserService;
     @Resource
     private BrokerageRecordService brokerageRecordService;
 
@@ -45,15 +42,10 @@ public class AppBrokerageRecordController {
         return success(BrokerageRecordConvert.INSTANCE.convertPage02(pageResult));
     }
 
-    // TODO @疯狂:这里还有一个漏网之鱼~
     @GetMapping("/get-product-brokerage-price")
     @Operation(summary = "获得商品的分销金额")
     public CommonResult<AppBrokerageProductPriceRespVO> getProductBrokeragePrice(@RequestParam("spuId") Long spuId) {
-        AppBrokerageProductPriceRespVO respVO = new AppBrokerageProductPriceRespVO();
-        respVO.setEnabled(brokerageUserService.getUserBrokerageEnabled(getLoginUserId()));
-        respVO.setBrokerageMinPrice(1);
-        respVO.setBrokerageMaxPrice(2);
-        return success(respVO);
+        return success(brokerageRecordService.calculateProductBrokeragePrice(spuId, getLoginUserId()));
     }
 
 }

+ 10 - 3
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.trade.convert.order;
 
+import cn.hutool.core.util.BooleanUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
@@ -14,6 +15,7 @@ import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDT
 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
+import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
 import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
 import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
@@ -266,11 +268,16 @@ public interface TradeOrderConvert {
 
     TradeOrderDO convert(TradeOrderRemarkReqVO reqVO);
 
-    default BrokerageAddReqBO convert(MemberUserRespDTO user, TradeOrderItemDO item, ProductSkuRespDTO sku) {
-        return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId())
+    default BrokerageAddReqBO convert(MemberUserRespDTO user, TradeOrderItemDO item,
+                                      ProductSpuRespDTO spu, ProductSkuRespDTO sku) {
+        BrokerageAddReqBO bo = new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId())
                 .setBasePrice(item.getPayPrice() * item.getCount())
                 .setTitle(StrUtil.format("{}成功购买{}", user.getNickname(), item.getSpuName()))
-                .setFirstFixedPrice(sku.getFirstBrokeragePrice()).setSecondFixedPrice(sku.getSecondBrokeragePrice());
+                .setFirstFixedPrice(0).setSecondFixedPrice(0);
+        if (BooleanUtil.isTrue(spu.getSubCommissionType())) {
+            bo.setFirstFixedPrice(sku.getFirstBrokeragePrice()).setSecondFixedPrice(sku.getSecondBrokeragePrice());
+        }
+        return bo;
     }
 
     TradeBeforeOrderCreateReqBO convert(AppTradeOrderCreateReqVO createReqVO);

+ 9 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.service.brokerage;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageProductPriceRespVO;
 import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO;
 import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO;
@@ -110,4 +111,12 @@ public interface BrokerageRecordService {
      */
     Integer getUserRankByPrice(Long userId, LocalDateTime[] times);
 
+    /**
+     * 计算商品被购买后,推广员可以得到的佣金
+     *
+     * @param spuId  商品编号
+     * @param userId 用户编号
+     * @return 用户佣金
+     */
+    AppBrokerageProductPriceRespVO calculateProductBrokeragePrice(Long spuId, Long userId);
 }

+ 58 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.trade.service.brokerage;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.BooleanUtil;
 import cn.hutool.core.util.ObjectUtil;
@@ -9,7 +10,12 @@ import cn.hutool.extra.spring.SpringUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
+import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
+import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
+import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
+import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO;
+import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageProductPriceRespVO;
 import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO;
 import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO;
 import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert;
@@ -36,6 +42,9 @@ import java.util.Objects;
 import java.util.Optional;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMaxValue;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getMinValue;
+import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH;
 
 /**
@@ -55,6 +64,11 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
     @Resource
     private BrokerageUserService brokerageUserService;
 
+    @Resource
+    private ProductSpuApi productSpuApi;
+    @Resource
+    private ProductSkuApi productSkuApi;
+
     @Override
     public BrokerageRecordDO getBrokerageRecord(Integer id) {
         return brokerageRecordMapper.selectById(id);
@@ -293,6 +307,50 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
         return true;
     }
 
+    @Override
+    public AppBrokerageProductPriceRespVO calculateProductBrokeragePrice(Long spuId, Long userId) {
+        // 1. 构建默认的返回值
+        AppBrokerageProductPriceRespVO respVO = new AppBrokerageProductPriceRespVO().setEnabled(false)
+                .setBrokerageMinPrice(0).setBrokerageMaxPrice(0);
+
+        // 2.1 校验分销功能是否开启
+        TradeConfigDO tradeConfig = tradeConfigService.getTradeConfig();
+        if (tradeConfig == null || !BooleanUtil.isTrue(tradeConfig.getBrokerageEnabled())) {
+            return respVO;
+        }
+
+        // 2.2 校验用户是否有分销资格
+        respVO.setEnabled(brokerageUserService.getUserBrokerageEnabled(getLoginUserId()));
+        if (!BooleanUtil.isTrue(respVO.getEnabled())) {
+            return respVO;
+        }
+
+        Integer fixedMinPrice = 0;
+        Integer fixedMaxPrice = 0;
+        Integer spuMinPrice = 0;
+        Integer spuMaxPrice = 0;
+        // 2.3 校验商品是否存在
+        ProductSpuRespDTO spu = productSpuApi.getSpu(spuId);
+        if (spu == null) {
+            return respVO;
+        }
+
+        List<ProductSkuRespDTO> skuList = productSkuApi.getSkuListBySpuId(ListUtil.of(spuId));
+        if (BooleanUtil.isTrue(spu.getSubCommissionType())) {
+            // 3.1 商品单独分佣模式
+            fixedMinPrice = getMinValue(skuList, ProductSkuRespDTO::getFirstBrokeragePrice);
+            fixedMaxPrice = getMaxValue(skuList, ProductSkuRespDTO::getFirstBrokeragePrice);
+        } else {
+            // 3.2 全局分佣模式(根据商品价格比例计算)
+            spuMinPrice = getMinValue(skuList, ProductSkuRespDTO::getPrice);
+            spuMaxPrice = getMaxValue(skuList, ProductSkuRespDTO::getPrice);
+        }
+
+        respVO.setBrokerageMinPrice(calculatePrice(spuMinPrice, tradeConfig.getBrokerageFirstPercent(), fixedMinPrice));
+        respVO.setBrokerageMaxPrice(calculatePrice(spuMaxPrice, tradeConfig.getBrokerageFirstPercent(), fixedMaxPrice));
+        return respVO;
+    }
+
     /**
      * 获得自身的代理对象,解决 AOP 生效问题
      *

+ 2 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java

@@ -849,7 +849,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         // 每一个订单项,都会去生成分销记录
         List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(orderId);
         List<BrokerageAddReqBO> addList = convertList(orderItems,
-                item -> TradeOrderConvert.INSTANCE.convert(user, item, productSkuApi.getSku(item.getSkuId())));
+                item -> TradeOrderConvert.INSTANCE.convert(user, item,
+                        productSpuApi.getSpu(item.getSpuId()), productSkuApi.getSku(item.getSkuId())));
         brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, addList);
     }