Browse Source

code review:优惠劵逻辑

YunaiV 1 year ago
parent
commit
9e3564bd6a
24 changed files with 110 additions and 65 deletions
  1. 1 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java
  2. 4 2
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponController.java
  3. 21 11
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java
  4. 1 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplatePageReqVO.java
  5. 1 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java
  6. 5 5
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java
  7. 6 5
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java
  8. 2 1
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java
  9. 2 3
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java
  10. 2 0
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/bo/CouponTakeCountBO.java
  11. 3 3
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageUserController.java
  12. 1 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java
  13. 6 6
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java
  14. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java
  15. 1 3
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserService.java
  16. 27 8
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java
  17. 7 6
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java
  18. 1 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java
  19. 2 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/UserBrokerageSummaryBO.java
  20. 0 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java
  21. 9 6
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
  22. 2 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java
  23. 4 0
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserPageReqVO.java
  24. 1 1
      yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java

+ 1 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplatePageReqVO.java

@@ -44,4 +44,5 @@ public class CouponTemplatePageReqVO extends PageParam {
 
     @Schema(description = "商品范围编号", example = "1")
     private Long productScopeValue;
+
 }

+ 4 - 2
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponController.java

@@ -41,13 +41,15 @@ public class AppCouponController {
     @Operation(summary = "领取优惠劵")
     @Parameter(name = "templateId", description = "优惠券模板编号", required = true, example = "1024")
     public CommonResult<Boolean> takeCoupon(@Valid @RequestBody AppCouponTakeReqVO reqVO) {
-        Long userId = getLoginUserId();
         // 领取
+        Long userId = getLoginUserId();
         couponService.takeCoupon(reqVO.getTemplateId(), CollUtil.newHashSet(userId), CouponTakeTypeEnum.USER);
+
         // 检查是否可以继续领取
         CouponTemplateDO couponTemplate = couponTemplateService.getCouponTemplate(reqVO.getTemplateId());
         boolean canTakeAgain = true;
         if (couponTemplate.getTakeLimitCount() != null && couponTemplate.getTakeLimitCount() > 0) {
+            // TODO @疯狂:要不要搞个 getTakeCount 方法?
             Integer takeCount = MapUtil.getInt(couponService.getTakeCountMapByTemplateIds(
                     Collections.singleton(reqVO.getTemplateId()), userId), reqVO.getTemplateId(), 0);
             canTakeAgain = takeCount < couponTemplate.getTakeLimitCount();
@@ -58,7 +60,7 @@ public class AppCouponController {
     @GetMapping("/match-list")
     @Operation(summary = "获得匹配指定商品的优惠劵列表")
     public CommonResult<List<AppCouponMatchRespVO>> getMatchCouponList(AppCouponMatchReqVO matchReqVO) {
-        // todo: 优惠金额倒序
+        // todo: 优化:优惠金额倒序
         return success(CouponConvert.INSTANCE.convertList(couponService.getMatchCouponList(getLoginUserId(), matchReqVO)));
     }
 

+ 21 - 11
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponTemplateController.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.controller.app.coupon;
 import cn.hutool.core.util.ObjUtil;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
 import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
 import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.template.AppCouponTemplatePageReqVO;
@@ -45,12 +46,14 @@ public class AppCouponTemplateController {
     @Operation(summary = "获得优惠劵模版分页")
     public CommonResult<PageResult<AppCouponTemplateRespVO>> getCouponTemplatePage(AppCouponTemplatePageReqVO pageReqVO) {
         // 1.1 处理查询条件:商品范围编号
-        Long productScopeValue = getaProductScopeValue(pageReqVO);
-        // 1.2 处理查询条件:领取方式=直接领取
+        Long productScopeValue = getProductScopeValue(pageReqVO);
+        // 1.2 处理查询条件:领取方式 = 直接领取
         List<Integer> canTakeTypes = Collections.singletonList(CouponTakeTypeEnum.USER.getValue());
+
         // 2. 分页查询
         PageResult<CouponTemplateDO> pageResult = couponTemplateService.getCouponTemplatePage(
                 CouponTemplateConvert.INSTANCE.convert(pageReqVO, canTakeTypes, pageReqVO.getProductScope(), productScopeValue));
+
         // 3.1 领取数量
         Map<Long, Integer> couponTakeCountMap = new HashMap<>(0);
         Long userId = getLoginUserId();
@@ -63,17 +66,24 @@ public class AppCouponTemplateController {
         return success(CouponTemplateConvert.INSTANCE.convertAppPage(pageResult, couponTakeCountMap));
     }
 
-    private Long getaProductScopeValue(AppCouponTemplatePageReqVO pageReqVO) {
-        Long productScopeValue = pageReqVO.getSpuId();
-        if (pageReqVO.getProductScope() == null || Objects.equals(pageReqVO.getProductScope(), PromotionProductScopeEnum.ALL.getScope())) {
-            // 通用券:清除商品范围
-            productScopeValue = null;
-        } else if (Objects.equals(pageReqVO.getProductScope(), PromotionProductScopeEnum.CATEGORY.getScope()) && pageReqVO.getSpuId() != null) {
-            // 品类券:查询商品的品类
-            productScopeValue = Optional.ofNullable(productSpuApi.getSpu(pageReqVO.getSpuId()))
+    /**
+     * 获得分页查询的商品范围
+     *
+     * @param pageReqVO 分页查询
+     * @return 商品范围
+     */
+    private Long getProductScopeValue(AppCouponTemplatePageReqVO pageReqVO) {
+        // 通用券:清除商品范围
+        if (pageReqVO.getProductScope() == null || ObjectUtils.equalsAny(pageReqVO.getProductScope(), PromotionProductScopeEnum.ALL.getScope(), null)) {
+            return null;
+        }
+        // 品类券:查询商品的品类
+        if (Objects.equals(pageReqVO.getProductScope(), PromotionProductScopeEnum.CATEGORY.getScope()) && pageReqVO.getSpuId() != null) {
+            return Optional.ofNullable(productSpuApi.getSpu(pageReqVO.getSpuId()))
                     .map(ProductSpuRespDTO::getCategoryId).orElse(null);
         }
-        return productScopeValue;
+        // 商品卷:直接返回
+        return pageReqVO.getSpuId();
     }
 
 }

+ 1 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplatePageReqVO.java

@@ -20,4 +20,5 @@ public class AppCouponTemplatePageReqVO extends PageParam {
 
     @Schema(description = "商品标号", example = "1")
     private Long spuId;
+
 }

+ 1 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java

@@ -61,4 +61,5 @@ public interface CouponConvert {
     PageResult<AppCouponRespVO> convertAppPage(PageResult<CouponDO> pageResult);
 
     List<AppCouponMatchRespVO> convertList(List<CouponDO> list);
+
 }

+ 5 - 5
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponTemplateConvert.java

@@ -42,16 +42,16 @@ public interface CouponTemplateConvert {
         if (MapUtil.isEmpty(couponTakeCountMap)) {
             return result;
         }
-
-        for (AppCouponTemplateRespVO vo : result.getList()) {
+        for (AppCouponTemplateRespVO template : result.getList()) {
             // 每人领取数量无限制
-            if (vo.getTakeLimitCount() == -1) {
-                vo.setTakeStatus(false);
+            if (template.getTakeLimitCount() == -1) {
+                template.setTakeStatus(false);
                 continue;
             }
             // 检查已领取数量是否超过限领数量
-            vo.setTakeStatus(MapUtil.getInt(couponTakeCountMap, vo.getId(), 0) >= vo.getTakeLimitCount());
+            template.setTakeStatus(MapUtil.getInt(couponTakeCountMap, template.getId(), 0) >= template.getTakeLimitCount());
         }
         return result;
     }
+
 }

+ 6 - 5
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java

@@ -70,6 +70,7 @@ public interface CouponMapper extends BaseMapperX<CouponDO> {
         );
     }
 
+    // TODO @疯狂:这个是不是搞个 Map 就可以呀?
     default List<CouponTakeCountBO> selectCountByUserIdAndTemplateIdIn(Long userId, Collection<Long> templateIds) {
         return BeanUtil.copyToList(selectMaps(MPJWrappers.lambdaJoin(CouponDO.class)
                 .select(CouponDO::getTemplateId)
@@ -81,18 +82,17 @@ public interface CouponMapper extends BaseMapperX<CouponDO> {
 
     default List<CouponDO> selectListByUserIdAndStatusAndUsePriceLeAndProductScope(
             Long userId, Integer status, Integer usePrice, List<Long> spuIds, List<Long> categoryIds) {
-
         Function<List<Long>, String> productScopeValuesFindInSetFunc = ids -> ids.stream()
                 .map(id -> StrUtil.format("FIND_IN_SET({}, product_scope_values) ", id))
                 .collect(Collectors.joining(" OR "));
         return selectList(new LambdaQueryWrapperX<CouponDO>()
                 .eq(CouponDO::getUserId, userId)
                 .eq(CouponDO::getStatus, status)
-                .le(CouponDO::getUsePrice, usePrice)
-                .and(w -> w.eq(CouponDO::getProductScope, PromotionProductScopeEnum.ALL.getScope())
-                        .or(ww -> ww.eq(CouponDO::getProductScope, PromotionProductScopeEnum.SPU.getScope())
+                .le(CouponDO::getUsePrice, usePrice) // 价格小于等于,满足价格使用条件
+                .and(w -> w.eq(CouponDO::getProductScope, PromotionProductScopeEnum.ALL.getScope()) // 商品范围一:全部
+                        .or(ww -> ww.eq(CouponDO::getProductScope, PromotionProductScopeEnum.SPU.getScope()) // 商品范围二:满足指定商品
                                 .apply(productScopeValuesFindInSetFunc.apply(spuIds)))
-                        .or(ww -> ww.eq(CouponDO::getProductScope, PromotionProductScopeEnum.CATEGORY.getScope())
+                        .or(ww -> ww.eq(CouponDO::getProductScope, PromotionProductScopeEnum.CATEGORY.getScope()) // 商品范围三:满足指定分类
                                 .apply(productScopeValuesFindInSetFunc.apply(categoryIds)))));
     }
 
@@ -102,4 +102,5 @@ public interface CouponMapper extends BaseMapperX<CouponDO> {
                 .le(CouponDO::getValidEndTime, validEndTime)
         );
     }
+
 }

+ 2 - 1
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java

@@ -137,7 +137,8 @@ public interface CouponService {
      * @return 领取优惠券的数量
      */
     default Map<Long, Integer> getTakeCountMapByTemplateIds(Collection<Long> templateIds, Long userId) {
-        return convertMap(getTakeCountListByTemplateIds(templateIds, userId), CouponTakeCountBO::getTemplateId, CouponTakeCountBO::getCount);
+        return convertMap(getTakeCountListByTemplateIds(templateIds, userId),
+                CouponTakeCountBO::getTemplateId, CouponTakeCountBO::getCount);
     }
 
     /**

+ 2 - 3
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java

@@ -222,13 +222,12 @@ public class CouponServiceImpl implements CouponService {
 
     private boolean expireCoupon(CouponDO coupon) {
         // 更新记录状态
-        CouponDO updateObj = new CouponDO().setStatus(CouponStatusEnum.EXPIRE.getStatus());
-        int updateRows = couponMapper.updateByIdAndStatus(coupon.getId(), CouponStatusEnum.UNUSED.getStatus(), updateObj);
+        int updateRows = couponMapper.updateByIdAndStatus(coupon.getId(), CouponStatusEnum.UNUSED.getStatus(),
+                new CouponDO().setStatus(CouponStatusEnum.EXPIRE.getStatus()));
         if (updateRows == 0) {
             log.error("[expireCoupon][coupon({}) 更新为已过期失败]", coupon.getId());
             return false;
         }
-
         log.info("[expireCoupon][coupon({}) 更新为已过期成功]", coupon.getId());
         return true;
     }

+ 2 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/bo/CouponTakeCountBO.java

@@ -9,6 +9,7 @@ import lombok.Data;
  */
 @Data
 public class CouponTakeCountBO {
+
     /**
      * 优惠劵模板编号
      */
@@ -17,4 +18,5 @@ public class CouponTakeCountBO {
      * 领取数量
      */
     private Integer count;
+
 }

+ 3 - 3
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageUserController.java

@@ -42,6 +42,7 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti
 @Validated
 @Slf4j
 public class AppBrokerageUserController {
+
     @Resource
     private BrokerageUserService brokerageUserService;
     @Resource
@@ -69,8 +70,7 @@ public class AppBrokerageUserController {
     @Operation(summary = "绑定推广员")
     @PreAuthenticated
     public CommonResult<Boolean> bindBrokerageUser(@Valid @RequestBody AppBrokerageUserBindReqVO reqVO) {
-        MemberUserRespDTO user = memberUserApi.getUser(getLoginUserId());
-        return success(brokerageUserService.bindBrokerageUser(user.getId(), reqVO.getBindUserId(), user.getCreateTime()));
+        return success(brokerageUserService.bindBrokerageUser(getLoginUserId(), reqVO.getBindUserId()));
     }
 
     @GetMapping("/get-summary")
@@ -86,7 +86,7 @@ public class AppBrokerageUserController {
         Integer yesterdayPrice = brokerageRecordService.getSummaryPriceByUserId(brokerageUser.getId(),
                 BrokerageRecordBizTypeEnum.ORDER.getType(), beginTime, endTime);
         // 统计用户提现的佣金
-        Integer withdrawPrice = brokerageWithdrawService.getWithdrawSummaryByUserId(Collections.singleton(brokerageUser.getId()),
+        Integer withdrawPrice = brokerageWithdrawService.getWithdrawSummaryListByUserId(Collections.singleton(brokerageUser.getId()),
                         BrokerageWithdrawStatusEnum.AUDIT_SUCCESS).stream()
                 .findFirst().map(UserWithdrawSummaryBO::getPrice).orElse(0);
         // 统计分销用户数量(一级)

+ 1 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageRecordMapper.java

@@ -68,6 +68,7 @@ public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> {
                 .eq(BrokerageRecordDO::getStatus, status)
                 .groupBy(BrokerageRecordDO::getUserId));
         return BeanUtil.copyToList(list, UserBrokerageSummaryBO.class);
+        // selectJoinList有BUG,会与租户插件冲突:解析SQL时,发生异常 https://gitee.com/best_handsome/mybatis-plus-join/issues/I84GYW
 //            return selectJoinList(UserBrokerageSummaryBO.class, MPJWrappers.lambdaJoin(BrokerageRecordDO.class)
 //                    .select(BrokerageRecordDO::getUserId)
 //                    .selectCount(BrokerageRecordDO::getId, UserBrokerageSummaryBO::getCount)

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

@@ -78,25 +78,25 @@ public interface BrokerageRecordService {
     int unfreezeRecord();
 
     /**
-     * 汇总用户佣金
+     * 按照 userId,汇总每个用户佣金
      *
      * @param userIds 用户编号
      * @param bizType 业务类型
      * @param status  佣金状态
-     * @return 用户佣金汇总
+     * @return 用户佣金汇总 List
      */
-    List<UserBrokerageSummaryBO> getUserBrokerageSummaryByUserId(Collection<Long> userIds, Integer bizType, Integer status);
+    List<UserBrokerageSummaryBO> getUserBrokerageSummaryListByUserId(Collection<Long> userIds, Integer bizType, Integer status);
 
     /**
-     * 汇总用户佣金
+     * 按照 userId,汇总每个用户佣金
      *
      * @param userIds 用户编号
      * @param bizType 业务类型
      * @param status  佣金状态
-     * @return 用户佣金汇总
+     * @return 用户佣金汇总 Map
      */
     default Map<Long, UserBrokerageSummaryBO> getUserBrokerageSummaryMapByUserId(Collection<Long> userIds, Integer bizType, Integer status) {
-        return convertMap(getUserBrokerageSummaryByUserId(userIds, bizType, status), UserBrokerageSummaryBO::getUserId);
+        return convertMap(getUserBrokerageSummaryListByUserId(userIds, bizType, status), UserBrokerageSummaryBO::getUserId);
     }
 
     /**

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

@@ -232,7 +232,7 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
     }
 
     @Override
-    public List<UserBrokerageSummaryBO> getUserBrokerageSummaryByUserId(Collection<Long> userIds, Integer bizType, Integer status) {
+    public List<UserBrokerageSummaryBO> getUserBrokerageSummaryListByUserId(Collection<Long> userIds, Integer bizType, Integer status) {
         return brokerageRecordMapper.selectCountAndSumPriceByUserIdInAndBizTypeAndStatus(userIds, bizType, status);
     }
 

+ 1 - 3
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserService.java

@@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokera
 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
 
 import javax.validation.constraints.NotNull;
-import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.List;
 
@@ -107,10 +106,9 @@ public interface BrokerageUserService {
      *
      * @param userId       用户编号
      * @param bindUserId   推广员编号
-     * @param registerTime 用户注册时间
      * @return 是否绑定
      */
-    boolean bindBrokerageUser(@NotNull Long userId, @NotNull Long bindUserId, @NotNull LocalDateTime registerTime);
+    boolean bindBrokerageUser(@NotNull Long userId, @NotNull Long bindUserId);
 
     /**
      * 获取用户是否有分销资格

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

@@ -7,6 +7,8 @@ import cn.hutool.core.util.BooleanUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
+import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
+import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserPageReqVO;
 import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryPageReqVO;
 import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO;
@@ -48,6 +50,9 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
     @Resource
     private TradeConfigService tradeConfigService;
 
+    @Resource
+    private MemberUserApi memberUserApi;
+
     @Override
     public BrokerageUserDO getBrokerageUser(Long id) {
         return brokerageUserMapper.selectById(id);
@@ -155,7 +160,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
     }
 
     @Override
-    public boolean bindBrokerageUser(Long userId, Long bindUserId, LocalDateTime registerTime) {
+    public boolean bindBrokerageUser(Long userId, Long bindUserId) {
         // 1. 获得分销用户
         boolean isNewBrokerageUser = false;
         BrokerageUserDO brokerageUser = brokerageUserMapper.selectById(userId);
@@ -165,7 +170,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
         }
 
         // 2.1 校验是否能绑定用户
-        boolean validated = isUserCanBind(brokerageUser, registerTime);
+        boolean validated = isUserCanBind(brokerageUser);
         if (!validated) {
             return false;
         }
@@ -223,7 +228,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
         return new PageResult<>(pageResult.getRecords(), pageResult.getTotal());
     }
 
-    private boolean isUserCanBind(BrokerageUserDO user, LocalDateTime registerTime) {
+    private boolean isUserCanBind(BrokerageUserDO user) {
         // 校验分销功能是否启用
         TradeConfigDO tradeConfig = tradeConfigService.getTradeConfig();
         if (tradeConfig == null || !BooleanUtil.isTrue(tradeConfig.getBrokerageEnabled())) {
@@ -237,9 +242,8 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
 
         // 校验分销关系绑定模式
         if (BrokerageBindModeEnum.REGISTER.getMode().equals(tradeConfig.getBrokerageBindMode())) {
-            // 判断是否为新用户:注册时间在30秒内的,都算新用户
-            boolean isNotNewUser = LocalDateTimeUtils.beforeNow(registerTime.plusSeconds(30));
-            if (isNotNewUser) {
+            // 判断是否为新用户:注册时间在 30 秒内的,都算新用户
+            if (!isNewRegisterUser(user.getId())) {
                 throw exception(BROKERAGE_BIND_MODE_REGISTER); // 只有在注册时可以绑定
             }
         } else if (BrokerageBindModeEnum.ANYTIME.getMode().equals(tradeConfig.getBrokerageBindMode())) {
@@ -247,14 +251,29 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
                 throw exception(BROKERAGE_BIND_OVERRIDE); // 已绑定了推广人
             }
         }
-
         return true;
     }
 
+    /**
+     * 判断是否为新用户
+     *
+     * 标准:注册时间在 30 秒内的,都算新用户
+     *
+     * 疑问:为什么通过这样的方式实现?
+     * 回答:因为注册在 member 模块,希望它和 trade 模块解耦,所以只能用这种约定的逻辑。
+     *
+     * @param userId 用户编号
+     * @return 是否新用户
+     */
+    private boolean isNewRegisterUser(Long userId) {
+        MemberUserRespDTO user = memberUserApi.getUser(userId);
+        return user != null && LocalDateTimeUtils.beforeNow(user.getCreateTime().plusSeconds(30));
+    }
+
     private void validateCanBindUser(BrokerageUserDO user, Long bindUserId) {
         // 校验要绑定的用户有无推广资格
         BrokerageUserDO bindUser = brokerageUserMapper.selectById(bindUserId);
-        if (bindUser == null || !BooleanUtil.isTrue(bindUser.getBrokerageEnabled())) {
+        if (bindUser == null || BooleanUtil.isFalse(bindUser.getBrokerageEnabled())) {
             throw exception(BROKERAGE_BIND_USER_NOT_ENABLED);
         }
 

+ 7 - 6
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java

@@ -56,22 +56,23 @@ public interface BrokerageWithdrawService {
     Long createBrokerageWithdraw(AppBrokerageWithdrawCreateReqVO createReqVO, Long userId);
 
     /**
-     * 汇总用户提现
+     * 按照 userId,汇总每个用户提现
      *
      * @param userIds 用户编号
      * @param status  提现状态
-     * @return 用户提现汇总
+     * @return 用户提现汇总 List
      */
-    List<UserWithdrawSummaryBO> getWithdrawSummaryByUserId(Collection<Long> userIds, BrokerageWithdrawStatusEnum status);
+    List<UserWithdrawSummaryBO> getWithdrawSummaryListByUserId(Collection<Long> userIds, BrokerageWithdrawStatusEnum status);
 
     /**
-     * 汇总用户提现
+     * 按照 userId,汇总每个用户提现
      *
      * @param userIds 用户编号
      * @param status  提现状态
-     * @return 用户提现汇总
+     * @return 用户提现汇总 Map
      */
     default Map<Long, UserWithdrawSummaryBO> getWithdrawSummaryMapByUserId(Set<Long> userIds, BrokerageWithdrawStatusEnum status) {
-        return convertMap(getWithdrawSummaryByUserId(userIds, status), UserWithdrawSummaryBO::getUserId);
+        return convertMap(getWithdrawSummaryListByUserId(userIds, status), UserWithdrawSummaryBO::getUserId);
     }
+
 }

+ 1 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java

@@ -144,7 +144,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
     }
 
     @Override
-    public List<UserWithdrawSummaryBO> getWithdrawSummaryByUserId(Collection<Long> userIds, BrokerageWithdrawStatusEnum status) {
+    public List<UserWithdrawSummaryBO> getWithdrawSummaryListByUserId(Collection<Long> userIds, BrokerageWithdrawStatusEnum status) {
         return brokerageWithdrawMapper.selectCountAndSumPriceByUserIdAndStatus(userIds, status.getStatus());
     }
 

+ 2 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/UserBrokerageSummaryBO.java

@@ -13,12 +13,13 @@ import lombok.NoArgsConstructor;
 @NoArgsConstructor
 @AllArgsConstructor
 public class UserBrokerageSummaryBO {
+
     /**
      * 用户编号
      */
     private Long userId;
     /**
-     * 佣金数量
+     * 推广数量
      */
     private Integer count;
     /**

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

@@ -125,7 +125,6 @@ public interface TradeOrderUpdateService {
      */
     void updateOrderItemWhenAfterSaleCreate(@NotNull Long id, @NotNull Long afterSaleId);
 
-
     /**
      * 当售后完成后,更新交易订单项的售后状态
      *

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

@@ -753,6 +753,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 
     @Override
     public void updateOrderItemWhenAfterSaleCreate(Long id, Long afterSaleId) {
+        // TODO @疯狂:这个可以直接在接口上,写 @Null 参数校验;
         if (afterSaleId == null) {
             throw new IllegalArgumentException(StrUtil.format("id({}) 退款发起,售后单编号不能为空", id));
         }
@@ -765,6 +766,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void updateOrderItemWhenAfterSaleSuccess(Long id, Integer refundPrice) {
+        // TODO @疯狂:这个可以直接在接口上,写 @Null 参数校验;
         if (refundPrice == null) {
             throw new IllegalArgumentException(StrUtil.format("id({}) 退款成功,退款金额不能为空", id));
         }
@@ -787,15 +789,17 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         }
 
         // TODO 芋艿:这块扣减规则,需要在考虑下
-        // 3.1 回滚数据:增加 SKU 库存
+        // 3. 回滚数据:增加 SKU 库存
         productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(Collections.singletonList(orderItem)));
-        // 3.2 回滚数据:扣减用户积分(赠送的)
+
+        // 4.1 回滚数据:扣减用户积分(赠送的)
         reduceUserPoint(order.getUserId(), orderItem.getGivePoint(), MemberPointBizTypeEnum.AFTER_SALE_DEDUCT_GIVE, orderItem.getAfterSaleId());
-        // 3.3 回滚数据:增加用户积分(返还抵扣)
+        // 4.2 回滚数据:增加用户积分(返还抵扣)
         addUserPoint(order.getUserId(), orderItem.getUsePoint(), MemberPointBizTypeEnum.AFTER_SALE_REFUND_USED, orderItem.getAfterSaleId());
-        // 3.4 回滚数据:扣减用户经验
+        // 4.3 回滚数据:扣减用户经验
         getSelf().reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, orderItem.getAfterSaleId());
-        // 3.5 回滚数据:更新分佣记录为已失效
+
+        // 5. 回滚数据:更新分佣记录为已失效
         getSelf().cancelBrokerageAsync(order.getUserId(), id);
     }
 
@@ -826,7 +830,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         couponApi.returnUsedCoupon(order.getCouponId());
     }
 
-
     /**
      * 判断指定订单的所有订单项,是不是都售后成功
      *

+ 2 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java

@@ -87,10 +87,11 @@ public class TradePointUsePriceCalculator implements TradePriceCalculator {
         if (config.getTradeDeductMaxPrice() != null && config.getTradeDeductMaxPrice() > 0) {
             usePoint = Math.min(usePoint, config.getTradeDeductMaxPrice());
         }
+        // TODO @疯狂:这里应该是,抵扣到只剩下 0.01;
         // 积分优惠金额(分)
         int pointPrice = usePoint * config.getTradeDeductUnitPrice();
         if (result.getPrice().getPayPrice() <= pointPrice) {
-            // 禁止0元购
+            // 禁止 0 元购
             throw exception(PRICE_CALCULATE_PAY_PRICE_ILLEGAL);
         }
 //        // 允许0 元购!!!:用户积分比较多时,积分可以抵扣的金额要大于支付金额,这时需要根据支付金额反推使用多少积分

+ 4 - 0
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/vo/MemberUserPageReqVO.java

@@ -41,4 +41,8 @@ public class MemberUserPageReqVO extends PageParam {
     @Schema(description = "用户分组编号", example = "1")
     private Long groupId;
 
+    // TODO 芋艿:注册用户类型;
+
+    // TODO 芋艿:登录用户类型;
+
 }

+ 1 - 1
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java

@@ -190,7 +190,7 @@ public class MemberUserServiceImpl implements MemberUserService {
     @Transactional(rollbackFor = Exception.class)
     public void updateUser(MemberUserUpdateReqVO updateReqVO) {
         // 校验存在
-        MemberUserDO user = validateUserExists(updateReqVO.getId());
+        validateUserExists(updateReqVO.getId());
         // 校验手机唯一
         validateMobileUnique(updateReqVO.getId(), updateReqVO.getMobile());