瀏覽代碼

code review:分销逻辑

YunaiV 1 年之前
父節點
當前提交
82c6354e1d
共有 13 個文件被更改,包括 46 次插入32 次删除
  1. 6 1
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApi.java
  2. 1 0
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageUserTypeEnum.java
  3. 2 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/BrokerageRecordController.java
  4. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserMySummaryRespVO.java
  5. 0 3
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java
  6. 6 6
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/user/BrokerageUserConvert.java
  7. 3 5
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
  8. 2 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/record/BrokerageRecordDO.java
  9. 3 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/record/BrokerageRecordMapper.java
  10. 5 3
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/user/BrokerageUserMapper.java
  11. 5 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/BrokerageAddReqBO.java
  12. 10 6
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordServiceImpl.java
  13. 2 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java

+ 6 - 1
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApi.java

@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserDTO;
 import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
 
+// TODO @疯狂:是不是不需要这个啦?
 /**
  * 分销 API 接口
  *
@@ -31,6 +32,7 @@ public interface BrokerageApi {
      */
     default boolean bindUser(@NotNull Long userId, @NotNull Long bindUserId, @NotNull LocalDateTime registerTime) {
         // 注册时间在30秒内的,都算新用户
+        // TODO @疯狂:这个要不抽到 service 里哈?
         boolean isNewUser = LocalDateTimeUtils.afterNow(registerTime.minusSeconds(30));
         return bindUser(userId, bindUserId, isNewUser);
     }
@@ -43,5 +45,8 @@ public interface BrokerageApi {
      * @param isNewUser  是否为新用户
      * @return 是否绑定
      */
-    boolean bindUser(@NotNull Long userId, @NotNull Long bindUserId, @NotNull Boolean isNewUser);
+    boolean bindUser(@NotNull(message = "用户编号不能为空") Long userId,
+                     @NotNull(message = "推广员编号不能为空") Long bindUserId,
+                     @NotNull Boolean isNewUser);
+
 }

+ 1 - 0
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageUserTypeEnum.java

@@ -6,6 +6,7 @@ import lombok.Getter;
 
 import java.util.Arrays;
 
+// TODO @疯狂:是不是搞成层级,类似 level 这样?因为本质上,它是 1 级、2 级、3 级这样的关系哈
 /**
  * 分销用户类型枚举
  *

+ 2 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/BrokerageRecordController.java

@@ -55,10 +55,11 @@ public class BrokerageRecordController {
     public CommonResult<PageResult<BrokerageRecordRespVO>> getBrokerageRecordPage(@Valid BrokerageRecordPageReqVO pageVO) {
         PageResult<BrokerageRecordDO> pageResult = brokerageRecordService.getBrokerageRecordPage(pageVO);
 
+        // 查询用户信息
         Set<Long> userIds = convertSet(pageResult.getList(), BrokerageRecordDO::getUserId);
         userIds.addAll(convertList(pageResult.getList(), BrokerageRecordDO::getSourceUserId));
         Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(userIds);
-
+        // 拼接数据
         return success(BrokerageRecordConvert.INSTANCE.convertPage(pageResult, userMap));
     }
 

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserMySummaryRespVO.java

@@ -19,7 +19,7 @@ public class AppBrokerageUserMySummaryRespVO {
     @Schema(description = "冻结的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "234")
     private Integer frozenPrice;
 
-    @Schema(description = "分销用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
+    @Schema(description = "分销用户数量(一级)", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
     private Integer firstBrokerageUserCount;
 
     @Schema(description = "分销用户数量(二级)", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")

+ 0 - 3
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java

@@ -52,15 +52,12 @@ public interface BrokerageRecordConvert {
 
     default PageResult<BrokerageRecordRespVO> convertPage(PageResult<BrokerageRecordDO> pageResult, Map<Long, MemberUserRespDTO> userMap) {
         PageResult<BrokerageRecordRespVO> result = convertPage(pageResult);
-
         for (BrokerageRecordRespVO respVO : result.getList()) {
             Optional.ofNullable(userMap.get(respVO.getUserId())).ifPresent(user ->
                     respVO.setUserNickname(user.getNickname()).setUserAvatar(user.getAvatar()));
-
             Optional.ofNullable(userMap.get(respVO.getSourceUserId())).ifPresent(user ->
                     respVO.setSourceUserNickname(user.getNickname()).setSourceUserAvatar(user.getAvatar()));
         }
-
         return result;
     }
 }

+ 6 - 6
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/user/BrokerageUserConvert.java

@@ -35,18 +35,18 @@ public interface BrokerageUserConvert {
                                                         Map<Long, Long> brokerageUserCountMap,
                                                         Map<Long, UserBrokerageSummaryBO> userOrderSummaryMap) {
         PageResult<BrokerageUserRespVO> result = convertPage(pageResult);
-        for (BrokerageUserRespVO vo : result.getList()) {
+        for (BrokerageUserRespVO userVO : result.getList()) {
             // 用户信息
-            copyTo(userMap.get(vo.getId()), vo);
+            copyTo(userMap.get(userVO.getId()), userVO);
 
             // 推广用户数量
-            vo.setBrokerageUserCount(MapUtil.getInt(brokerageUserCountMap, vo.getId(), 0));
+            userVO.setBrokerageUserCount(MapUtil.getInt(brokerageUserCountMap, userVO.getId(), 0));
             // 推广订单数量、推广订单金额
-            Optional<UserBrokerageSummaryBO> orderSummaryOptional = Optional.ofNullable(userOrderSummaryMap.get(vo.getId()));
-            vo.setBrokerageOrderCount(orderSummaryOptional.map(UserBrokerageSummaryBO::getCount).orElse(0))
+            Optional<UserBrokerageSummaryBO> orderSummaryOptional = Optional.ofNullable(userOrderSummaryMap.get(userVO.getId()));
+            userVO.setBrokerageOrderCount(orderSummaryOptional.map(UserBrokerageSummaryBO::getCount).orElse(0))
                     .setBrokerageOrderPrice(orderSummaryOptional.map(UserBrokerageSummaryBO::getPrice).orElse(0));
             // todo 已提现次数、已提现金额
-            vo.setWithdrawCount(0).setWithdrawPrice(0);
+            userVO.setWithdrawCount(0).setWithdrawPrice(0);
         }
         return result;
     }

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

@@ -279,11 +279,9 @@ public interface TradeOrderConvert {
     TradeOrderDO convert(TradeOrderRemarkReqVO reqVO);
 
     default BrokerageAddReqBO convert(TradeOrderItemDO item, ProductSkuRespDTO sku) {
-        return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId()))
-                .setSourceUserId(item.getUserId())
+        return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId())
                 .setBasePrice(item.getPayPrice() * item.getCount())
-                .setFirstFixedPrice(sku.getSubCommissionFirstPrice())
-                .setSecondFixedPrice(sku.getSubCommissionSecondPrice())
-                .setTitle(BrokerageRecordBizTypeEnum.ORDER.getTitle());
+                .setTitle(BrokerageRecordBizTypeEnum.ORDER.getTitle()) // TODO @疯狂:标题类似:木晴冰雪成功购买云时代的JVM原理与实战;茫农成功购买深入拆解消息队列47讲
+                .setFirstFixedPrice(sku.getSubCommissionFirstPrice()).setSecondFixedPrice(sku.getSubCommissionSecondPrice());
     }
 }

+ 2 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/record/BrokerageRecordDO.java

@@ -85,13 +85,13 @@ public class BrokerageRecordDO extends BaseDO {
     /**
      * 来源用户类型
      * <p>
-     * 枚举 {@link BrokerageUserTypeEnum}
+     * 枚举 {@link BrokerageUserTypeEnum},被推广用户和 {@link #userId} 的推广层级关系
      */
     private Integer sourceUserType;
     /**
      * 来源用户编号
      * <p>
-     * 关联 MemberUserDO.id
+     * 关联 MemberUserDO.id 字段,被推广用户的编号
      */
     private Long sourceUserId;
 

+ 3 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/record/BrokerageRecordMapper.java

@@ -26,7 +26,7 @@ public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> {
     default PageResult<BrokerageRecordDO> selectPage(BrokerageRecordPageReqVO reqVO) {
         boolean sourceUserTypeCondition = reqVO.getSourceUserType() != null &&
                 !BrokerageUserTypeEnum.ALL.getType().equals(reqVO.getSourceUserType());
-
+        // 分页查询
         return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageRecordDO>()
                 .eqIfPresent(BrokerageRecordDO::getUserId, reqVO.getUserId())
                 .eqIfPresent(BrokerageRecordDO::getBizType, reqVO.getBizType())
@@ -54,7 +54,8 @@ public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> {
                 BrokerageRecordDO::getUserId, userId);
     }
 
-    @Select("SELECT COUNT(1), SUM(price) FROM trade_brokerage_record WHERE user_id = #{userId} AND biz_type = #{bizType} AND status = #{status}")
+    @Select("SELECT COUNT(1), SUM(price) FROM trade_brokerage_record " +
+            "WHERE user_id = #{userId} AND biz_type = #{bizType} AND status = #{status}")
     UserBrokerageSummaryBO selectCountAndSumPriceByUserIdAndBizTypeAndStatus(@Param("userId") Long userId,
                                                                              @Param("bizType") Integer bizType,
                                                                              @Param("status") Integer status);

+ 5 - 3
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/user/BrokerageUserMapper.java

@@ -36,8 +36,9 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
         } else if (BrokerageUserTypeEnum.SECOND.getType().equals(reqVO.getUserType())) {
             buildSecondBindUserCondition(reqVO.getBindUserId(), wrapper);
         } else {
+            // TODO @疯狂:要不要把这个逻辑,挪到 Service 里,算出子用户有哪些,然后 IN?
             buildFirstBindUserCondition(reqVO.getBindUserId(), wrapper);
-            buildSecondBindUserCondition(reqVO.getBindUserId(), wrapper.or());
+            buildSecondBindUserCondition(reqVO.getBindUserId(), wrapper.or()); // 通过 or 实现多个条件
         }
     }
 
@@ -45,8 +46,8 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
         wrapper.eq(BrokerageUserDO::getBindUserId, bindUserId);
     }
 
-    static void buildSecondBindUserCondition(Long bindUserId, LambdaQueryWrapper<BrokerageUserDO> w) {
-        w.inSql(BrokerageUserDO::getBindUserId, StrUtil.format("SELECT id FROM trade_brokerage_user WHERE bind_user_id = {}", bindUserId));
+    static void buildSecondBindUserCondition(Long bindUserId, LambdaQueryWrapper<BrokerageUserDO> wrapper) {
+        wrapper.inSql(BrokerageUserDO::getBindUserId, StrUtil.format("SELECT id FROM trade_brokerage_user WHERE bind_user_id = {}", bindUserId));
     }
 
     /**
@@ -142,4 +143,5 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
 
     @Select("SELECT COUNT(1) from trade_brokerage_user WHERE bind_user_id IN (SELECT id FROM trade_brokerage_user WHERE bind_user_id = #{bindUserId})")
     Long selectCountByBindUserIdInBindUserId(Long bindUserId);
+
 }

+ 5 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/BrokerageAddReqBO.java

@@ -5,6 +5,7 @@ import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
 import javax.validation.constraints.NotNull;
 
 /**
@@ -30,6 +31,7 @@ public class BrokerageAddReqBO {
     /**
      * 一级佣金(固定)
      */
+    @NotNull(message = "一级佣金(固定)不能为空")
     private Integer firstFixedPrice;
     /**
      * 二级佣金(固定)
@@ -39,10 +41,13 @@ public class BrokerageAddReqBO {
     /**
      * 来源用户编号
      */
+    @NotNull(message = "来源用户编号不能为空")
     private Long sourceUserId;
 
     /**
      * 佣金记录标题
      */
+    @NotEmpty(message = "佣金记录标题不能为空")
     private String title;
+
 }

+ 10 - 6
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordServiceImpl.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.service.brokerage.record;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.BooleanUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.spring.SpringUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
@@ -154,21 +155,24 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
         int totalBrokerage = 0;
         List<BrokerageRecordDO> records = new ArrayList<>();
         for (BrokerageAddReqBO item : list) {
-            Integer fixedPrice = 0;
+            // 计算金额
+            Integer fixedPrice;
             if (BrokerageUserTypeEnum.FIRST.equals(sourceUserType)) {
                 fixedPrice = item.getFirstFixedPrice();
             } else if (BrokerageUserTypeEnum.SECOND.equals(sourceUserType)) {
                 fixedPrice = item.getSecondFixedPrice();
+            } else {
+                throw new IllegalArgumentException(StrUtil.format("来源用户({}) 不合法", sourceUserType));
             }
-
-            int brokeragePerItem = calculatePrice(item.getBasePrice(), brokeragePercent, fixedPrice);
-            if (brokeragePerItem <= 0) {
+            int brokeragePrice = calculatePrice(item.getBasePrice(), brokeragePercent, fixedPrice);
+            if (brokeragePrice <= 0) {
                 continue;
             }
+            totalBrokerage += brokeragePrice;
+            // 创建记录实体
             records.add(BrokerageRecordConvert.INSTANCE.convert(user, bizType, item.getBizId(),
-                    brokerageFrozenDays, brokeragePerItem, unfreezeTime, item.getTitle(),
+                    brokerageFrozenDays, brokeragePrice, unfreezeTime, item.getTitle(),
                     item.getSourceUserId(), sourceUserType.getType()));
-            totalBrokerage += brokeragePerItem;
         }
         if (CollUtil.isEmpty(records)) {
             return;

+ 2 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java

@@ -134,7 +134,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
     @Override
     public Long getBrokerageUserCountByBindUserId(Long bindUserId, BrokerageUserTypeEnum userType) {
         switch (userType) {
-            case ALL:
+            case ALL: // TODO @疯狂:ALL 是不是不用搞个枚举,默认为空就是不过滤哈~
                 Long firstCount = brokerageUserMapper.selectCountByBindUserId(bindUserId);
                 Long secondCount = brokerageUserMapper.selectCountByBindUserIdInBindUserId(bindUserId);
                 return firstCount + secondCount;
@@ -183,7 +183,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
     public Boolean getUserBrokerageEnabled(Long userId) {
         // 全局分销功能是否开启
         TradeConfigDO tradeConfig = tradeConfigService.getTradeConfig();
-        if (tradeConfig == null || !BooleanUtil.isTrue(tradeConfig.getBrokerageEnabled())) {
+        if (tradeConfig == null || BooleanUtil.isFalse(tradeConfig.getBrokerageEnabled())) {
             return false;
         }