rentaiming
2024-06-13 fe2d5b14031edbe43238770fb1fc21e8a322b51a
ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/async/AsyncMethodService.java
@@ -1,25 +1,29 @@
package com.ruoyi.goods.service.async;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.goods.domain.GoodsGroupPurchase;
import com.ruoyi.system.api.domain.GoodsGroupPurchase;
import com.ruoyi.system.api.constants.DelayTaskEnum;
import com.ruoyi.system.api.domain.DelayTask;
import com.ruoyi.system.api.domain.GoodsGroupPurchase;
import com.ruoyi.system.api.domain.GoodsSeckill;
import com.ruoyi.system.api.feignClient.SysUserClient;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * @author mitao
 * @date 2024/5/24
 */
@Component
@Service
@Slf4j
@RequiredArgsConstructor
public class AsyncMethodService {
@@ -28,47 +32,53 @@
    private final SysUserClient sysUserClient;
    @Async
    public void seckillScheduleTask(GoodsSeckill goodsSeckill) {
        LocalDateTime startTime = goodsSeckill.getStartTime();
        LocalDateTime endTime = goodsSeckill.getEndTime();
        //秒杀在一小时内开始
        if (isWithinOneHour(startTime)) {
            Long id = goodsSeckill.getId();
            //秒杀已经开始
            if (LocalDateTime.now().isAfter(startTime)) {
                handleStartDelayTask(id, DelayTaskEnum.SECKILL_START_TASK, startTime, 3L);
            } else {
                Duration duration = Duration.between(LocalDateTime.now(), startTime);
                handleStartDelayTask(id, DelayTaskEnum.SECKILL_START_TASK, startTime,
                        duration.getSeconds());
    @Transactional(rollbackFor = Exception.class)
    public void seckillScheduleTask(List<GoodsSeckill> goodsSeckillList) {
        for (GoodsSeckill goodsSeckill : goodsSeckillList) {
            LocalDateTime startTime = goodsSeckill.getStartTime();
            LocalDateTime endTime = goodsSeckill.getEndTime();
            // 秒杀在一小时内开始
            if (isWithinOneHour(startTime)) {
                Long id = goodsSeckill.getId();
                // 秒杀已经开始
                if (LocalDateTime.now().isAfter(startTime)) {
                    handleStartDelayTask(id, DelayTaskEnum.SECKILL_START_TASK, startTime, 3L);
                } else {
                    Duration duration = Duration.between(LocalDateTime.now(), startTime);
                    handleStartDelayTask(id, DelayTaskEnum.SECKILL_START_TASK, startTime,
                            duration.getSeconds());
                }
                log.info(">>>>>>>>>>>>>>>>>>>>秒杀商品:{} 开始秒杀<<<<<<<<<<<<<<<<<<<<", id);
                // 秒杀结束延时任务
                handleEndDelayTask(id, DelayTaskEnum.SECKILL_END_TASK, endTime);
            }
            log.info(">>>>>>>>>>>>>>>>>>>>秒杀商品:{} 开始秒杀<<<<<<<<<<<<<<<<<<<<", id);
            //秒杀结束延时任务
            handleEndDelayTask(id, DelayTaskEnum.SECKILL_END_TASK, endTime);
        }
    }
    @Async
    public void groupPurchaseScheduleTask(GoodsGroupPurchase groupPurchase) {
        LocalDateTime startTime = groupPurchase.getStartTime();
        LocalDateTime endTime = groupPurchase.getEndTime();
        //秒杀在一小时内开始
        if (isWithinOneHour(startTime)) {
            Long id = groupPurchase.getId();
            //秒杀已经开始,三秒后执行
            if (LocalDateTime.now().isAfter(startTime)) {
                handleStartDelayTask(id, DelayTaskEnum.GROUP_PURCHASES_START_TASK, startTime, 3L);
            } else {
                Duration duration = Duration.between(LocalDateTime.now(), startTime);
                handleStartDelayTask(id, DelayTaskEnum.GROUP_PURCHASES_START_TASK, startTime,
                        duration.getSeconds());
    @Transactional(rollbackFor = Exception.class)
    public void groupPurchaseScheduleTask(List<GoodsGroupPurchase> groupPurchaseList) {
        for (GoodsGroupPurchase goodsGroupPurchase : groupPurchaseList) {
            LocalDateTime startTime = goodsGroupPurchase.getStartTime();
            LocalDateTime endTime = goodsGroupPurchase.getEndTime();
            // 团购在一小时内开始
            if (isWithinOneHour(startTime)) {
                Long id = goodsGroupPurchase.getId();
                // 团购已经开始,三秒后执行
                if (LocalDateTime.now().isAfter(startTime)) {
                    handleStartDelayTask(id, DelayTaskEnum.GROUP_PURCHASES_START_TASK, startTime,
                            3L);
                } else {
                    Duration duration = Duration.between(LocalDateTime.now(), startTime);
                    handleStartDelayTask(id, DelayTaskEnum.GROUP_PURCHASES_START_TASK, startTime,
                            duration.getSeconds());
                }
                // 团购结束延时任务
                handleEndDelayTask(id, DelayTaskEnum.GROUP_PURCHASES_END_TASK, endTime);
            }
            //秒杀结束延时任务
            handleEndDelayTask(id, DelayTaskEnum.GROUP_PURCHASES_END_TASK, endTime);
        }
    }
    private boolean isWithinOneHour(LocalDateTime startTime) {
        LocalDateTime checkTime = LocalDateTime.now().plusHours(1);
        return checkTime.isAfter(startTime);
@@ -77,14 +87,15 @@
    private void handleEndDelayTask(Long id, DelayTaskEnum delayTaskEnum, LocalDateTime endTime) {
        String endTaskKey = delayTaskEnum.getCode() + "-" + id;
        DelayTask endDelayTask = sysUserClient.getDelayTask(
                endTaskKey).getData();
                endTaskKey, SecurityConstants.INNER).getData();
        // 如果延时任务为空,创建延时任务控制活动定时开始和结束
        Duration duration = Duration.between(LocalDateTime.now(), endTime);
        if (StringUtils.isNull(endDelayTask)) {
            createEndDelayTask(endTime, endTaskKey, duration);
        } else {
            if (!endDelayTask.getExecuteTime().isEqual(endTime)) {
                sysUserClient.deleteDelayTask(endTaskKey);
                sysUserClient.deleteDelayTask(endTaskKey,
                        SecurityConstants.INNER);
                redisService.deleteObject(endTaskKey);
                createEndDelayTask(endTime, endTaskKey, duration);
            }
@@ -103,18 +114,18 @@
        endDelayTask.setCreateTime(LocalDateTime.now());
        endDelayTask.setExecuteTime(endTime);
        endDelayTask.setRedisKey(seckillEndTaskKey);
        sysUserClient.addDelayTask(endDelayTask);
        sysUserClient.addDelayTask(endDelayTask, SecurityConstants.INNER);
    }
    private void handleStartDelayTask(Long id, DelayTaskEnum delayTaskEnum, LocalDateTime startTime,
            Long timeout) {
        String startTaskKey = delayTaskEnum.getCode() + "-" + id;
        //查询延时任务
        DelayTask startDelayTask = sysUserClient.getDelayTask(
                startTaskKey).getData();
        redisService.setCacheObject(
                startTaskKey,
                startTime, timeout, TimeUnit.SECONDS);
        //查询延时任务
        DelayTask startDelayTask = sysUserClient.getDelayTask(
                startTaskKey, SecurityConstants.INNER).getData();
        if (StringUtils.isNull(startDelayTask)) {
            startDelayTask = new DelayTask();
            startDelayTask.setDelFlag(0);
@@ -122,11 +133,11 @@
            startDelayTask.setExecuteTime(LocalDateTime.now().plusSeconds(timeout));
            startDelayTask.setRedisKey(
                    startTaskKey);
            sysUserClient.addDelayTask(startDelayTask);
            sysUserClient.addDelayTask(startDelayTask, SecurityConstants.INNER);
        } else {
            if (!startDelayTask.getExecuteTime().isEqual(startTime)) {
                sysUserClient.deleteDelayTask(
                        startTaskKey);
                        startTaskKey, SecurityConstants.INNER);
                redisService.deleteObject(
                        startTaskKey);
                startDelayTask.setDelFlag(0);
@@ -134,7 +145,7 @@
                startDelayTask.setExecuteTime(LocalDateTime.now().plusSeconds(timeout));
                startDelayTask.setRedisKey(
                        startTaskKey);
                sysUserClient.addDelayTask(startDelayTask);
                sysUserClient.addDelayTask(startDelayTask, SecurityConstants.INNER);
            }
        }
        log.info(">>>>>>>>>>>>>>>>>>>>延时任务{}执行了<<<<<<<<<<<<<<<<<<<<", startTaskKey);