Преглед изворни кода

【功能优化】商城:价格计算时,返回可用 + 不可用的优惠劵

YunaiV пре 6 месеци
родитељ
комит
840cfad84a
21 измењених фајлова са 240 додато и 263 уклоњено
  1. 3 3
      pom.xml
  2. 9 9
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java
  3. 0 27
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponValidReqDTO.java
  4. 0 2
      yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
  5. 6 9
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java
  6. 5 12
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/AppCouponController.java
  7. 0 30
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponMatchReqVO.java
  8. 0 16
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponMatchRespVO.java
  9. 0 2
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponRespVO.java
  10. 0 3
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java
  11. 0 20
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/coupon/CouponMapper.java
  12. 1 7
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/reward/RewardActivityMapper.java
  13. 0 30
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java
  14. 2 28
      yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java
  15. 1 1
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
  16. 43 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java
  17. 64 1
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java
  18. 67 27
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java
  19. 8 3
      yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java
  20. 1 1
      yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImplTest.java
  21. 30 30
      yudao-server/pom.xml

+ 3 - 3
pom.xml

@@ -15,12 +15,12 @@
         <!-- 各种 module 拓展 -->
         <module>yudao-module-system</module>
         <module>yudao-module-infra</module>
-        <module>yudao-module-member</module>
+<!--        <module>yudao-module-member</module>-->
 <!--        <module>yudao-module-bpm</module>-->
 <!--        <module>yudao-module-report</module>-->
 <!--        <module>yudao-module-mp</module>-->
-        <module>yudao-module-pay</module>
-        <module>yudao-module-mall</module>
+<!--        <module>yudao-module-pay</module>-->
+<!--        <module>yudao-module-mall</module>-->
 <!--        <module>yudao-module-crm</module>-->
 <!--        <module>yudao-module-erp</module>-->
 <!--        <module>yudao-module-ai</module>-->

+ 9 - 9
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApi.java

@@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.promotion.api.coupon;
 
 import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO;
 import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
-import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO;
 import jakarta.validation.Valid;
 
 import java.util.List;
@@ -15,6 +14,15 @@ import java.util.Map;
  */
 public interface CouponApi {
 
+    /**
+     * 获得用户的优惠劵列表
+     *
+     * @param userId 用户编号
+     * @param status 优惠劵状态
+     * @return 优惠劵列表
+     */
+    List<CouponRespDTO> getCouponListByUserId(Long userId, Integer status);
+
     /**
      * 使用优惠劵
      *
@@ -29,14 +37,6 @@ public interface CouponApi {
      */
     void returnUsedCoupon(Long id);
 
-    /**
-     * 校验优惠劵
-     *
-     * @param validReqDTO 校验请求
-     * @return 优惠劵
-     */
-    CouponRespDTO validateCoupon(@Valid CouponValidReqDTO validReqDTO);
-
     /**
      * 【管理员】给指定用户批量发送优惠券
      *

+ 0 - 27
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponValidReqDTO.java

@@ -1,27 +0,0 @@
-package cn.iocoder.yudao.module.promotion.api.coupon.dto;
-
-import lombok.Data;
-
-import jakarta.validation.constraints.NotNull;
-
-/**
- * 优惠劵使用 Request DTO
- *
- * @author 芋道源码
- */
-@Data
-public class CouponValidReqDTO {
-
-    /**
-     * 优惠劵编号
-     */
-    @NotNull(message = "优惠劵编号不能为空")
-    private Long id;
-
-    /**
-     * 用户编号
-     */
-    @NotNull(message = "用户编号不能为空")
-    private Long userId;
-
-}

+ 0 - 2
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java

@@ -20,8 +20,6 @@ public interface ErrorCodeConstants {
     ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1_013_002_000, "Banner 不存在");
 
     // ========== Coupon 相关 1-013-003-000 ============
-    ErrorCode COUPON_NO_MATCH_SPU = new ErrorCode(1_013_003_000, "优惠劵没有可使用的商品!");
-    ErrorCode COUPON_NO_MATCH_MIN_PRICE = new ErrorCode(1_013_003_001, "所结算的商品中未满足使用的金额");
 
     // ========== 优惠劵模板 1-013-004-000 ==========
     ErrorCode COUPON_TEMPLATE_NOT_EXISTS = new ErrorCode(1_013_004_000, "优惠劵模板不存在");

+ 6 - 9
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java

@@ -1,11 +1,9 @@
 package cn.iocoder.yudao.module.promotion.api.coupon;
 
 
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO;
 import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
-import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO;
-import cn.iocoder.yudao.module.promotion.convert.coupon.CouponConvert;
-import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
 import cn.iocoder.yudao.module.promotion.service.coupon.CouponService;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
@@ -26,6 +24,11 @@ public class CouponApiImpl implements CouponApi {
     @Resource
     private CouponService couponService;
 
+    @Override
+    public List<CouponRespDTO> getCouponListByUserId(Long userId, Integer status) {
+        return BeanUtils.toBean(couponService.getCouponList(userId, status), CouponRespDTO.class);
+    }
+
     @Override
     public void useCoupon(CouponUseReqDTO useReqDTO) {
         couponService.useCoupon(useReqDTO.getId(), useReqDTO.getUserId(),
@@ -37,12 +40,6 @@ public class CouponApiImpl implements CouponApi {
         couponService.returnUsedCoupon(id);
     }
 
-    @Override
-    public CouponRespDTO validateCoupon(CouponValidReqDTO validReqDTO) {
-        CouponDO coupon = couponService.validCoupon(validReqDTO.getId(), validReqDTO.getUserId());
-        return CouponConvert.INSTANCE.convert(coupon);
-    }
-
     @Override
     public List<Long> takeCouponsByAdmin(Map<Long, Integer> giveCoupons, Long userId) {
         return couponService.takeCouponsByAdmin(giveCoupons, userId);

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

@@ -5,7 +5,9 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
-import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon.*;
+import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon.AppCouponPageReqVO;
+import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon.AppCouponRespVO;
+import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon.AppCouponTakeReqVO;
 import cn.iocoder.yudao.module.promotion.convert.coupon.CouponConvert;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
@@ -15,13 +17,12 @@ import cn.iocoder.yudao.module.promotion.service.coupon.CouponTemplateService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
-import jakarta.annotation.Resource;
-import jakarta.validation.Valid;
 import java.util.Collections;
-import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@@ -56,14 +57,6 @@ public class AppCouponController {
         return success(canTakeAgain);
     }
 
-    @GetMapping("/match-list")
-    @Operation(summary = "获得匹配指定商品的优惠劵列表", description = "用于下单页,展示优惠劵列表")
-    public CommonResult<List<AppCouponMatchRespVO>> getMatchCouponList(AppCouponMatchReqVO matchReqVO) {
-        // todo: 优化:优惠金额倒序
-        List<CouponDO> list = couponService.getMatchCouponList(getLoginUserId(), matchReqVO);
-        return success(BeanUtils.toBean(list, AppCouponMatchRespVO.class));
-    }
-
     @GetMapping("/page")
     @Operation(summary = "我的优惠劵列表")
     @PreAuthenticated

+ 0 - 30
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponMatchReqVO.java

@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-import java.util.List;
-
-@Schema(description = "用户 App - 优惠劵的匹配 Request VO")
-@Data
-public class AppCouponMatchReqVO {
-
-    @Schema(description = "商品金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    @NotNull(message = "商品金额不能为空")
-    private Integer price;
-
-    @Schema(description = "商品 SPU 编号的数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2]")
-    @NotEmpty(message = "商品 SPU 编号不能为空")
-    private List<Long> spuIds;
-
-    @Schema(description = "商品 SKU 编号的数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2]")
-    @NotEmpty(message = "商品 SKU 编号不能为空")
-    private List<Long> skuIds;
-
-    @Schema(description = "分类编号的数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[10, 20]")
-    @NotEmpty(message = "分类编号不能为空")
-    private List<Long> categoryIds;
-
-}

+ 0 - 16
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponMatchRespVO.java

@@ -1,16 +0,0 @@
-package cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-@Schema(description = "用户 App - 优惠劵 Response VO")
-@Data
-public class AppCouponMatchRespVO extends AppCouponRespVO {
-
-    @Schema(description = "是否匹配", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
-    private Boolean match;
-
-    @Schema(description = "匹配条件的提示", example = "所结算商品没有符合条件的商品")
-    private String description;
-
-}

+ 0 - 2
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/coupon/AppCouponRespVO.java

@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
-import jakarta.validation.constraints.Min;
 import java.time.LocalDateTime;
 import java.util.List;
 
@@ -42,7 +41,6 @@ public class AppCouponRespVO {
     private Integer discountPercent;
 
     @Schema(description = "优惠金额", example = "10")
-    @Min(value = 0, message = "优惠金额需要大于等于 0")
     private Integer discountPrice;
 
     @Schema(description = "折扣上限", example = "100") // 单位:分,仅在 discountType 为 PERCENT 使用

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

@@ -4,9 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO;
 import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageItemRespVO;
 import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO;
-import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon.AppCouponMatchRespVO;
 import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon.AppCouponPageReqVO;
-import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon.AppCouponRespVO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
 import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum;
@@ -16,7 +14,6 @@ import org.mapstruct.factory.Mappers;
 
 import java.time.LocalDateTime;
 import java.util.Collection;
-import java.util.List;
 
 /**
  * 优惠劵 Convert

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

@@ -1,13 +1,11 @@
 package cn.iocoder.yudao.module.promotion.dal.mysql.coupon;
 
 import cn.hutool.core.map.MapUtil;
-import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
-import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.github.yulichang.toolkit.MPJWrappers;
 import org.apache.ibatis.annotations.Mapper;
@@ -16,8 +14,6 @@ import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
-import java.util.function.Function;
-import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
 
@@ -84,22 +80,6 @@ public interface CouponMapper extends BaseMapperX<CouponDO> {
         return convertMap(list, map -> MapUtil.getLong(map, templateIdAlias), map -> MapUtil.getInt(map, countAlias));
     }
 
-    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()) // 商品范围二:满足指定商品
-                                .apply(productScopeValuesFindInSetFunc.apply(spuIds)))
-                        .or(ww -> ww.eq(CouponDO::getProductScope, PromotionProductScopeEnum.CATEGORY.getScope()) // 商品范围三:满足指定分类
-                                .apply(productScopeValuesFindInSetFunc.apply(categoryIds)))));
-    }
-
     default List<CouponDO> selectListByStatusAndValidEndTimeLe(Integer status, LocalDateTime validEndTime) {
         return selectList(new LambdaQueryWrapperX<CouponDO>()
                 .eq(CouponDO::getStatus, status)

+ 1 - 7
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/reward/RewardActivityMapper.java

@@ -30,15 +30,9 @@ public interface RewardActivityMapper extends BaseMapperX<RewardActivityDO> {
                 .orderByDesc(RewardActivityDO::getId));
     }
 
-    default List<RewardActivityDO> selectListByProductScopeAndStatus(Integer productScope, Integer status) {
-        return selectList(new LambdaQueryWrapperX<RewardActivityDO>()
-                .eq(RewardActivityDO::getProductScope, productScope)
-                .eq(RewardActivityDO::getStatus, status));
-    }
-
     default List<RewardActivityDO> selectListBySpuIdsAndStatus(Collection<Long> spuIds, Integer status) {
         Function<Collection<Long>, String> productScopeValuesFindInSetFunc = ids -> ids.stream()
-                .map(id -> StrUtil.format("FIND_IN_SET({}, product_spu_ids) ", id))
+                .map(id -> StrUtil.format("FIND_IN_SET({}, product_scope_values) ", id))
                 .collect(Collectors.joining(" OR "));
         return selectList(new QueryWrapper<RewardActivityDO>()
                 .eq("status", status)

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

@@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.map.MapUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO;
-import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon.AppCouponMatchReqVO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
 import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum;
@@ -18,26 +17,6 @@ import java.util.*;
  */
 public interface CouponService {
 
-    /**
-     * 校验优惠劵,包括状态、有限期
-     * <p>
-     * 1. 如果校验通过,则返回优惠劵信息
-     * 2. 如果校验不通过,则直接抛出业务异常
-     *
-     * @param id     优惠劵编号
-     * @param userId 用户编号
-     * @return 优惠劵信息
-     */
-    CouponDO validCoupon(Long id, Long userId);
-
-    /**
-     * 校验优惠劵,包括状态、有限期
-     *
-     * @param coupon 优惠劵
-     * @see #validCoupon(Long, Long) 逻辑相同,只是入参不同
-     */
-    void validCoupon(CouponDO coupon);
-
     /**
      * 使用优惠劵
      *
@@ -171,15 +150,6 @@ public interface CouponService {
         return MapUtil.getInt(map, templateId, 0);
     }
 
-    /**
-     * 获取用户匹配的优惠券列表
-     *
-     * @param userId     用户编号
-     * @param matchReqVO 匹配参数
-     * @return 优惠券列表
-     */
-    List<CouponDO> getMatchCouponList(Long userId, AppCouponMatchReqVO matchReqVO);
-
     /**
      * 获取用户是否可以领取优惠券
      *

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

@@ -12,7 +12,6 @@ import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
 import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
 import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO;
-import cn.iocoder.yudao.module.promotion.controller.app.coupon.vo.coupon.AppCouponMatchReqVO;
 import cn.iocoder.yudao.module.promotion.convert.coupon.CouponConvert;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
 import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponTemplateDO;
@@ -56,18 +55,9 @@ public class CouponServiceImpl implements CouponService {
     private MemberUserApi memberUserApi;
 
     @Override
-    public CouponDO validCoupon(Long id, Long userId) {
-        CouponDO coupon = couponMapper.selectByIdAndUserId(id, userId);
-        if (coupon == null) {
-            throw exception(COUPON_NOT_EXISTS);
-        }
-        validCoupon(coupon);
-        return coupon;
-    }
-
-    @Override
-    public void validCoupon(CouponDO coupon) {
+    public void useCoupon(Long id, Long userId, Long orderId) {
         // 校验状态
+        CouponDO coupon = couponMapper.selectByIdAndUserId(id, userId);
         if (ObjectUtil.notEqual(coupon.getStatus(), CouponStatusEnum.UNUSED.getStatus())) {
             throw exception(COUPON_STATUS_NOT_UNUSED);
         }
@@ -75,12 +65,6 @@ public class CouponServiceImpl implements CouponService {
         if (!LocalDateTimeUtils.isBetween(coupon.getValidStartTime(), coupon.getValidEndTime())) {
             throw exception(COUPON_VALID_TIME_NOT_NOW);
         }
-    }
-
-    @Override
-    public void useCoupon(Long id, Long userId, Long orderId) {
-        // 校验优惠劵
-        validCoupon(id, userId);
 
         // 更新状态
         int updateCount = couponMapper.updateByIdAndStatus(id, CouponStatusEnum.UNUSED.getStatus(),
@@ -354,16 +338,6 @@ public class CouponServiceImpl implements CouponService {
         return couponMapper.selectCountByUserIdAndTemplateIdIn(userId, templateIds);
     }
 
-    @Override
-    public List<CouponDO> getMatchCouponList(Long userId, AppCouponMatchReqVO matchReqVO) {
-        List<CouponDO> list = couponMapper.selectListByUserIdAndStatusAndUsePriceLeAndProductScope(userId,
-                CouponStatusEnum.UNUSED.getStatus(),
-                matchReqVO.getPrice(), matchReqVO.getSpuIds(), matchReqVO.getCategoryIds());
-        // 兜底逻辑:如果 CouponExpireJob 未执行,status 未变成 EXPIRE ,但是 validEndTime 已经过期了,需要进行过滤
-        list.removeIf(coupon -> !LocalDateTimeUtils.isBetween(coupon.getValidStartTime(), coupon.getValidEndTime()));
-        return list;
-    }
-
     @Override
     public Map<Long, Boolean> getUserCanCanTakeMap(Long userId, List<CouponTemplateDO> templates) {
         // 1. 未登录时,都显示可以领取

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

@@ -61,7 +61,7 @@ public interface ErrorCodeConstants {
     ErrorCode PRICE_CALCULATE_COUPON_NOT_MATCH_NORMAL_ORDER = new ErrorCode(1_011_003_004, "参与秒杀、拼团、砍价的营销商品,无法使用优惠劵");
     ErrorCode PRICE_CALCULATE_SECKILL_TOTAL_LIMIT_COUNT = new ErrorCode(1_011_003_005, "参与秒杀的商品,超过了秒杀总限购数量");
     ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TYPE_ILLEGAL = new ErrorCode(1_011_003_006, "计算快递运费异常,配送方式不匹配");
-    ErrorCode PRICE_CALCULATE_COUPON_PRICE_TOO_MUCH = new ErrorCode(1_011_003_007, "该优惠劵无法使用,原因:优惠金额超过订单金额");
+    ErrorCode PRICE_CALCULATE_COUPON_CAN_NOT_USE = new ErrorCode(1_011_003_007, "该优惠劵无法使用,原因:{}」");
 
     // ========== 物流 Express 模块 1-011-004-000 ==========
     ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1_011_004_000, "快递公司不存在");

+ 43 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementRespVO.java

@@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.trade.controller.app.order.vo;
 
 import cn.iocoder.yudao.module.trade.controller.app.base.property.AppProductPropertyValueDetailRespVO;
 import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.time.LocalDateTime;
 import java.util.List;
 
 @Schema(description = "用户 App - 交易订单结算信息 Response VO")
@@ -19,6 +19,9 @@ public class AppTradeOrderSettlementRespVO {
     @Schema(description = "购物项数组", requiredMode = Schema.RequiredMode.REQUIRED)
     private List<Item> items;
 
+    @Schema(description = "优惠劵数组", requiredMode = Schema.RequiredMode.REQUIRED)
+    private List<Coupon> coupons; // 可用 + 不可用
+
     @Schema(description = "费用", requiredMode = Schema.RequiredMode.REQUIRED)
     private Price price;
 
@@ -109,7 +112,6 @@ public class AppTradeOrderSettlementRespVO {
         private String mobile;
 
         @Schema(description = "地区编号", requiredMode = Schema.RequiredMode.REQUIRED)
-        @NotNull(message = "地区编号不能为空")
         private Long areaId;
         @Schema(description = "地区名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "上海上海市普陀区")
         private String areaName;
@@ -122,4 +124,43 @@ public class AppTradeOrderSettlementRespVO {
 
     }
 
+    @Schema(description = "优惠劵信息")
+    @Data
+    public static class Coupon {
+
+        @Schema(description = "优惠劵编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+        private Long id;
+
+        @Schema(description = "优惠劵名", requiredMode = Schema.RequiredMode.REQUIRED, example = "春节送送送")
+        private String name;
+
+        @Schema(description = "是否设置满多少金额可用", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") // 单位:分;0 - 不限制
+        private Integer usePrice;
+
+        @Schema(description = "固定日期 - 生效开始时间")
+        private LocalDateTime validStartTime;
+
+        @Schema(description = "固定日期 - 生效结束时间")
+        private LocalDateTime validEndTime;
+
+        @Schema(description = "优惠类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+        private Integer discountType;
+
+        @Schema(description = "折扣百分比", example = "80") //  例如说,80% 为 80
+        private Integer discountPercent;
+
+        @Schema(description = "优惠金额", example = "10")
+        private Integer discountPrice;
+
+        @Schema(description = "折扣上限", example = "100") // 单位:分,仅在 discountType 为 PERCENT 使用
+        private Integer discountLimitPrice;
+
+        @Schema(description = "是否可用", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
+        private Boolean match;
+
+        @Schema(description = "不可用原因", example = "优惠劵已过期")
+        private String mismatchReason;
+
+    }
+
 }

+ 64 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java

@@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
 import lombok.Data;
 
+import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Map;
 
@@ -45,9 +46,13 @@ public class TradePriceCalculateRespBO {
     private List<Promotion> promotions;
 
     /**
-     * 优惠劵编号
+     * 使用的优惠劵编号
      */
     private Long couponId;
+    /**
+     * 用户的优惠劵列表(可用 + 不可用)
+     */
+    private List<Coupon> coupons;
 
     /**
      * 会员剩余积分
@@ -339,4 +344,62 @@ public class TradePriceCalculateRespBO {
 
     }
 
+    /**
+     * 优惠劵信息
+     */
+    @Data
+    public static class Coupon {
+
+        /**
+         * 优惠劵编号
+         */
+        private Long id;
+        /**
+         * 优惠劵名
+         */
+        private String name;
+
+        /**
+         * 是否设置满多少金额可用,单位:分
+         */
+        private Integer usePrice;
+
+        /**
+         * 生效开始时间
+         */
+        private LocalDateTime validStartTime;
+        /**
+         * 生效结束时间
+         */
+        private LocalDateTime validEndTime;
+
+        /**
+         * 优惠类型
+         */
+        private Integer discountType;
+        /**
+         * 折扣百分比
+         */
+        private Integer discountPercent;
+        /**
+         * 优惠金额,单位:分
+         */
+        private Integer discountPrice;
+        /**
+         * 折扣上限,单位:分
+         */
+        private Integer discountLimitPrice;
+
+        /**
+         * 是否匹配
+         */
+        private Boolean match;
+        /**
+         * 不匹配的原因
+         */
+        private String mismatchReason;
+
+    }
+
+
 }

+ 67 - 27
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java

@@ -1,31 +1,31 @@
 package cn.iocoder.yudao.module.trade.service.price.calculator;
 
 import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
 import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO;
-import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO;
 import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
 import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
 import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
+import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum;
 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
+import jakarta.annotation.Resource;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
 
-import jakarta.annotation.Resource;
 import java.util.List;
 import java.util.function.Predicate;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
-import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_NO_MATCH_MIN_PRICE;
-import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_NO_MATCH_SPU;
+import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_COUPON_CAN_NOT_USE;
 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_COUPON_NOT_MATCH_NORMAL_ORDER;
-import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_COUPON_PRICE_TOO_MUCH;
 
 /**
  * 优惠劵的 {@link TradePriceCalculator} 实现类
@@ -41,34 +41,37 @@ public class TradeCouponPriceCalculator implements TradePriceCalculator {
 
     @Override
     public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
-        // 1.1 校验优惠劵
-        if (param.getCouponId() == null) {
-            return;
-        }
-        CouponRespDTO coupon = couponApi.validateCoupon(new CouponValidReqDTO()
-                .setId(param.getCouponId()).setUserId(param.getUserId()));
-        Assert.notNull(coupon, "校验通过的优惠劵({}),不能为空", param.getCouponId());
-        // 1.2 只有【普通】订单,才允许使用优惠劵
+        // 只有【普通】订单,才允许使用优惠劵
         if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.NORMAL.getType())) {
-            throw exception(PRICE_CALCULATE_COUPON_NOT_MATCH_NORMAL_ORDER);
+            if (ObjectUtil.notEqual(result.getType(), TradeOrderTypeEnum.NORMAL.getType())) {
+                throw exception(PRICE_CALCULATE_COUPON_NOT_MATCH_NORMAL_ORDER);
+            }
+            return;
         }
 
-        // 2.1 获得匹配的商品 SKU 数组
-        List<TradePriceCalculateRespBO.OrderItem> orderItems = filterMatchCouponOrderItems(result, coupon);
-        if (CollUtil.isEmpty(orderItems)) {
-            throw exception(COUPON_NO_MATCH_SPU);
+        // 1.1 加载用户的优惠劵列表
+        List<CouponRespDTO> coupons = couponApi.getCouponListByUserId(param.getUserId(), CouponStatusEnum.UNUSED.getStatus());
+        coupons.removeIf(coupon -> LocalDateTimeUtils.beforeNow(coupon.getValidEndTime()));
+        // 1.2 计算优惠劵的使用条件
+        result.setCoupons(calculateCoupons(coupons, result));
+
+        // 2. 校验优惠劵是否可用
+        if (param.getCouponId() == null) {
+            return;
         }
-        // 2.2 计算是否满足优惠劵的使用金额
-        Integer totalPayPrice = TradePriceCalculatorHelper.calculateTotalPayPrice(orderItems);
-        if (totalPayPrice < coupon.getUsePrice()) {
-            throw exception(COUPON_NO_MATCH_MIN_PRICE);
+        TradePriceCalculateRespBO.Coupon couponBO = CollUtil.findOne(result.getCoupons(), item -> item.getId().equals(param.getCouponId()));
+        CouponRespDTO coupon = CollUtil.findOne(coupons, item -> item.getId().equals(param.getCouponId()));
+        if (couponBO == null || coupon == null) {
+            throw exception(PRICE_CALCULATE_COUPON_CAN_NOT_USE, "优惠劵不存在");
+        }
+        if (Boolean.FALSE.equals(couponBO.getMatch())) {
+            throw exception(PRICE_CALCULATE_COUPON_CAN_NOT_USE, couponBO.getMismatchReason());
         }
 
         // 3.1 计算可以优惠的金额
+        List<TradePriceCalculateRespBO.OrderItem> orderItems = filterMatchCouponOrderItems(result, coupon);
+        Integer totalPayPrice = TradePriceCalculatorHelper.calculateTotalPayPrice(orderItems);
         Integer couponPrice = getCouponPrice(coupon, totalPayPrice);
-        if (couponPrice <= totalPayPrice) {
-            throw exception(PRICE_CALCULATE_COUPON_PRICE_TOO_MUCH);
-        }
         // 3.2 计算分摊的优惠金额
         List<Integer> divideCouponPrices = TradePriceCalculatorHelper.dividePrice(orderItems, couponPrice);
 
@@ -76,7 +79,7 @@ public class TradeCouponPriceCalculator implements TradePriceCalculator {
         result.setCouponId(param.getCouponId());
         // 4.2 记录优惠明细
         TradePriceCalculatorHelper.addPromotion(result, orderItems,
-                param.getCouponId(), coupon.getName(), PromotionTypeEnum.COUPON.getType(),
+                param.getCouponId(), couponBO.getName(), PromotionTypeEnum.COUPON.getType(),
                 StrUtil.format("优惠劵:省 {} 元", TradePriceCalculatorHelper.formatPrice(couponPrice)),
                 divideCouponPrices);
         // 4.3 更新 SKU 优惠金额
@@ -88,6 +91,43 @@ public class TradeCouponPriceCalculator implements TradePriceCalculator {
         TradePriceCalculatorHelper.recountAllPrice(result);
     }
 
+    /**
+     * 计算用户的优惠劵列表(可用 + 不可用)
+     *
+     * @param coupons 优惠劵
+     * @param result 计算结果
+     * @return 优惠劵列表
+     */
+    private List<TradePriceCalculateRespBO.Coupon> calculateCoupons(List<CouponRespDTO> coupons,
+                                                                    TradePriceCalculateRespBO result) {
+        return convertList(coupons, coupon -> {
+            TradePriceCalculateRespBO.Coupon matchCoupon = BeanUtils.toBean(coupon, TradePriceCalculateRespBO.Coupon.class);
+            // 1.1 优惠劵未到使用时间
+            if (LocalDateTimeUtils.afterNow(coupon.getValidStartTime())) {
+                return matchCoupon.setMatch(false).setMismatchReason("优惠劵未到使用时间");
+            }
+            // 1.2 优惠劵没有匹配的商品
+            List<TradePriceCalculateRespBO.OrderItem> orderItems = filterMatchCouponOrderItems(result, coupon);
+            if (CollUtil.isEmpty(orderItems)) {
+                return matchCoupon.setMatch(false).setMismatchReason("优惠劵没有匹配的商品");
+            }
+            // 1.3 差 %1$,.2f 元可用优惠劵
+            Integer totalPayPrice = TradePriceCalculatorHelper.calculateTotalPayPrice(orderItems);
+            if (totalPayPrice < coupon.getUsePrice()) {
+                return matchCoupon.setMatch(false)
+                        .setMismatchReason(String.format("差 %1$,.2f 元可用优惠劵", (coupon.getUsePrice() - totalPayPrice) / 100D));
+            }
+            // 1.4 优惠金额超过订单金额
+            Integer couponPrice = getCouponPrice(coupon, totalPayPrice);
+            if (couponPrice >= totalPayPrice) {
+                return matchCoupon.setMatch(false).setMismatchReason("优惠金额超过订单金额");
+            }
+
+            // 2. 满足条件
+            return matchCoupon.setMatch(true);
+        });
+    }
+
     private Integer getCouponPrice(CouponRespDTO coupon, Integer totalPayPrice) {
         if (PromotionDiscountTypeEnum.PRICE.getType().equals(coupon.getDiscountType())) { // 减价
             return coupon.getDiscountPrice();

+ 8 - 3
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java

@@ -1,12 +1,13 @@
 package cn.iocoder.yudao.module.trade.service.price.calculator;
 
+import cn.hutool.core.collection.ListUtil;
 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
 import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
 import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponRespDTO;
-import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO;
 import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
 import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
 import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
+import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum;
 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum;
 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
 import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
@@ -14,8 +15,10 @@ import org.junit.jupiter.api.Test;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 
+import java.time.Duration;
 import java.util.ArrayList;
 
+import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
 import static java.util.Arrays.asList;
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -69,8 +72,10 @@ public class TradeCouponPriceCalculatorTest extends BaseMockitoUnitTest {
         CouponRespDTO coupon = randomPojo(CouponRespDTO.class, o -> o.setId(1024L).setName("程序员节")
                 .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductScopeValues(asList(1L, 2L))
                 .setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType())
-                .setDiscountPercent(50).setDiscountLimitPrice(70));
-        when(couponApi.validateCoupon(eq(new CouponValidReqDTO().setId(1024L).setUserId(233L)))).thenReturn(coupon);
+                .setDiscountPercent(50).setDiscountLimitPrice(70))
+                .setValidStartTime(addTime(Duration.ofDays(1))).setValidEndTime(addTime(Duration.ofDays(2)));
+        when(couponApi.getCouponListByUserId(eq(233L), eq(CouponStatusEnum.UNUSED.getStatus())))
+                .thenReturn(ListUtil.toList(coupon));
 
         // 调用
         tradeCouponPriceCalculator.calculate(param, result);

+ 1 - 1
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2TokenServiceImplTest.java

@@ -144,7 +144,7 @@ public class OAuth2TokenServiceImplTest extends BaseDbAndRedisUnitTest {
         // 调用,并断言
         assertServiceException(() -> oauth2TokenService.refreshAccessToken(refreshToken, clientId),
                 new ErrorCode(401, "刷新令牌已过期"));
-        assertEquals(0, oauth2RefreshTokenMapper.selectCount());
+        assertEquals(0, oauth2AccessTokenMapper.selectCount());
     }
 
     @Test

+ 30 - 30
yudao-server/pom.xml

@@ -33,11 +33,11 @@
         </dependency>
 
         <!-- 会员中心。默认注释,保证编译速度 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-member-biz</artifactId>
-            <version>${revision}</version>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>cn.iocoder.boot</groupId>-->
+<!--            <artifactId>yudao-module-member-biz</artifactId>-->
+<!--            <version>${revision}</version>-->
+<!--        </dependency>-->
 
         <!-- 数据报表。默认注释,保证编译速度 -->
 <!--        <dependency>-->
@@ -52,11 +52,11 @@
 <!--            <version>${revision}</version>-->
 <!--        </dependency>-->
         <!-- 支付服务。默认注释,保证编译速度 -->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-pay-biz</artifactId>
-            <version>${revision}</version>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>cn.iocoder.boot</groupId>-->
+<!--            <artifactId>yudao-module-pay-biz</artifactId>-->
+<!--            <version>${revision}</version>-->
+<!--        </dependency>-->
 
         <!-- 微信公众号模块。默认注释,保证编译速度 -->
 <!--        <dependency>-->
@@ -66,26 +66,26 @@
 <!--        </dependency>-->
 
         <!-- 商城相关模块。默认注释,保证编译速度-->
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-promotion-biz</artifactId>
-            <version>${revision}</version>
-        </dependency>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-product-biz</artifactId>
-            <version>${revision}</version>
-        </dependency>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-trade-biz</artifactId>
-            <version>${revision}</version>
-        </dependency>
-        <dependency>
-            <groupId>cn.iocoder.boot</groupId>
-            <artifactId>yudao-module-statistics-biz</artifactId>
-            <version>${revision}</version>
-        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>cn.iocoder.boot</groupId>-->
+<!--            <artifactId>yudao-module-promotion-biz</artifactId>-->
+<!--            <version>${revision}</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>cn.iocoder.boot</groupId>-->
+<!--            <artifactId>yudao-module-product-biz</artifactId>-->
+<!--            <version>${revision}</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>cn.iocoder.boot</groupId>-->
+<!--            <artifactId>yudao-module-trade-biz</artifactId>-->
+<!--            <version>${revision}</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>cn.iocoder.boot</groupId>-->
+<!--            <artifactId>yudao-module-statistics-biz</artifactId>-->
+<!--            <version>${revision}</version>-->
+<!--        </dependency>-->
 
         <!-- CRM 相关模块。默认注释,保证编译速度 -->
 <!--        <dependency>-->