diff --git a/mobile-web/src/page/shipping/order.vue b/mobile-web/src/page/shipping/order.vue index 9d677d2e9..3dee90f55 100644 --- a/mobile-web/src/page/shipping/order.vue +++ b/mobile-web/src/page/shipping/order.vue @@ -124,8 +124,9 @@ }; }, methods: { - onCouponChange(a, b, c) { - debugger; + onCouponChange(index) { + this.chosenCoupon = index; + this.showCouponPopup = false; }, onCouponExchange(a, b, c) { Dialog.alert({ @@ -204,7 +205,7 @@ endAt: card.validEndTime / 1000, // description: '述信息,优惠券可用时展示', reason: card.unavailableReason, - value: card.preferentialType === 1 ? card.priceOff : card.percentOff, + value: 0, // TODO ,需要服务端算 valueDesc: card.preferentialType === 1 ? card.priceOff / 100 : card.percentOff / 10.0, unitDesc: card.preferentialType === 1 ? '元' : '折' }) diff --git a/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersCartController.java b/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersCartController.java index 0f2abf46d..e24ca194f 100644 --- a/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersCartController.java +++ b/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersCartController.java @@ -96,7 +96,7 @@ public class UsersCartController { return CommonResult.success(result); } // 计算商品价格 - CommonResult calcOrderPriceResult = list0(cartItems); + CommonResult calcOrderPriceResult = list0(cartItems, null); if (calcOrderPriceResult.isError()) { return CommonResult.error(calcOrderPriceResult); } @@ -105,7 +105,7 @@ public class UsersCartController { } @GetMapping("/confirm_create_order") - public CommonResult getConfirmCreateOrder() { + public CommonResult getConfirmCreateOrder(@RequestParam("couponCardId") Integer couponCardId) { Integer userId = UserSecurityContextHolder.getContext().getUserId(); // 获得购物车中选中的 List cartItems = cartService.list(userId, true).getData(); @@ -117,7 +117,7 @@ public class UsersCartController { return CommonResult.success(result); } // 计算商品价格 - CommonResult calcOrderPriceResult = list0(cartItems); + CommonResult calcOrderPriceResult = list0(cartItems, couponCardId); if (calcOrderPriceResult.isError()) { return CommonResult.error(calcOrderPriceResult); } @@ -130,10 +130,12 @@ public class UsersCartController { .setCouponCards(couponCards)); } - private CommonResult list0(List cartItems) { + private CommonResult list0(List cartItems, Integer couponCardId) { // 创建计算的 DTO CalcOrderPriceDTO calcOrderPriceDTO = new CalcOrderPriceDTO() - .setItems(new ArrayList<>(cartItems.size())); + .setUserId(UserSecurityContextHolder.getContext().getUserId()) + .setItems(new ArrayList<>(cartItems.size())) + .setCouponCardId(couponCardId); for (CartItemBO item : cartItems) { calcOrderPriceDTO.getItems().add(new CalcOrderPriceDTO.Item(item.getSkuId(), item.getQuantity(), item.getSelected())); } diff --git a/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersOrderController.java b/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersOrderController.java index d83aa1638..4e5fe7b7b 100644 --- a/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersOrderController.java +++ b/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersOrderController.java @@ -93,10 +93,13 @@ public class UsersOrderController { @GetMapping("confirm_create_order") @ApiOperation("确认创建订单") public CommonResult getConfirmCreateOrder(@RequestParam("skuId") Integer skuId, - @RequestParam("quantity") Integer quantity) { + @RequestParam("quantity") Integer quantity, + @RequestParam("couponCardId") Integer couponCardId) { // 创建 CalcOrderPriceDTO 对象,并执行价格计算 CalcOrderPriceDTO calcOrderPriceDTO = new CalcOrderPriceDTO() - .setItems(Collections.singletonList(new CalcOrderPriceDTO.Item(skuId, quantity, true))); + .setUserId(UserSecurityContextHolder.getContext().getUserId()) + .setItems(Collections.singletonList(new CalcOrderPriceDTO.Item(skuId, quantity, true))) + .setCouponCardId(couponCardId); CommonResult calcOrderPriceResult = cartService.calcOrderPrice(calcOrderPriceDTO); if (calcOrderPriceResult.isError()) { return CommonResult.error(calcOrderPriceResult); diff --git a/order/order-application/src/main/java/cn/iocoder/mall/order/application/vo/UsersOrderConfirmCreateVO.java b/order/order-application/src/main/java/cn/iocoder/mall/order/application/vo/UsersOrderConfirmCreateVO.java index 7d5981f30..5551a7694 100644 --- a/order/order-application/src/main/java/cn/iocoder/mall/order/application/vo/UsersOrderConfirmCreateVO.java +++ b/order/order-application/src/main/java/cn/iocoder/mall/order/application/vo/UsersOrderConfirmCreateVO.java @@ -24,7 +24,6 @@ public class UsersOrderConfirmCreateVO { * 优惠劵列表 TODO 芋艿,后续改改 */ private List couponCards; - /** * 商品分组 * diff --git a/order/order-service-api/src/main/java/cn/iocoder/mall/order/api/bo/CalcOrderPriceBO.java b/order/order-service-api/src/main/java/cn/iocoder/mall/order/api/bo/CalcOrderPriceBO.java index 5ef38fcd5..98d8f68e1 100644 --- a/order/order-service-api/src/main/java/cn/iocoder/mall/order/api/bo/CalcOrderPriceBO.java +++ b/order/order-service-api/src/main/java/cn/iocoder/mall/order/api/bo/CalcOrderPriceBO.java @@ -18,6 +18,17 @@ public class CalcOrderPriceBO { * 商品分组数组 */ private List itemGroups; + /** + * 优惠劵编号 + */ + private Integer couponCardId; + /** + * 优惠劵减少的金额 + * + * 1. 若未使用优惠劵,返回 null + * 2. 该金额,已经分摊到每个 Item 的 discountTotal ,需要注意。 + */ + private Integer couponCardDiscountTotal; /** * 邮费信息 * diff --git a/order/order-service-api/src/main/java/cn/iocoder/mall/order/api/dto/CalcOrderPriceDTO.java b/order/order-service-api/src/main/java/cn/iocoder/mall/order/api/dto/CalcOrderPriceDTO.java index 88dd2e05d..71781754d 100644 --- a/order/order-service-api/src/main/java/cn/iocoder/mall/order/api/dto/CalcOrderPriceDTO.java +++ b/order/order-service-api/src/main/java/cn/iocoder/mall/order/api/dto/CalcOrderPriceDTO.java @@ -3,6 +3,7 @@ package cn.iocoder.mall.order.api.dto; import lombok.Data; import lombok.experimental.Accessors; +import javax.validation.constraints.NotNull; import java.util.List; /** @@ -12,9 +13,13 @@ import java.util.List; @Accessors(chain = true) public class CalcOrderPriceDTO { + @NotNull(message = "用户编号不能为空") + private Integer userId; /** - * 商品数组 + * 优惠劵编号 */ + private Integer couponCardId; + @NotNull(message = "商品数组不能为空") private List items; @Data diff --git a/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/CartServiceImpl.java b/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/CartServiceImpl.java index f6c54f887..a7f5aae9f 100644 --- a/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/CartServiceImpl.java +++ b/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/CartServiceImpl.java @@ -16,7 +16,9 @@ import cn.iocoder.mall.order.biz.dataobject.CartItemDO; import cn.iocoder.mall.product.api.ProductSpuService; import cn.iocoder.mall.product.api.bo.ProductSkuBO; import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO; +import cn.iocoder.mall.promotion.api.CouponService; import cn.iocoder.mall.promotion.api.PromotionActivityService; +import cn.iocoder.mall.promotion.api.bo.CouponCardDetailBO; import cn.iocoder.mall.promotion.api.bo.PromotionActivityBO; import cn.iocoder.mall.promotion.api.constant.*; import com.alibaba.dubbo.config.annotation.Reference; @@ -38,6 +40,8 @@ public class CartServiceImpl implements CartService { private ProductSpuService productSpuService; @Reference(validation = "true") private PromotionActivityService promotionActivityService; + @Reference(validation = "true") + private CouponService couponService; @Autowired private CartMapper cartMapper; @@ -152,6 +156,7 @@ public class CartServiceImpl implements CartService { @Override public CommonResult calcOrderPrice(CalcOrderPriceDTO calcOrderPriceDTO) { + // TODO 芋艿,补充一些表单校验。例如说,需要传入用户编号。 // 校验商品都存在 Map calcOrderItemMap = calcOrderPriceDTO.getItems().stream() .collect(Collectors.toMap(CalcOrderPriceDTO.Item::getSkuId, item -> item)); // KEY:skuId @@ -177,7 +182,15 @@ public class CartServiceImpl implements CartService { // 3. 计算【满减送】促销 List itemGroups = groupByFullPrivilege(items, activityList); calcOrderPriceBO.setItemGroups(itemGroups); - // 4. 计算最终的价格 + // 4. 计算优惠劵 + if (calcOrderPriceDTO.getCouponCardId() != null) { + CommonResult result = modifyPriceByCouponCard(calcOrderPriceDTO.getUserId(), calcOrderPriceDTO.getCouponCardId(), itemGroups); + if (result.isError()) { + return CommonResult.error(result); + } + calcOrderPriceBO.setCouponCardDiscountTotal(result.getData()); + } + // 5. 计算最终的价格 int buyTotal = 0; int discountTotal = 0; int presentTotal = 0; @@ -314,6 +327,72 @@ public class CartServiceImpl implements CartService { return itemGroups; } + private CommonResult modifyPriceByCouponCard(Integer userId, Integer couponCardId, List itemGroups) { + Assert.isTrue(couponCardId != null, "优惠劵编号不能为空"); + // 查询优惠劵 + CommonResult couponCardResult = couponService.getCouponCardDetail(userId, couponCardId); + if (couponCardResult.isError()) { + return CommonResult.error(couponCardResult); + } + CouponCardDetailBO couponCard = couponCardResult.getData(); + // 获得匹配的商品 + List items = new ArrayList<>(); + if (RangeTypeEnum.ALL.getValue().equals(couponCard.getRangeType())) { +// totalPrice = spus.stream().mapToInt(spu -> spu.getPrice() * spu.getQuantity()).sum(); + itemGroups.forEach(itemGroup -> items.addAll(itemGroup.getItems())); + } else if (RangeTypeEnum.PRODUCT_INCLUDE_PART.getValue().equals(couponCard.getRangeType())) { + itemGroups.forEach(itemGroup -> items.forEach(item -> { + if (couponCard.getRangeValues().contains(item.getSpu().getId())) { + items.add(item); + } + })); + } else if (RangeTypeEnum.PRODUCT_EXCLUDE_PART.getValue().equals(couponCard.getRangeType())) { + itemGroups.forEach(itemGroup -> items.forEach(item -> { + if (!couponCard.getRangeValues().contains(item.getSpu().getId())) { + items.add(item); + } + })); + } else if (RangeTypeEnum.CATEGORY_INCLUDE_PART.getValue().equals(couponCard.getRangeType())) { + itemGroups.forEach(itemGroup -> items.forEach(item -> { + if (couponCard.getRangeValues().contains(item.getSpu().getCid())) { + items.add(item); + } + })); + } else if (RangeTypeEnum.CATEGORY_EXCLUDE_PART.getValue().equals(couponCard.getRangeType())) { + itemGroups.forEach(itemGroup -> items.forEach(item -> { + if (!couponCard.getRangeValues().contains(item.getSpu().getCid())) { + items.add(item); + } + })); + } + // 判断是否符合条件 + int originalTotal = items.stream().mapToInt(CalcOrderPriceBO.Item::getPresentTotal).sum(); // 此处,指的是以优惠劵视角的原价 + if (originalTotal == 0 || originalTotal < couponCard.getPriceAvailable()) { + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.COUPON_CARD_NOT_MATCH.getCode()); // TODO 芋艿,这种情况,会出现错误码的提示,无法格式化出来。另外,这块的最佳实践,找人讨论下。 + } + // 计算价格 + // 获得到优惠信息,进行价格计算 + int presentTotal; + if (PreferentialTypeEnum.PRICE.getValue().equals(couponCard.getPreferentialType())) { // 减价 + // 计算循环次数。这样,后续优惠的金额就是相乘了 + presentTotal = originalTotal - couponCard.getPriceOff(); + Assert.isTrue(presentTotal > 0, "计算后,价格为负数:" + presentTotal); + } else if (PreferentialTypeEnum.DISCOUNT.getValue().equals(couponCard.getPreferentialType())) { // 打折 + presentTotal = originalTotal * couponCard.getPercentOff() / 100; + if (originalTotal - presentTotal > couponCard.getDiscountPriceLimit()) { + presentTotal = originalTotal - couponCard.getDiscountPriceLimit(); + } + } else { + throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", couponCard.toString())); + } + int discountTotal = originalTotal - presentTotal; + Assert.isTrue(discountTotal > 0, "计算后,不产生优惠:" + discountTotal); + // 按比例,拆分 presentTotal + splitDiscountPriceToItems(items, discountTotal, presentTotal); + // 返回优惠金额 + return CommonResult.success(originalTotal - presentTotal); + } + /** * 计算指定 SKU 在限时折扣下的价格 * @@ -393,11 +472,31 @@ public class CartServiceImpl implements CartService { } else { throw new IllegalArgumentException(String.format("满减送促销(%s) 的优惠类型不正确", activity.toString())); } - Integer discountTotal = originalTotal - presentTotal; + int discountTotal = originalTotal - presentTotal; if (discountTotal == 0) { return null; } // 按比例,拆分 presentTotal +// for (int i = 0; i < items.size(); i++) { +// CalcOrderPriceBO.Item item = items.get(i); +// Integer discountPart; +// if (i < items.size() - 1) { // 减一的原因,是因为拆分时,如果按照比例,可能会出现.所以最后一个,使用反减 +// discountPart = (int) (discountTotal * (1.0D * item.getPresentTotal() / presentTotal)); +// discountTotal -= discountPart; +// } else { +// discountPart = discountTotal; +// } +// Assert.isTrue(discountPart > 0, "优惠金额必须大于 0"); +// item.setDiscountTotal(item.getDiscountTotal() + discountPart); +// item.setPresentTotal(item.getBuyTotal() - item.getDiscountTotal()); +// item.setPresentPrice(item.getPresentTotal() / item.getBuyQuantity()); +// } + splitDiscountPriceToItems(items, discountTotal, presentTotal); + // 返回优惠金额 + return originalTotal - presentTotal; + } + + private void splitDiscountPriceToItems(List items, Integer discountTotal, Integer presentTotal) { for (int i = 0; i < items.size(); i++) { CalcOrderPriceBO.Item item = items.get(i); Integer discountPart; @@ -412,7 +511,6 @@ public class CartServiceImpl implements CartService { item.setPresentTotal(item.getBuyTotal() - item.getDiscountTotal()); item.setPresentPrice(item.getPresentTotal() / item.getBuyQuantity()); } - return originalTotal - presentTotal; } private PromotionActivityBO findPromotionActivityByType(List activityList, PromotionActivityTypeEnum type) { diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/CouponService.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/CouponService.java index ca12c3b85..d8891de8d 100644 --- a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/CouponService.java +++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/CouponService.java @@ -92,6 +92,15 @@ public interface CouponService { */ CommonResult cancelUseCouponCard(Integer userId, Integer couponCardId); + /** + * 获得指定优惠劵 + * + * @param userId 用户编号 + * @param couponCardId 优惠劵编号 + * @return 优惠劵 + */ + CommonResult getCouponCardDetail(Integer userId, Integer couponCardId); + /** * 获得用户所有优惠劵,并标明是否可用 * @@ -103,6 +112,7 @@ public interface CouponService { */ CommonResult> getCouponCardList(Integer userId, List spus); + // ========== 优惠码 ========== /** diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/CouponCardDetailBO.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/CouponCardDetailBO.java new file mode 100644 index 000000000..444fbfbf8 --- /dev/null +++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/CouponCardDetailBO.java @@ -0,0 +1,142 @@ +package cn.iocoder.mall.promotion.api.bo; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.Date; +import java.util.List; + +/** + * 优惠劵明细 BO 。 + * + * 主要是,会带上 {@link CouponTemplateBO} 的信息 + */ +@Data +@Accessors(chain = true) +public class CouponCardDetailBO { + + // ========== 基本信息 BEGIN ========== + /** + * 优惠劵编号 + */ + private Integer id; + /** + * 优惠劵(码)分组编号 + */ + private Integer templateId; + /** + * 优惠劵名 + */ + private String title; +// /** +// * 核销码 +// */ +// private String verifyCode; + /** + * 优惠码状态 + * + * 1-未使用 + * 2-已使用 + * 3-已失效 + */ + private Integer status; + + // ========== 基本信息 END ========== + + // ========== 领取情况 BEGIN ========== + /** + * 用户编号 + */ + private Integer userId; + /** + * 领取类型 + * + * 1 - 用户主动领取 + * 2 - 后台自动发放 + */ + private Integer takeType; + // ========== 领取情况 END ========== + + // ========== 使用规则 BEGIN ========== + /** + * 是否设置满多少金额可用,单位:分 + */ + private Integer priceAvailable; + /** + * 生效开始时间 + */ + private Date validStartTime; + /** + * 生效结束时间 + */ + private Date validEndTime; + // ========== 使用规则 END ========== + + // ========== 使用效果 BEGIN ========== + /** + * 优惠类型 + * + * 1-代金卷 + * 2-折扣卷 + */ + private Integer preferentialType; + /** + * 折扣 + */ + private Integer percentOff; + /** + * 优惠金额,单位:分。 + */ + private Integer priceOff; + /** + * 折扣上限,仅在 {@link #preferentialType} 等于 2 时生效。 + * + * 例如,折扣上限为 20 元,当使用 8 折优惠券,订单金额为 1000 元时,最高只可折扣 20 元,而非 80 元。 + */ + private Integer discountPriceLimit; + // ========== 使用效果 END ========== + + // ========== 使用情况 BEGIN ========== + /** + * 是否使用 + */ + private Boolean used; + /** + * 使用订单号 + */ + private Integer usedOrderId; + /** + * 订单中优惠面值,单位:分 + */ + private Integer usedPrice; + /** + * 使用时间 + */ + private Date usedTime; + + // TODO 芋艿,后续要加优惠劵的使用日志,因为下单后,可能会取消。 + + // ========== 使用情况 END ========== + + /** + * 创建时间 + */ + private Date createTime; + + // ========== FROM template 使用规则 BEGIN ========== + /** + * 可用范围的类型 + * + * 10-全部(ALL):所有可用 + * 20-部分(PART):部分商品可用,或指定商品可用 + * 21-部分(PART):部分商品不可用,或指定商品可用 + * 30-部分(PART):部分分类可用,或指定商品可用 + * 31-部分(PART):部分分类不可用,或指定商品可用 + */ + private Integer rangeType; + /** + * 指定商品 / 分类列表,使用逗号分隔商品编号 + */ + private List rangeValues; + +} diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/PromotionErrorCodeEnum.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/PromotionErrorCodeEnum.java index af574195b..3893cab2f 100644 --- a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/PromotionErrorCodeEnum.java +++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/PromotionErrorCodeEnum.java @@ -17,15 +17,21 @@ public enum PromotionErrorCodeEnum { // ========== COUPON TEMPLATE 模块 ========== - PRODUCT_TEMPLATE_NOT_EXISTS(1006002000, "优惠劵模板(码)不存在"), - PRODUCT_TEMPLATE_NOT_CARD(1006002001, "不是优惠劵模板"), - PRODUCT_TEMPLATE_NOT_CODE(1006002002, "不是优惠码模板"), - PRODUCT_TEMPLATE_TOTAL_CAN_NOT_REDUCE(1006002003, "优惠劵(码)模板的发放数量不能减小"), - PRODUCT_TEMPLATE_STATUS_NOT_ENABLE(1006002004, "优惠劵模板(码)未开启"), - PRODUCT_TEMPLATE_TOTAL_NOT_ENOUGH(1006002005, "优惠劵(码)模板的发放量不足"), - PRODUCT_TEMPLATE_CARD_ADD_EXCEED_QUOTA(1006002006, "优惠劵领取到达上限"), + COUPON_TEMPLATE_NOT_EXISTS(1006002000, "优惠劵模板(码)不存在"), + COUPON_TEMPLATE_NOT_CARD(1006002001, "不是优惠劵模板"), + COUPON_TEMPLATE_NOT_CODE(1006002002, "不是优惠码模板"), + COUPON_TEMPLATE_TOTAL_CAN_NOT_REDUCE(1006002003, "优惠劵(码)模板的发放数量不能减小"), + COUPON_TEMPLATE_STATUS_NOT_ENABLE(1006002004, "优惠劵模板(码)未开启"), + COUPON_TEMPLATE_TOTAL_NOT_ENOUGH(1006002005, "优惠劵(码)模板的发放量不足"), + COUPON_TEMPLATE_CARD_ADD_EXCEED_QUOTA(1006002006, "优惠劵领取到达上限"), + + // ========== COUPON CARD 模块 ========== + COUPON_CARD_NOT_EXISTS(1006003000, "优惠劵不存在"), + COUPON_CARD_ERROR_USER(1006003001, "优惠劵不属于当前用户"), + COUPON_CARD_NOT_MATCH(1006003002, "优惠劵不匹配,无法使用"), ; + private final int code; private final String message; diff --git a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/convert/CouponCardConvert.java b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/convert/CouponCardConvert.java index f66807fe8..b69663b9f 100644 --- a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/convert/CouponCardConvert.java +++ b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/convert/CouponCardConvert.java @@ -2,6 +2,7 @@ package cn.iocoder.mall.promotion.biz.convert; import cn.iocoder.mall.promotion.api.bo.CouponCardAvailableBO; import cn.iocoder.mall.promotion.api.bo.CouponCardBO; +import cn.iocoder.mall.promotion.api.bo.CouponCardDetailBO; import cn.iocoder.mall.promotion.biz.dataobject.CouponCardDO; import org.mapstruct.Mapper; import org.mapstruct.Mappings; @@ -23,6 +24,9 @@ public interface CouponCardConvert { @Mappings({}) CouponCardBO convert(CouponCardDO card); + @Mappings({}) + CouponCardDetailBO convert2(CouponCardDO card); + @Mappings({}) CouponCardAvailableBO convert2(CouponCardDO card, boolean x); // TODO 芋艿,临时用来解决 mapstruct 无法正确匹配方法的问题 diff --git a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/CouponServiceImpl.java b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/CouponServiceImpl.java index 4b4825c3b..a8e834102 100644 --- a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/CouponServiceImpl.java +++ b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/CouponServiceImpl.java @@ -20,7 +20,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.*; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @Service // 实际上不用添加。添加的原因是,必须 Spring 报错提示 @@ -99,15 +102,15 @@ public class CouponServiceImpl implements CouponService { // 校验 CouponCardTemplate 存在 CouponTemplateDO template = couponTemplateMapper.selectById(couponCardTemplateUpdateDTO.getId()); if (template == null) { - return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_NOT_EXISTS.getCode()); + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_EXISTS.getCode()); } // 校验 CouponCardTemplate 是 CARD if (!CouponTemplateTypeEnum.CARD.getValue().equals(template.getType())) { - return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_NOT_CARD.getCode()); + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_CARD.getCode()); } // 校验发放数量不能减少 if (couponCardTemplateUpdateDTO.getTotal() < template.getTotal()) { - return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_TOTAL_CAN_NOT_REDUCE.getCode()); + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.COUPON_TEMPLATE_TOTAL_CAN_NOT_REDUCE.getCode()); } // 更新优惠劵模板到数据库 CouponTemplateDO updateTemplateDO = CouponTemplateConvert.INSTANCE.convert(couponCardTemplateUpdateDTO); @@ -121,7 +124,7 @@ public class CouponServiceImpl implements CouponService { // 校验 CouponCardTemplate 存在 CouponTemplateDO template = couponTemplateMapper.selectById(couponTemplateId); if (template == null) { - return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_NOT_EXISTS.getCode()); + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_EXISTS.getCode()); } // 更新到数据库 CouponTemplateDO updateTemplateDO = new CouponTemplateDO().setId(couponTemplateId).setStatus(status); @@ -195,28 +198,28 @@ public class CouponServiceImpl implements CouponService { // 校验 CouponCardTemplate 存在 CouponTemplateDO template = couponTemplateMapper.selectById(couponTemplateId); if (template == null) { - return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_NOT_EXISTS.getCode()); + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_EXISTS.getCode()); } // 校验 CouponCardTemplate 是 CARD if (!CouponTemplateTypeEnum.CARD.getValue().equals(template.getType())) { - return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_NOT_CARD.getCode()); + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_CARD.getCode()); } // 校验 CouponCardTemplate 状态是否开启 if (!CouponTemplateStatusEnum.ENABLE.getValue().equals(template.getStatus())) { - return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_STATUS_NOT_ENABLE.getCode()); + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.COUPON_TEMPLATE_STATUS_NOT_ENABLE.getCode()); } // 校验 CouponCardTemplate 是否到达可领取的上限 if (template.getStatFetchNum() > template.getTotal()) { - return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_TOTAL_NOT_ENOUGH.getCode()); + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.COUPON_TEMPLATE_TOTAL_NOT_ENOUGH.getCode()); } // 校验单人可领取优惠劵是否到达上限 if (couponCardMapper.selectCountByUserIdAndTemplateId(userId, couponTemplateId) > template.getQuota()) { - return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_CARD_ADD_EXCEED_QUOTA.getCode()); + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.COUPON_TEMPLATE_CARD_ADD_EXCEED_QUOTA.getCode()); } // 增加优惠劵已领取量 int updateTemplateCount = couponTemplateMapper.updateStatFetchNumIncr(couponTemplateId); if (updateTemplateCount == 0) { // 超过 CouponCardTemplate 发放量 - return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_TEMPLATE_CARD_ADD_EXCEED_QUOTA.getCode()); + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.COUPON_TEMPLATE_CARD_ADD_EXCEED_QUOTA.getCode()); } // 创建优惠劵 // 1. 基本信息 + 领取情况 @@ -250,6 +253,28 @@ public class CouponServiceImpl implements CouponService { return null; } + @Override + public CommonResult getCouponCardDetail(Integer userId, Integer couponCardId) { + // 查询优惠劵 + CouponCardDO card = couponCardMapper.selectById(couponCardId); + if (card == null) { + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.COUPON_CARD_NOT_EXISTS.getCode()); + } + if (!userId.equals(card.getUserId())) { + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.COUPON_CARD_ERROR_USER.getCode()); + } + // 查询优惠劵模板 + CouponTemplateDO template = couponTemplateMapper.selectById(card.getTemplateId()); + if (template == null) { + return ServiceExceptionUtil.error(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_EXISTS.getCode()); + } + // 拼接结果 + CouponCardDetailBO detail = CouponCardConvert.INSTANCE.convert2(card); + detail.setRangeType(template.getRangeType()); + detail.setRangeValues(StringUtil.splitToInt(template.getRangeValues(), ",")); + return CommonResult.success(detail); + } + @Override public CommonResult> getCouponCardList(Integer userId, List spus) { // 查询用户未使用的优惠劵列表