From 43c263df4d8ce0cc830f287780c29db8a2b47f0f Mon Sep 17 00:00:00 2001
From: rentaiming <806181062@qq.com>
Date: 星期一, 27 五月 2024 08:44:34 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/async/AsyncMethodService.java |  142 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 142 insertions(+), 0 deletions(-)

diff --git a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/async/AsyncMethodService.java b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/async/AsyncMethodService.java
new file mode 100644
index 0000000..a0a2954
--- /dev/null
+++ b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/async/AsyncMethodService.java
@@ -0,0 +1,142 @@
+package com.ruoyi.goods.service.async;
+
+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.constants.DelayTaskEnum;
+import com.ruoyi.system.api.domain.DelayTask;
+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.concurrent.TimeUnit;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author mitao
+ * @date 2024/5/24
+ */
+@Component
+@Slf4j
+@RequiredArgsConstructor
+public class AsyncMethodService {
+
+    private final RedisService redisService;
+    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());
+            }
+            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());
+            }
+            //秒杀结束延时任务
+            handleEndDelayTask(id, DelayTaskEnum.GROUP_PURCHASES_END_TASK, endTime);
+        }
+    }
+
+    private boolean isWithinOneHour(LocalDateTime startTime) {
+        LocalDateTime checkTime = LocalDateTime.now().plusHours(1);
+        return checkTime.isAfter(startTime);
+    }
+
+    private void handleEndDelayTask(Long id, DelayTaskEnum delayTaskEnum, LocalDateTime endTime) {
+        String endTaskKey = delayTaskEnum.getCode() + "-" + id;
+        DelayTask endDelayTask = sysUserClient.getDelayTask(
+                endTaskKey).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);
+                redisService.deleteObject(endTaskKey);
+                createEndDelayTask(endTime, endTaskKey, duration);
+            }
+        }
+        log.info(">>>>>>>>>>>>>>>>>>>>延时任务{}执行了<<<<<<<<<<<<<<<<<<<<", endTaskKey);
+    }
+
+    private void createEndDelayTask(LocalDateTime endTime, String seckillEndTaskKey,
+            Duration duration) {
+        DelayTask endDelayTask;
+        redisService.setCacheObject(
+                seckillEndTaskKey,
+                endTime, duration.getSeconds(), TimeUnit.SECONDS);
+        endDelayTask = new DelayTask();
+        endDelayTask.setDelFlag(0);
+        endDelayTask.setCreateTime(LocalDateTime.now());
+        endDelayTask.setExecuteTime(endTime);
+        endDelayTask.setRedisKey(seckillEndTaskKey);
+        sysUserClient.addDelayTask(endDelayTask);
+    }
+
+    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);
+        if (StringUtils.isNull(startDelayTask)) {
+            startDelayTask = new DelayTask();
+            startDelayTask.setDelFlag(0);
+            startDelayTask.setCreateTime(LocalDateTime.now());
+            startDelayTask.setExecuteTime(LocalDateTime.now().plusSeconds(timeout));
+            startDelayTask.setRedisKey(
+                    startTaskKey);
+            sysUserClient.addDelayTask(startDelayTask);
+        } else {
+            if (!startDelayTask.getExecuteTime().isEqual(startTime)) {
+                sysUserClient.deleteDelayTask(
+                        startTaskKey);
+                redisService.deleteObject(
+                        startTaskKey);
+                startDelayTask.setDelFlag(0);
+                startDelayTask.setCreateTime(LocalDateTime.now());
+                startDelayTask.setExecuteTime(LocalDateTime.now().plusSeconds(timeout));
+                startDelayTask.setRedisKey(
+                        startTaskKey);
+                sysUserClient.addDelayTask(startDelayTask);
+            }
+        }
+        log.info(">>>>>>>>>>>>>>>>>>>>延时任务{}执行了<<<<<<<<<<<<<<<<<<<<", startTaskKey);
+    }
+}

--
Gitblit v1.7.1