Quellcode durchsuchen

用户领取优惠券功能开发

qizai vor 1 Jahr
Ursprung
Commit
0858d4335b

+ 32 - 0
vehicle-api/src/main/java/com/chelvc/cloud/vehicle/api/constant/CouponClaimType.java

@@ -0,0 +1,32 @@
+package com.chelvc.cloud.vehicle.api.constant;
+
+import com.chelvc.framework.common.model.Enumeration;
+import lombok.Getter;
+
+/**
+ * 优惠券获取方式枚举
+ *
+ * @author qizai
+ * @date 2023/9/10
+ */
+@Getter
+public enum CouponClaimType implements Enumeration {
+    /**
+     * 免费领取
+     */
+    FREE("免费领取"),
+
+    /**
+     * 活动领取
+     */
+    ACTIVITY("活动领取");
+
+    /**
+     * 类型描述
+     */
+    private final String description;
+
+    CouponClaimType(String description) {
+        this.description = description;
+    }
+}

+ 39 - 0
vehicle-api/src/main/java/com/chelvc/cloud/vehicle/api/constant/PromotionStatus.java

@@ -0,0 +1,39 @@
+package com.chelvc.cloud.vehicle.api.constant;
+
+import com.chelvc.framework.common.model.Enumeration;
+import lombok.Getter;
+
+/**
+ * 促销状态枚举
+ *
+ * @author qizai
+ * @date 2023/9/10
+ */
+@Getter
+public enum PromotionStatus implements Enumeration {
+    /**
+     * 新建
+     */
+    NEW("新建"),
+    /**
+     * 开始
+     */
+    START("开始"),
+    /**
+     * 结束
+     */
+    END("结束"),
+    /**
+     * 关闭
+     */
+    CLOSE("关闭");
+
+    /**
+     * 状态描述
+     */
+    private final String description;
+
+    PromotionStatus(String description) {
+        this.description = description;
+    }
+}

+ 0 - 1
vehicle-api/src/main/java/com/chelvc/cloud/vehicle/api/service/CouponService.java

@@ -1,6 +1,5 @@
 package com.chelvc.cloud.vehicle.api.service;
 
-
 import com.chelvc.cloud.vehicle.api.dto.CouponDTO;
 import com.chelvc.cloud.vehicle.api.param.CouponModifyParam;
 import com.chelvc.cloud.vehicle.api.param.CouponPagingParam;

+ 8 - 0
vehicle-api/src/main/java/com/chelvc/cloud/vehicle/api/service/UserCouponService.java

@@ -55,4 +55,12 @@ public interface UserCouponService {
      * @return 优惠券领取记录分页信息
      */
     Pagination<UserCouponDTO> getUserCouponPaging(UserCouponPagingParam param);
+
+    /**
+     * 领取优惠券
+     *
+     * @param couponId 优惠券ID
+     * @return 优惠券领取记录主键
+     */
+    Long claimCoupon(Long couponId);
 }

+ 8 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/dao/CouponMapper.java

@@ -26,4 +26,12 @@ public interface CouponMapper extends BaseMapper<Coupon> {
      */
     List<CouponDTO> listUserGoodsActiveCoupons(@Param("userId") Long userId,
                                                @Param("goodsCouponIds") Collection<Long> goodsCouponIds);
+
+    /**
+     * 修改优惠券已领取数量
+     *
+     * @param id   优惠券ID
+     * @param receiveNum 领取数量
+     */
+    void updateCouponReceivedNum(@Param("id") Long id, @Param("receiveNum") Integer receiveNum);
 }

+ 32 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/entity/Coupon.java

@@ -4,8 +4,10 @@ import java.util.Date;
 
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
+import com.chelvc.cloud.vehicle.api.constant.CouponClaimType;
 import com.chelvc.cloud.vehicle.api.constant.CouponStatus;
 import com.chelvc.cloud.vehicle.api.constant.CouponType;
+import com.chelvc.cloud.vehicle.api.constant.PromotionStatus;
 import com.chelvc.framework.database.entity.ModifyEntity;
 import lombok.AllArgsConstructor;
 import lombok.Data;
@@ -77,4 +79,34 @@ public class Coupon extends ModifyEntity<Long> {
      * 优惠券状态
      */
     private CouponStatus status;
+
+    /**
+     * 限制领取数量
+     */
+    private Integer limitNum;
+
+    /**
+     * 发行数量
+     */
+    private Integer publishNum;
+
+    /**
+     * 已被领取的数量
+     */
+    private Integer receivedNum;
+
+    /**
+     * 已被使用的数量
+     */
+    private Integer usedNum;
+
+    /**
+     * 优惠券获取方式类型
+     */
+    private CouponClaimType claimType;
+
+    /**
+     * 促销状态
+     */
+    private PromotionStatus promotionStatus;
 }

+ 8 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/CouponService.java

@@ -22,4 +22,12 @@ public interface CouponService extends IService<Coupon> {
      * @return 优惠券列表
      */
     List<CouponDTO> listUserGoodsActiveCoupons(Long userId, Collection<Long> goodsCouponIds);
+
+    /**
+     * 修改优惠券已领取数量
+     *
+     * @param couponId   优惠券ID
+     * @param receiveNum 领取数量
+     */
+    void updateCouponReceivedNum(Long couponId, Integer receiveNum);
 }

+ 12 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/CouponServiceImpl.java

@@ -5,8 +5,10 @@ import java.util.List;
 import java.util.Objects;
 import java.util.stream.Collectors;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.chelvc.cloud.vehicle.api.constant.PromotionStatus;
 import com.chelvc.cloud.vehicle.api.dto.CouponDTO;
 import com.chelvc.cloud.vehicle.api.param.CouponModifyParam;
 import com.chelvc.cloud.vehicle.api.param.CouponPagingParam;
@@ -14,6 +16,7 @@ import com.chelvc.cloud.vehicle.server.copier.CouponCopier;
 import com.chelvc.cloud.vehicle.server.dao.CouponMapper;
 import com.chelvc.cloud.vehicle.server.entity.Coupon;
 import com.chelvc.cloud.vehicle.server.service.CouponService;
+import com.chelvc.framework.base.exception.ResourceUnavailableException;
 import com.chelvc.framework.base.util.ResourceUtils;
 import com.chelvc.framework.common.model.Pagination;
 import com.chelvc.framework.database.context.DatabaseContextHolder;
@@ -92,6 +95,15 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
         return PagingUtils.convert(page, clients);
     }
 
+    @Override
+    public void updateCouponReceivedNum(Long couponId, Integer receiveNum) {
+        Coupon coupon = this.getById(couponId);
+        if (Objects.isNull(coupon)) {
+            throw new ResourceUnavailableException("当前优惠券不存在");
+        }
+        this.baseMapper.updateCouponReceivedNum(couponId, receiveNum);
+    }
+
     /**
      * 转换优惠券信息
      *

+ 47 - 0
vehicle-server/src/main/java/com/chelvc/cloud/vehicle/server/service/impl/UserCouponServiceImpl.java

@@ -1,7 +1,10 @@
 package com.chelvc.cloud.vehicle.server.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.chelvc.cloud.vehicle.api.constant.CouponClaimType;
+import com.chelvc.cloud.vehicle.api.constant.PromotionStatus;
 import com.chelvc.cloud.vehicle.api.constant.UserCouponStatus;
 import com.chelvc.cloud.vehicle.api.dto.UserCouponDTO;
 import com.chelvc.cloud.vehicle.api.param.UserCouponModifyParam;
@@ -9,9 +12,12 @@ import com.chelvc.cloud.vehicle.api.param.UserCouponPagingParam;
 import com.chelvc.cloud.vehicle.api.param.UserCouponQueryParam;
 import com.chelvc.cloud.vehicle.server.copier.UserCouponCopier;
 import com.chelvc.cloud.vehicle.server.dao.UserCouponMapper;
+import com.chelvc.cloud.vehicle.server.entity.Coupon;
 import com.chelvc.cloud.vehicle.server.entity.UserCoupon;
+import com.chelvc.cloud.vehicle.server.service.CouponService;
 import com.chelvc.cloud.vehicle.server.service.UserCouponService;
 import com.chelvc.framework.base.context.SessionContextHolder;
+import com.chelvc.framework.base.exception.ResourceUnavailableException;
 import com.chelvc.framework.base.util.ResourceUtils;
 import com.chelvc.framework.common.model.Pagination;
 import com.chelvc.framework.database.util.PagingUtils;
@@ -37,6 +43,8 @@ import java.util.stream.Collectors;
 public class UserCouponServiceImpl extends ServiceImpl<UserCouponMapper, UserCoupon> implements UserCouponService,
         com.chelvc.cloud.vehicle.api.service.UserCouponService {
 
+    private final CouponService couponService;
+
     @Override
     public List<UserCouponDTO> listUserCoupons(@NonNull UserCouponQueryParam param) {
         Long userId = SessionContextHolder.getId();
@@ -99,6 +107,45 @@ public class UserCouponServiceImpl extends ServiceImpl<UserCouponMapper, UserCou
         return PagingUtils.convert(page, userCoupons);
     }
 
+    @Override
+    public Long claimCoupon(@NonNull Long couponId) {
+        Coupon coupon = ResourceUtils.required(couponService.getById(couponId), "优惠券不存在");
+        if (CouponClaimType.FREE.equals(coupon.getClaimType())) {
+            throw new ResourceUnavailableException("当前优惠券不允许免费领取");
+        }
+        Long userId = SessionContextHolder.getId();
+        // 检查该用户可领取的优惠券的数量
+        this.checkCouponLimit(coupon, userId);
+        // 保存优惠券领取记录
+        UserCoupon userCoupon = UserCoupon.builder().userId(userId).couponId(couponId)
+                .type(coupon.getType()).used(false).build();
+        this.save(userCoupon);
+        // 修改优惠券的领取数量
+        couponService.updateCouponReceivedNum(couponId, 1);
+        return userCoupon.getId();
+    }
+
+    /**
+     * 检查该用户可领取的优惠券的数量
+     *
+     * @param coupon 要领取的优惠券
+     * @param userId 用户ID
+     */
+    public void checkCouponLimit(Coupon coupon, Long userId) {
+        Integer haveCoupons = this.lambdaQuery()
+                .eq(UserCoupon::getUserId, userId)
+                .eq(UserCoupon::getCouponId, coupon.getId()).count();
+        if (!PromotionStatus.START.name().equals(coupon.getPromotionStatus())) {
+            throw new ResourceUnavailableException("当前优惠券已经被领取完了,下次要早点来哦");
+        }
+        if (coupon.getPublishNum() != 0 && coupon.getReceivedNum() >= coupon.getPublishNum()) {
+            throw new ResourceUnavailableException("优惠券剩余领取数量不足");
+        }
+        if (!coupon.getLimitNum().equals(0) && haveCoupons >= coupon.getLimitNum()) {
+            throw new ResourceUnavailableException("超出领取限制,此优惠券最多领取" + coupon.getLimitNum() + "张");
+        }
+    }
+
     /**
      * 转换优惠券领取记录信息
      *

+ 5 - 0
vehicle-server/src/main/resources/mapper/CouponMapper.xml

@@ -19,4 +19,9 @@
             and cn.expiration > now() and cn.status = 'ONLINE'
         </where>
     </select>
+
+    <update id="updateCouponReceivedNum">
+        update coupon cn set cn.received_num = cn.received_num + #{receiveNum}
+        where cn.id = #{id}
+    </update>
 </mapper>