Commit 2c39405bcea22737be3a49beb23cc67fa7a99c7d

Authored by YunaiV
1 parent 8ae8a4a6

promotion:完善的优惠卷的实体

yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/coupon/CouponStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.enums.coupon;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 优惠劵状态枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@AllArgsConstructor
  15 +@Getter
  16 +public enum CouponStatusEnum implements IntArrayValuable {
  17 +
  18 + UNUSED(1, "未使用"),
  19 + USED(2, "已使用"),
  20 + EXPIRE(3, "已过期"),
  21 + ;
  22 +
  23 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponStatusEnum::getValue).toArray();
  24 +
  25 + /**
  26 + * 值
  27 + */
  28 + private final Integer value;
  29 + /**
  30 + * 名字
  31 + */
  32 + private final String name;
  33 +
  34 + @Override
  35 + public int[] array() {
  36 + return ARRAYS;
  37 + }
  38 +
  39 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java
1 1 package cn.iocoder.yudao.module.promotion.dal.dataobject.coupon;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
  5 +import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
4 6 import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
  7 +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum;
  8 +import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum;
5 9 import com.baomidou.mybatisplus.annotation.KeySequence;
6 10 import com.baomidou.mybatisplus.annotation.TableField;
7 11 import com.baomidou.mybatisplus.annotation.TableName;
8   -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
9 12 import lombok.Data;
10 13 import lombok.EqualsAndHashCode;
11 14  
... ... @@ -14,9 +17,11 @@ import java.util.List;
14 17  
15 18 /**
16 19 * 优惠劵 DO
  20 + *
  21 + * @author 芋道源码
17 22 */
18 23 @TableName(value = "promotion_coupon", autoResultMap = true)
19   -@KeySequence("promotion_coupo_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  24 +@KeySequence("promotion_coupon_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
20 25 @Data
21 26 @EqualsAndHashCode(callSuper = true)
22 27 public class CouponDO extends BaseDO {
... ... @@ -35,21 +40,13 @@ public class CouponDO extends BaseDO {
35 40 /**
36 41 * 优惠劵名
37 42 *
38   - * 冗余自 {@link CouponTemplateDO} 的 title
39   - *
40   - * TODO 芋艿,暂时不考虑冗余的更新
  43 + * 冗余 {@link CouponTemplateDO#getName()}
41 44 */
42   - private String title;
43   -// /**
44   -// * 核销码
45   -// */
46   -// private String verifyCode;
  45 + private String name;
47 46 /**
48 47 * 优惠码状态
49 48 *
50   - * 1-未使用
51   - * 2-已使用
52   - * 3-已失效
  49 + * 枚举 {@link CouponStatusEnum}
53 50 */
54 51 private Integer status;
55 52  
... ... @@ -58,13 +55,14 @@ public class CouponDO extends BaseDO {
58 55 // ========== 领取情况 BEGIN ==========
59 56 /**
60 57 * 用户编号
  58 + *
  59 + * 关联 MemberUserDO 的 id 字段
61 60 */
62   - private Integer userId;
  61 + private Long userId;
63 62 /**
64 63 * 领取类型
65 64 *
66   - * 1 - 用户主动领取
67   - * 2 - 后台自动发放
  65 + * 枚举 {@link CouponTakeTypeEnum}
68 66 */
69 67 private Integer takeType;
70 68 // ========== 领取情况 END ==========
... ... @@ -72,8 +70,10 @@ public class CouponDO extends BaseDO {
72 70 // ========== 使用规则 BEGIN ==========
73 71 /**
74 72 * 是否设置满多少金额可用,单位:分
  73 + *
  74 + * 冗余 {@link CouponTemplateDO#getUsePrice()}
75 75 */
76   - private Integer priceAvailable;
  76 + private Integer usePrice;
77 77 /**
78 78 * 生效开始时间
79 79 */
... ... @@ -90,50 +90,49 @@ public class CouponDO extends BaseDO {
90 90 private Integer productScope;
91 91 /**
92 92 * 商品 SPU 编号的数组
  93 + *
  94 + * 冗余 {@link CouponTemplateDO#getProductSpuIds()}
93 95 */
94   - @TableField(typeHandler = JacksonTypeHandler.class)
95   - private List<Long> spuIds;
  96 + @TableField(typeHandler = LongListTypeHandler.class)
  97 + private List<Long> productSpuIds;
96 98 // ========== 使用规则 END ==========
97 99  
98 100 // ========== 使用效果 BEGIN ==========
99 101 /**
100   - * 优惠类型
  102 + * 折扣类型
101 103 *
102   - * 1-代金卷
103   - * 2-折扣卷
  104 + * 冗余 {@link CouponTemplateDO#getDiscountType()}
104 105 */
105   - private Integer preferentialType;
  106 + private Integer discountType;
106 107 /**
107   - * 折扣
  108 + * 折扣百分比
  109 + *
  110 + * 冗余 {@link CouponTemplateDO#getDiscountPercent()}
108 111 */
109   - private Integer percentOff;
  112 + private Integer discountPercent;
110 113 /**
111   - * 优惠金额,单位:分。
  114 + * 优惠金额,单位:分
  115 + *
  116 + * 冗余 {@link CouponTemplateDO#getDiscountPrice()}
112 117 */
113   - private Integer priceOff;
  118 + private Integer discountPrice;
114 119 /**
115   - * 折扣上限,仅在 {@link #preferentialType} 等于 2 时生效。
  120 + * 折扣上限,仅在 {@link #discountType} 等于 {@link PromotionDiscountTypeEnum#PERCENT} 时生效
116 121 *
117   - * 例如,折扣上限为 20 元,当使用 8 折优惠券,订单金额为 1000 元时,最高只可折扣 20 元,而非 80 元。
  122 + * 冗余 {@link CouponTemplateDO#getDiscountLimitPrice()}
118 123 */
119   - private Integer discountPriceLimit;
  124 + private Integer discountLimitPrice;
120 125 // ========== 使用效果 END ==========
121 126  
122 127 // ========== 使用情况 BEGIN ==========
123   -// /**
124   -// * 使用订单号
125   -// */
126   -// private Integer usedOrderId; // TODO 芋艿,暂时不考虑这个字段
127   -// /**
128   -// * 订单中优惠面值,单位:分
129   -// */
130   -// private Integer usedPrice; // TODO 芋艿,暂时不考虑这个字段
  128 + /**
  129 + * 使用订单号
  130 + */
  131 + private Long useOrderId;
131 132 /**
132 133 * 使用时间
133 134 */
134   - private Date usedTime;
135   -
136   - // TODO 芋艿,后续要加优惠劵的使用日志,因为下单后,可能会取消。
  135 + private Date useTime;
137 136  
138 137 // ========== 使用情况 END ==========
139 138  
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java
... ... @@ -21,6 +21,8 @@ import java.util.List;
21 21 * 优惠劵模板 DO
22 22 *
23 23 * 当用户领取时,会生成 {@link CouponDO} 优惠劵
  24 + *
  25 + * @author 芋道源码
24 26 */
25 27 @TableName(value = "promotion_coupon_template", autoResultMap = true)
26 28 @KeySequence("promotion_coupon_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java
... ... @@ -10,10 +10,7 @@ import cn.iocoder.yudao.module.promotion.convert.price.PriceConvert;
10 10 import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
11 11 import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO;
12 12 import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
13   -import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum;
14   -import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum;
15   -import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
16   -import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
  13 +import cn.iocoder.yudao.module.promotion.enums.common.*;
17 14 import cn.iocoder.yudao.module.promotion.service.coupon.CouponService;
18 15 import cn.iocoder.yudao.module.promotion.service.discount.DiscountService;
19 16 import cn.iocoder.yudao.module.promotion.service.reward.RewardService;
... ... @@ -283,7 +280,7 @@ public class PriceServiceImpl implements PriceService {
283 280 // 计算是否满足优惠劵的使用金额
284 281 Integer originPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum);
285 282 assert originPrice != null;
286   - if (originPrice < coupon.getPriceAvailable()) {
  283 + if (originPrice < coupon.getUsePrice()) {
287 284 throw exception(COUPON_NO_MATCH_MIN_PRICE);
288 285 }
289 286  
... ... @@ -294,7 +291,7 @@ public class PriceServiceImpl implements PriceService {
294 291 // TODO 芋艿:limit 不能超过最大价格
295 292 List<Integer> couponPartPrices = dividePrice(orderItems, couponPrice);
296 293 // 记录优惠明细
297   - addPromotion(priceCalculate, orderItems, coupon.getId(), coupon.getTitle(),
  294 + addPromotion(priceCalculate, orderItems, coupon.getId(), coupon.getName(),
298 295 PromotionTypeEnum.COUPON.getType(), PromotionLevelEnum.COUPON.getLevel(), couponPartPrices,
299 296 true, StrUtil.format("优惠劵:省 {} 元", formatPrice(couponPrice)));
300 297 // 修改 SKU 的分摊
... ... @@ -309,19 +306,18 @@ public class PriceServiceImpl implements PriceService {
309 306 return priceCalculate.getOrder().getItems();
310 307 }
311 308 return CollectionUtils.filterList(priceCalculate.getOrder().getItems(),
312   - orderItem -> coupon.getSpuIds().contains(orderItem.getSpuId()));
  309 + orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId()));
313 310 }
314 311  
315 312 private Integer getCouponPrice(CouponDO coupon, Integer originPrice) {
316   - // TODO 芋艿 getPreferentialType 的枚举判断
317   - if (coupon.getPreferentialType().equals(1)) { // 减价
318   - return coupon.getPriceOff();
319   - } else if (coupon.getPreferentialType().equals(2)) { // 打折
320   - Integer couponPrice = originPrice * coupon.getPercentOff() / 100;
321   - return coupon.getDiscountPriceLimit() == null ? couponPrice
322   - : Math.min(couponPrice, coupon.getDiscountPriceLimit()); // 优惠上限
  313 + if (PromotionDiscountTypeEnum.PRICE.getType().equals(coupon.getDiscountType())) { // 减价
  314 + return coupon.getDiscountPrice();
  315 + } else if (PromotionDiscountTypeEnum.PERCENT.getType().equals(coupon.getDiscountType())) { // 打折
  316 + int couponPrice = originPrice * coupon.getDiscountPercent() / 100;
  317 + return coupon.getDiscountLimitPrice() == null ? couponPrice
  318 + : Math.min(couponPrice, coupon.getDiscountLimitPrice()); // 优惠上限
323 319 }
324   - throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", coupon.toString()));
  320 + throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", coupon));
325 321 }
326 322  
327 323 // ========== 其它相对通用的方法 ==========
... ...
yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java
... ... @@ -373,7 +373,7 @@ public class PriceServiceTest extends BaseMockitoUnitTest {
373 373 ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L));
374 374 when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03));
375 375 // mock 方法(优惠劵 Coupon 信息)
376   - CouponDO coupon = randomPojo(CouponDO.class, o -> o.setId(1024L).setTitle("程序员节")
  376 + CouponDO coupon = randomPojo(CouponDO.class, o -> o.setId(1024L).setName("程序员节")
377 377 .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setSpuIds(asList(1L, 2L))
378 378 .setPriceAvailable(350).setPreferentialType(2).setPercentOff(50).setDiscountPriceLimit(70));
379 379 when(couponService.validCoupon(eq(1024L), eq(calculateReqDTO.getUserId()))).thenReturn(coupon);
... ...