mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-01 02:38:43 +08:00 
			
		
		
		
	code review:分销逻辑
This commit is contained in:
		| @@ -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); | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -6,6 +6,7 @@ import lombok.Getter; | ||||
|  | ||||
| import java.util.Arrays; | ||||
|  | ||||
| // TODO @疯狂:是不是搞成层级,类似 level 这样?因为本质上,它是 1 级、2 级、3 级这样的关系哈 | ||||
| /** | ||||
|  * 分销用户类型枚举 | ||||
|  * | ||||
|   | ||||
| @@ -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)); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -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") | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
|   | ||||
| @@ -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()); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|  | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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,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; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
|         } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV