Kaynağa Gözat

feat(coupon): 新增小程序用户领取优惠券功能

- 新增 AppletGainCouponForm 表单对象用于接收优惠券编码和用户ID
- 在 AppletUserController 中添加 /gainCoupon 接口供小程序调用
- CouponService 接口新增 gainCoupon 方法定义
- CouponServiceImpl 实现领取优惠券逻辑,包括模板校验、重复领取判断等
- 优化部分代码依赖注入方式,将 CouponTemplateMapper 替换为 CouponTemplateService
- 增加对优惠券模板有效性校验及异常处理机制
wzq 22 saat önce
ebeveyn
işleme
96030bad28

+ 8 - 0
src/main/java/com/zsElectric/boot/business/controller/applet/AppletUserController.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.zsElectric.boot.business.model.entity.UserFeedback;
 import com.zsElectric.boot.business.model.form.UserFeedbackForm;
 import com.zsElectric.boot.business.model.form.applet.AppFeedbackForm;
+import com.zsElectric.boot.business.model.form.applet.AppletGainCouponForm;
 import com.zsElectric.boot.business.model.query.CouponTemplateQuery;
 import com.zsElectric.boot.business.model.query.applet.AppCouponQuery;
 import com.zsElectric.boot.business.model.vo.CouponTemplateVO;
@@ -96,4 +97,11 @@ public class AppletUserController {
         IPage<CouponTemplateVO> result = couponTemplateService.getCouponTemplatePage(CouponTemplateQuery);
         return Result.success(result);
     }
+
+    @Operation(summary = "领取优惠券")
+    @PostMapping("/gainCoupon")
+    public Result<Boolean> gainCoupon(@RequestBody AppletGainCouponForm formData) {
+        Boolean result = couponService.gainCoupon(formData);
+        return Result.judge(result);
+    }
 }

+ 25 - 0
src/main/java/com/zsElectric/boot/business/model/form/applet/AppletGainCouponForm.java

@@ -0,0 +1,25 @@
+package com.zsElectric.boot.business.model.form.applet;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.Size;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+@Getter
+@Setter
+@Schema(description = "获取优惠券表单对象")
+public class AppletGainCouponForm implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    @Schema(description = "优惠券编码")
+    private String couponCode;
+
+    @Schema(description = "用户ID", hidden = true)
+    private Long userId;
+
+}

+ 3 - 0
src/main/java/com/zsElectric/boot/business/service/CouponService.java

@@ -2,6 +2,7 @@ package com.zsElectric.boot.business.service;
 
 import com.zsElectric.boot.business.model.entity.Coupon;
 import com.zsElectric.boot.business.model.form.CouponForm;
+import com.zsElectric.boot.business.model.form.applet.AppletGainCouponForm;
 import com.zsElectric.boot.business.model.query.CouponQuery;
 import com.zsElectric.boot.business.model.query.applet.AppCouponQuery;
 import com.zsElectric.boot.business.model.vo.CouponVO;
@@ -116,4 +117,6 @@ public interface CouponService extends IService<Coupon> {
     IPage<CouponVO> getUserCouponPage(AppCouponQuery queryParams);
 
     AppCouponStatusNumVO getCouponStatusNum(Long userId);
+
+    Boolean gainCoupon(AppletGainCouponForm formData);
 }

+ 44 - 5
src/main/java/com/zsElectric/boot/business/service/impl/CouponServiceImpl.java

@@ -1,8 +1,11 @@
 package com.zsElectric.boot.business.service.impl;
 
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.zsElectric.boot.business.model.form.applet.AppletGainCouponForm;
 import com.zsElectric.boot.business.model.query.applet.AppCouponQuery;
 import com.zsElectric.boot.business.model.vo.applet.AppCouponStatusNumVO;
+import com.zsElectric.boot.business.service.CouponTemplateService;
 import com.zsElectric.boot.core.exception.CouponException;
 import com.zsElectric.boot.business.mapper.CouponTemplateMapper;
 import com.zsElectric.boot.business.model.entity.CouponTemplate;
@@ -41,7 +44,7 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
 
     private final CouponConverter couponConverter;
 
-    private final CouponTemplateMapper couponTemplateMapper;
+    private final CouponTemplateService couponTemplateService;
 
     /**
     * 获取优惠劵分页列表
@@ -122,7 +125,7 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
     @Transactional(rollbackFor = Exception.class)
     public Long takeCoupon(Long templateId, Long userId, Integer takeType) {
         // 获取优惠券模板
-        CouponTemplate template = couponTemplateMapper.selectById(templateId);
+        CouponTemplate template = couponTemplateService.getById(templateId);
         if (template == null) {
             throw new CouponException("优惠券模板不存在");
         }
@@ -159,7 +162,7 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
 
         // 更新模板已发放数量
         template.setTotalCountAll(template.getTotalCountAll() != null ? template.getTotalCountAll() + 1 : 1);
-        couponTemplateMapper.updateById(template);
+        couponTemplateService.updateById(template);
 
         return coupon.getId();
     }
@@ -178,7 +181,7 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
         }
 
         // 获取优惠券模板
-        CouponTemplate template = couponTemplateMapper.selectById(coupon.getTemplateId());
+        CouponTemplate template = couponTemplateService.getById(coupon.getTemplateId());
         if (template == null) {
             return BigDecimal.ZERO;
         }
@@ -296,7 +299,7 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
         }
 
         // 获取优惠券模板
-        CouponTemplate template = couponTemplateMapper.selectById(coupon.getTemplateId());
+        CouponTemplate template = couponTemplateService.getById(coupon.getTemplateId());
         if (template == null) {
             return false;
         }
@@ -432,4 +435,40 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
         return this.baseMapper.getCouponStatusNum(userId);
     }
 
+    @Override
+    public Boolean gainCoupon(AppletGainCouponForm formData) {
+        formData.setUserId(SecurityUtils.getUserId());
+        //查询优惠券模板是否存在且可用
+        CouponTemplate template = couponTemplateService.getOne(Wrappers.lambdaQuery(CouponTemplate.class)
+                .eq(CouponTemplate::getCode, formData.getCouponCode()));
+        if (ObjectUtil.isEmpty(template)) {
+            throw new CouponException("优惠券不存在");
+        }
+        if (!couponTemplateService.isValidTemplate(template.getId())) {
+            throw new CouponException("优惠券已失效");
+        }
+        //判断当前用户是否已经领取过该优惠券
+        Coupon coupon = this.getOne(Wrappers.lambdaQuery(Coupon.class)
+                .eq(Coupon::getUserId, formData.getUserId())
+                .eq(Coupon::getCouponCode, formData.getCouponCode())
+        );
+        if (ObjectUtil.isNotEmpty(coupon)) {
+            throw new CouponException("当前用户已经领取过该优惠券");
+        }
+        Coupon userCoupon = new Coupon();
+        userCoupon.setTemplateId(template.getId());
+        userCoupon.setName(template.getName());
+        userCoupon.setCouponCode(template.getCode());
+        userCoupon.setStatus(1);
+        userCoupon.setDescription(template.getDescription());
+        userCoupon.setUserId(formData.getUserId());
+        userCoupon.setTakeType(1);
+
+        LocalDateTime now = LocalDateTime.now();
+
+        userCoupon.setTakeTime(now);
+        userCoupon.setExpireTime(now.plusDays(template.getFailureTime()));
+        return this.save(userCoupon);
+    }
+
 }