瀏覽代碼

优惠券:过期定时任务

owen 1 年之前
父節點
當前提交
2766dd672a

+ 4 - 0
yudao-module-mall/yudao-module-promotion-biz/pom.xml

@@ -45,6 +45,10 @@
             <groupId>cn.iocoder.boot</groupId>
             <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
         </dependency>
+        <dependency>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
+        </dependency>
         <dependency>
             <groupId>cn.iocoder.boot</groupId>
             <artifactId>yudao-spring-boot-starter-biz-weixin</artifactId>

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

@@ -13,6 +13,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.github.yulichang.toolkit.MPJWrappers;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.List;
 import java.util.function.Function;
@@ -94,4 +95,11 @@ public interface CouponMapper extends BaseMapperX<CouponDO> {
                         .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)
+                .le(CouponDO::getValidEndTime, validEndTime)
+        );
+    }
 }

+ 29 - 0
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/job/CouponExpireJob.java

@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.promotion.job;
+
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
+import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
+import cn.iocoder.yudao.module.promotion.service.coupon.CouponService;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * 优惠券过期 Job
+ *
+ * @author owen
+ */
+@Component
+@TenantJob
+public class CouponExpireJob implements JobHandler {
+
+    @Resource
+    private CouponService couponService;
+
+    @Override
+    public String execute(String param) {
+        int count = couponService.expireCoupon();
+        return StrUtil.format("过期优惠券 {} 个", count);
+    }
+
+}

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

@@ -157,4 +157,11 @@ public interface CouponService {
      * @return 优惠券列表
      */
     List<CouponDO> getMatchCouponList(Long userId, AppCouponMatchReqVO matchReqVO);
+
+    /**
+     * 过期优惠券
+     *
+     * @return 过期数量
+     */
+    int expireCoupon();
 }

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

@@ -6,6 +6,7 @@ import cn.hutool.core.collection.ListUtil;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.spring.SpringUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
@@ -21,6 +22,7 @@ import cn.iocoder.yudao.module.promotion.enums.coupon.CouponStatusEnum;
 import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTakeTypeEnum;
 import cn.iocoder.yudao.module.promotion.enums.coupon.CouponTemplateValidityTypeEnum;
 import cn.iocoder.yudao.module.promotion.service.coupon.bo.CouponTakeCountBO;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
@@ -43,6 +45,7 @@ import static java.util.Arrays.asList;
  *
  * @author 芋道源码
  */
+@Slf4j
 @Service
 @Validated
 public class CouponServiceImpl implements CouponService {
@@ -193,6 +196,43 @@ public class CouponServiceImpl implements CouponService {
                 matchReqVO.getPrice(), matchReqVO.getSpuIds(), matchReqVO.getCategoryIds());
     }
 
+    @Override
+    public int expireCoupon() {
+        // 1. 查询待过期的优惠券
+        List<CouponDO> list = couponMapper.selectListByStatusAndValidEndTimeLe(
+                CouponStatusEnum.UNUSED.getStatus(), LocalDateTime.now());
+        if (CollUtil.isEmpty(list)) {
+            return 0;
+        }
+
+        // 2. 遍历执行
+        int count = 0;
+        for (CouponDO coupon : list) {
+            try {
+                boolean success = getSelf().expireCoupon(coupon);
+                if (success) {
+                    count++;
+                }
+            } catch (Exception e) {
+                log.error("[expireCoupon][coupon({}) 更新为已过期失败]", coupon.getId(), e);
+            }
+        }
+        return count;
+    }
+
+    private boolean expireCoupon(CouponDO coupon) {
+        // 更新记录状态
+        CouponDO updateObj = new CouponDO().setStatus(CouponStatusEnum.EXPIRE.getStatus());
+        int updateRows = couponMapper.updateByIdAndStatus(coupon.getId(), CouponStatusEnum.UNUSED.getStatus(), updateObj);
+        if (updateRows == 0) {
+            log.error("[expireCoupon][coupon({}) 更新为已过期失败]", coupon.getId());
+            return false;
+        }
+
+        log.info("[expireCoupon][coupon({}) 更新为已过期成功]", coupon.getId());
+        return true;
+    }
+
     /**
      * 校验优惠券是否可以领取
      *
@@ -246,4 +286,12 @@ public class CouponServiceImpl implements CouponService {
         userIds.removeIf(userId -> MapUtil.getInt(userTakeCountMap, userId, 0) >= couponTemplate.getTakeLimitCount());
     }
 
+    /**
+     * 获得自身的代理对象,解决 AOP 生效问题
+     *
+     * @return 自己
+     */
+    private CouponServiceImpl getSelf() {
+        return SpringUtil.getBean(getClass());
+    }
 }