From c7a3b2836d11492549501e23b66ab5d1cabb1d14 Mon Sep 17 00:00:00 2001
From: mitao <2763622819@qq.com>
Date: 星期五, 24 五月 2024 18:20:31 +0800
Subject: [PATCH] Merge branch 'dev-mitao'

---
 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/listener/RedisListener.java                              |   10 
 ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml                                          |   13 +
 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/DelayTask.java                                |    4 
 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/Order.java                                    |    2 
 ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsGroupPurchaseServiceImpl.java            |   66 ++++++
 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/PaymentMethodEnum.java                    |    4 
 ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/async/AsyncMethodService.java                      |  142 ++++++++++++++
 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/OrderFallbackFactory.java                    |    7 
 ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsSeckillServiceImpl.java                  |  129 +-----------
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java                         |   20 +
 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/OrderClient.java                         |   11 +
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java                            |   14 +
 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/BaseAsyncConfigurer.java                 |   54 +++++
 ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/management/MgtGoodsGroupPurchaseController.java |   12 +
 ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/management/DTO/GoodsGroupPurchaseDTO.java       |   10 +
 ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IGoodsGroupPurchaseService.java                    |    7 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/mapper/OrderMapper.java                                    |   17 +
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/IOrderService.java                                 |   17 +
 ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/task/GoodsScheduler.java                                   |   54 +++++
 19 files changed, 464 insertions(+), 129 deletions(-)

diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/DelayTask.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/DelayTask.java
index 96c8b08..83538f5 100644
--- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/DelayTask.java
+++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/DelayTask.java
@@ -41,8 +41,8 @@
     /**
      * 执行时间
      */
-    @TableField("end_time")
-    private LocalDateTime endTime;
+    @TableField("execute_time")
+    private LocalDateTime executeTime;
 
     @TableField("create_time")
     private LocalDateTime createTime;
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/pojo/Order.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/Order.java
similarity index 98%
rename from ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/pojo/Order.java
rename to ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/Order.java
index e7019b4..2809b2c 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/domain/pojo/Order.java
+++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/Order.java
@@ -1,4 +1,4 @@
-package com.ruoyi.order.domain.pojo;
+package com.ruoyi.system.api.domain;
 
 import com.baomidou.mybatisplus.annotation.FieldFill;
 import com.baomidou.mybatisplus.annotation.IdType;
diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/OrderFallbackFactory.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/OrderFallbackFactory.java
index de129fb..a6975ef 100644
--- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/OrderFallbackFactory.java
+++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/OrderFallbackFactory.java
@@ -1,9 +1,11 @@
 package com.ruoyi.system.api.factory;
 
 import com.ruoyi.common.core.domain.R;
+import com.ruoyi.system.api.domain.Order;
 import com.ruoyi.system.api.domain.dto.OrderAuctionBondDTO;
 import com.ruoyi.system.api.domain.dto.OrderDTO;
 import com.ruoyi.system.api.feignClient.OrderClient;
+import java.util.List;
 import org.springframework.cloud.openfeign.FallbackFactory;
 
 /**
@@ -35,6 +37,11 @@
             public R<Integer> getGroupPurchasesGoodsNum(Long id) {
                 return R.fail("获取团购商品已购数量失败:" + cause.getMessage());
             }
+
+            @Override
+            public R<List<Order>> getOrderByGroupPurchaseId(Long id) {
+                return R.fail("根据团购商品id获取订单列表失败:" + cause.getMessage());
+            }
         };
 
     }
diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/OrderClient.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/OrderClient.java
index 9612ed5..4895905 100644
--- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/OrderClient.java
+++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/OrderClient.java
@@ -2,9 +2,11 @@
 
 import com.ruoyi.common.core.constant.ServiceNameConstants;
 import com.ruoyi.common.core.domain.R;
+import com.ruoyi.system.api.domain.Order;
 import com.ruoyi.system.api.domain.dto.OrderAuctionBondDTO;
 import com.ruoyi.system.api.domain.dto.OrderDTO;
 import com.ruoyi.system.api.factory.OrderFallbackFactory;
+import java.util.List;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -38,4 +40,13 @@
      */
     @GetMapping("/order/group-purchase-num/{id}")
     R<Integer> getGroupPurchasesGoodsNum(@PathVariable("id") Long id);
+
+    /**
+     * 根据团购商品id获取订单列表
+     *
+     * @param id 团购商品id
+     * @return List<Order> 订单列表
+     */
+    @GetMapping("/order/group-purchase-id/{id}")
+    R<List<Order>> getOrderByGroupPurchaseId(@PathVariable("id") Long id);
 }
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/BaseAsyncConfigurer.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/BaseAsyncConfigurer.java
new file mode 100644
index 0000000..3263e0f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/config/BaseAsyncConfigurer.java
@@ -0,0 +1,54 @@
+package com.ruoyi.common.core.config;
+
+import java.lang.reflect.Method;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadPoolExecutor;
+import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.AsyncConfigurer;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+@Configuration
+@EnableAsync
+public class BaseAsyncConfigurer implements AsyncConfigurer {
+
+    @Bean("AsyncExecutor")
+    public ThreadPoolTaskExecutor executor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        int corePoolSize = 10;
+        executor.setCorePoolSize(corePoolSize);
+        int maxPoolSize = 50;
+        executor.setMaxPoolSize(maxPoolSize);
+        int queueCapacity = 10;
+        executor.setQueueCapacity(queueCapacity);
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        String threadNamePrefix = "AsyncExecutor-";
+        executor.setThreadNamePrefix(threadNamePrefix);
+        executor.setWaitForTasksToCompleteOnShutdown(true);
+        // 使用自定义的跨线程的请求级别线程工厂类19
+        int awaitTerminationSeconds = 5;
+        executor.setAwaitTerminationSeconds(awaitTerminationSeconds);
+        executor.initialize();
+        return executor;
+    }
+
+    @Override
+    public Executor getAsyncExecutor() {
+        return executor();
+    }
+
+    /*异步任务中异常处理*/
+    @Override
+    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+        return (Throwable ex, Method method, Object... params) -> {
+            //todo 异步方法异常处理
+            System.out.println("class#method: " + method.getDeclaringClass().getName() + "#"
+                    + method.getName());
+            System.out.println("type        : " + ex.getClass().getName());
+            System.out.println("exception   : " + ex.getMessage());
+        };
+    }
+
+}
\ No newline at end of file
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/PaymentMethodEnum.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/PaymentMethodEnum.java
index eb2c956..75fc971 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/PaymentMethodEnum.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/enums/PaymentMethodEnum.java
@@ -12,8 +12,8 @@
 
     /* 支付方式 1=微信 2=支付宝*/
 
-    WECHAT(1, "男"),
-    ALIPAY(2, "未知");
+    WECHAT(1, "微信"),
+    ALIPAY(2, "支付宝");
     @EnumValue
     private final int code;
     @JsonValue
diff --git a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/management/DTO/GoodsGroupPurchaseDTO.java b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/management/DTO/GoodsGroupPurchaseDTO.java
index a6b6421..f44b259 100644
--- a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/management/DTO/GoodsGroupPurchaseDTO.java
+++ b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/management/DTO/GoodsGroupPurchaseDTO.java
@@ -5,6 +5,8 @@
 import io.swagger.annotations.ApiModelProperty;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 import lombok.Data;
 
 /**
@@ -22,29 +24,37 @@
     private Long goodsSkuId;
 
     @ApiModelProperty(value = "分享标题")
+    @NotBlank(message = "分享标题不能为空")
     private String shareTitle;
 
     @ApiModelProperty(value = "分享图片")
+    @NotBlank(message = "分享图片不能为空")
     private String sharePic;
 
     @ApiModelProperty(value = "团购价格")
+    @NotNull(message = "团购价格不能为空")
     private BigDecimal groupPurchasePrice;
 
     @ApiModelProperty(value = "成团人数")
+    @NotNull(message = "成团人数不能为空")
     private Integer groupSize;
 
     @ApiModelProperty(value = "限购数量")
+    @NotNull(message = "限购数量不能为空")
     private Integer limitNumber;
 
     @ApiModelProperty(value = "团购开始时间")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @NotNull(message = "团购开始时间不能为空")
     private LocalDateTime startTime;
 
     @ApiModelProperty(value = "团购结束时间")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @NotNull(message = "团购结束时间不能为空")
     private LocalDateTime endTime;
 
     @ApiModelProperty(value = "参团说明")
+    @NotBlank(message = "参团说明不能为空")
     private String description;
 
 }
diff --git a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/management/MgtGoodsGroupPurchaseController.java b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/management/MgtGoodsGroupPurchaseController.java
index dea8bed..496d25b 100644
--- a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/management/MgtGoodsGroupPurchaseController.java
+++ b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/management/MgtGoodsGroupPurchaseController.java
@@ -86,4 +86,16 @@
         goodsGroupPurchaseService.updStatus(dto);
         return R.ok();
     }
+
+    /**
+     * 立即结束
+     *
+     * @param id 团购商品id
+     */
+    @ApiOperation(value = "立即结束", notes = "立即结束")
+    @PutMapping("/stop-immediately/{id}")
+    public R<Void> stopImmediately(@PathVariable("id") Long id) {
+        goodsGroupPurchaseService.stopImmediately(id);
+        return R.ok();
+    }
 }
diff --git a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IGoodsGroupPurchaseService.java b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IGoodsGroupPurchaseService.java
index 8eb6d9c..9d34215 100644
--- a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IGoodsGroupPurchaseService.java
+++ b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IGoodsGroupPurchaseService.java
@@ -61,4 +61,11 @@
      * @param groupPurchaseId 团购商品id
      */
     void endGroupPurchase(Long groupPurchaseId);
+
+    /**
+     * 立即结束团购
+     *
+     * @param id 团购商品id
+     */
+    void stopImmediately(Long id);
 }
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..b07f229
--- /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.goods.domain.GoodsSeckill;
+import com.ruoyi.system.api.constants.DelayTaskEnum;
+import com.ruoyi.system.api.domain.DelayTask;
+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);
+    }
+}
diff --git a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsGroupPurchaseServiceImpl.java b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsGroupPurchaseServiceImpl.java
index 237b1b1..fa87a08 100644
--- a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsGroupPurchaseServiceImpl.java
+++ b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsGroupPurchaseServiceImpl.java
@@ -2,7 +2,9 @@
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.core.enums.GroupStatusEnum;
 import com.ruoyi.common.core.enums.ListingStatusEnum;
+import com.ruoyi.common.core.enums.PaymentMethodEnum;
 import com.ruoyi.common.core.enums.StartStatusEnum;
 import com.ruoyi.common.core.exception.ServiceException;
 import com.ruoyi.common.core.utils.StringUtils;
@@ -12,10 +14,15 @@
 import com.ruoyi.goods.controller.management.DTO.GoodsGroupPurchaseQuery;
 import com.ruoyi.goods.controller.management.VO.GoodsGroupPurchaseVO;
 import com.ruoyi.goods.domain.GoodsGroupPurchase;
+import com.ruoyi.goods.domain.GoodsSku;
 import com.ruoyi.goods.mapper.GoodsGroupPurchaseMapper;
 import com.ruoyi.goods.service.IGoodsGroupPurchaseService;
+import com.ruoyi.goods.service.IGoodsSkuService;
+import com.ruoyi.goods.service.async.AsyncMethodService;
+import com.ruoyi.system.api.domain.Order;
 import com.ruoyi.system.api.domain.dto.ListStatusDTO;
 import com.ruoyi.system.api.feignClient.OrderClient;
+import java.util.List;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -34,7 +41,8 @@
 public class GoodsGroupPurchaseServiceImpl extends ServiceImpl<GoodsGroupPurchaseMapper, GoodsGroupPurchase> implements IGoodsGroupPurchaseService {
 
     private final OrderClient orderClient;
-
+    private final IGoodsSkuService goodsSkuService;
+    private final AsyncMethodService asyncMethodService;
     /**
      * 获取团购商品列表的分页数据
      *
@@ -57,15 +65,39 @@
     public void saveGoodsGroupPurchase(GoodsGroupPurchaseDTO dto) {
         GoodsGroupPurchase goodsGroupPurchase = BeanUtils.copyBean(dto, GoodsGroupPurchase.class);
         if (StringUtils.isNull(dto.getId())) {
+            if (StringUtils.isNull(dto.getGoodsSkuId())) {
+                throw new ServiceException("商品id不能为空");
+            }
             this.save(goodsGroupPurchase);
+            GoodsSku goodsSku = goodsSkuService.getById(dto.getGoodsSkuId());
+            if (StringUtils.isNull(goodsSku)) {
+                throw new ServiceException("商品不存在");
+            }
+            int groupPurchaseStock = dto.getLimitNumber() * dto.getGroupSize();
+            goodsSkuService.lambdaUpdate()
+                    .set(GoodsSku::getStock, goodsSku.getStock() - groupPurchaseStock)
+                    .ge(GoodsSku::getStock, groupPurchaseStock)
+                    .eq(GoodsSku::getId, goodsSku.getId());
         } else {
             GoodsGroupPurchase groupPurchase = this.getById(dto.getId());
             if (StringUtils.isNull(groupPurchase)) {
                 throw new ServiceException("团购商品不存在");
             }
+            int originGroupStock = groupPurchase.getLimitNumber() * groupPurchase.getGroupSize();
+            GoodsSku goodsSku = goodsSkuService.getById(dto.getGoodsSkuId());
+            if (StringUtils.isNull(goodsSku)) {
+                throw new ServiceException("商品不存在");
+            }
+            int groupPurchaseStock = dto.getLimitNumber() * dto.getGroupSize();
+            int latestStock = originGroupStock - groupPurchaseStock;
+            goodsSkuService.lambdaUpdate()
+                    .set(GoodsSku::getStock,
+                            goodsSku.getStock() + latestStock)
+                    .ge(GoodsSku::getStock, latestStock)
+                    .eq(GoodsSku::getId, goodsSku.getId());
             this.updateById(goodsGroupPurchase);
+            asyncMethodService.groupPurchaseScheduleTask(goodsGroupPurchase);
         }
-        //TODO 添加调度任务 处理团购商品开始结束
     }
 
     /**
@@ -140,4 +172,34 @@
             //TODO 通知小程序
         }
     }
+
+    /**
+     * 立即结束
+     *
+     * @param id 团购商品id
+     */
+    @Override
+    public void stopImmediately(Long id) {
+        GoodsGroupPurchase groupPurchase = this.getById(id);
+        if (StringUtils.isNull(groupPurchase)) {
+            throw new ServiceException("团购商品不存在");
+        }
+        //判断商品状态,未成团则查询关联订单,进行退款;成团就直接修改状态
+        if (groupPurchase.getGroupStatus().equals(GroupStatusEnum.TO_FORM_A_GROUP)) {
+            //查询关联订单
+            List<Order> orderList = orderClient.getOrderByGroupPurchaseId(id).getData();
+            for (Order order : orderList) {
+                if (PaymentMethodEnum.ALIPAY.equals(order.getPaymentMethod())) {
+                    //TODO
+                }
+                if (PaymentMethodEnum.WECHAT.equals(order.getPaymentMethod())) {
+                    //TODO
+                }
+            }
+        } else {
+            this.lambdaUpdate()
+                    .set(GoodsGroupPurchase::getStartStatus, StartStatusEnum.ENDED)
+                    .eq(GoodsGroupPurchase::getId, id).update();
+        }
+    }
 }
diff --git a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsSeckillServiceImpl.java b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsSeckillServiceImpl.java
index b41c374..68bfb79 100644
--- a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsSeckillServiceImpl.java
+++ b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsSeckillServiceImpl.java
@@ -4,6 +4,7 @@
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.core.constant.CacheConstants;
 import com.ruoyi.common.core.enums.StartStatusEnum;
+import com.ruoyi.common.core.exception.ServiceException;
 import com.ruoyi.common.core.utils.StringUtils;
 import com.ruoyi.common.core.utils.page.BeanUtils;
 import com.ruoyi.common.core.utils.page.PageDTO;
@@ -15,21 +16,17 @@
 import com.ruoyi.goods.mapper.GoodsSeckillMapper;
 import com.ruoyi.goods.service.IGoodsSeckillService;
 import com.ruoyi.goods.service.IGoodsSkuService;
+import com.ruoyi.goods.service.async.AsyncMethodService;
 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.domain.GoodsSku;
 import com.ruoyi.system.api.domain.dto.ListStatusDTO;
 import com.ruoyi.system.api.feignClient.OrderClient;
-import com.ruoyi.system.api.feignClient.SysUserClient;
-import java.time.Duration;
-import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Optional;
-import java.util.concurrent.TimeUnit;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.redisson.api.RedissonClient;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -51,7 +48,7 @@
     private final RedisService redisService;
     private final SysUserClient sysUserClient;
     private final RedissonClient redissonClient;
-
+    private final AsyncMethodService asyncMethodService;
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void addGoodsSeckill(GoodsSeckillDTO dto) {
@@ -67,117 +64,19 @@
         this.saveBatch(goodsSeckills);
 
         for (GoodsSeckill goodsSeckill : goodsSeckills) {
-            LocalDateTime startTime = goodsSeckill.getStartTime();
-            LocalDateTime endTime = goodsSeckill.getEndTime();
-            LocalDateTime checkTime = LocalDateTime.now().plusHours(1);
-            //秒杀在一小时内开始
-            if (checkTime.isAfter(startTime)) {
-                Long id = goodsSeckill.getId();
-                LocalDateTime now = LocalDateTime.now();
-                String seckillStartTaskKey = DelayTaskEnum.SECKILL_START_TASK.getCode() + "-" + id;
-                //秒杀已经开始
-                if (now.isAfter(startTime)) {
-                    //查询延时任务
-                    DelayTask startDelayTask = sysUserClient.getDelayTask(
-                            seckillStartTaskKey).getData();
-                    if (StringUtils.isNull(startDelayTask)) {
-                        redisService.setCacheObject(
-                                seckillStartTaskKey,
-                                startTime, 3L, TimeUnit.SECONDS);
-                        startDelayTask = new DelayTask();
-                        startDelayTask.setDelFlag(0);
-                        startDelayTask.setCreateTime(LocalDateTime.now());
-                        startDelayTask.setEndTime(LocalDateTime.now().plusSeconds(3));
-                        startDelayTask.setRedisKey(
-                                seckillStartTaskKey);
-                        sysUserClient.addDelayTask(startDelayTask);
-                    } else {
-                        if (!startDelayTask.getEndTime().isEqual(startTime)) {
-                            sysUserClient.deleteDelayTask(
-                                    seckillStartTaskKey);
-                            redisService.deleteObject(
-                                    seckillStartTaskKey);
-                            redisService.setCacheObject(
-                                    seckillStartTaskKey,
-                                    startTime, 3L, TimeUnit.SECONDS);
-                            startDelayTask = new DelayTask();
-                            startDelayTask.setDelFlag(0);
-                            startDelayTask.setCreateTime(LocalDateTime.now());
-                            startDelayTask.setEndTime(LocalDateTime.now().plusSeconds(3));
-                            startDelayTask.setRedisKey(
-                                    seckillStartTaskKey);
-                            sysUserClient.addDelayTask(startDelayTask);
-                        }
-                    }
-                } else {
-                    DelayTask startDelayTask = sysUserClient.getDelayTask(
-                            seckillStartTaskKey).getData();
-                    Duration duration = Duration.between(LocalDateTime.now(), startTime);
-
-                    if (StringUtils.isNull(startDelayTask)) {
-                        redisService.setCacheObject(
-                                seckillStartTaskKey,
-                                startTime, duration.toMillis(), TimeUnit.MILLISECONDS);
-                        startDelayTask = new DelayTask();
-                        startDelayTask.setDelFlag(0);
-                        startDelayTask.setCreateTime(LocalDateTime.now());
-                        startDelayTask.setEndTime(startTime);
-                        startDelayTask.setRedisKey(
-                                seckillStartTaskKey);
-                        sysUserClient.addDelayTask(startDelayTask);
-                    } else {
-                        if (!startDelayTask.getEndTime().isEqual(startTime)) {
-                            sysUserClient.deleteDelayTask(
-                                    seckillStartTaskKey);
-                            redisService.deleteObject(
-                                    seckillStartTaskKey);
-                            redisService.setCacheObject(
-                                    seckillStartTaskKey,
-                                    startTime, duration.toMillis(), TimeUnit.MILLISECONDS);
-                            startDelayTask = new DelayTask();
-                            startDelayTask.setDelFlag(0);
-                            startDelayTask.setCreateTime(LocalDateTime.now());
-                            startDelayTask.setEndTime(startTime);
-                            startDelayTask.setRedisKey(
-                                    seckillStartTaskKey);
-                            sysUserClient.addDelayTask(startDelayTask);
-                        }
-                    }
-                }
-                String seckillEndTaskKey = DelayTaskEnum.SECKILL_END_TASK.getCode() + "-" + id;
-                DelayTask endDelayTask = sysUserClient.getDelayTask(
-                        seckillEndTaskKey).getData();
-                // 如果延时任务为空,创建延时任务控制活动定时开始和结束
-                if (StringUtils.isNull(endDelayTask)) {
-                    Duration duration = Duration.between(LocalDateTime.now(), endTime);
-                    redisService.setCacheObject(
-                            seckillEndTaskKey,
-                            endTime, duration.toMillis(), TimeUnit.MILLISECONDS);
-                    endDelayTask = new DelayTask();
-                    endDelayTask.setDelFlag(0);
-                    endDelayTask.setCreateTime(LocalDateTime.now());
-                    endDelayTask.setEndTime(endTime);
-                    endDelayTask.setRedisKey(seckillEndTaskKey);
-                    sysUserClient.addDelayTask(endDelayTask);
-                } else {
-                    Duration duration = Duration.between(LocalDateTime.now(), endTime);
-                    if (!endDelayTask.getEndTime().isEqual(endTime)) {
-                        sysUserClient.deleteDelayTask(seckillEndTaskKey);
-                        redisService.deleteObject(seckillEndTaskKey);
-                        redisService.setCacheObject(
-                                seckillEndTaskKey,
-                                endTime, duration.toMillis(), TimeUnit.MILLISECONDS);
-                        endDelayTask = new DelayTask();
-                        endDelayTask.setDelFlag(0);
-                        endDelayTask.setCreateTime(LocalDateTime.now());
-                        endDelayTask.setEndTime(endTime);
-                        endDelayTask.setRedisKey(seckillEndTaskKey);
-                        sysUserClient.addDelayTask(endDelayTask);
-                    }
-                }
+            GoodsSku goodsSku = goodsSkuService.getById(goodsSeckill.getGoodsSkuId());
+            if (StringUtils.isNull(goodsSku)) {
+                throw new ServiceException("商品不存在");
             }
+            Integer seckillStock = goodsSeckill.getSeckillStock();
+            goodsSkuService.lambdaUpdate()
+                    .set(GoodsSku::getStock, goodsSku.getStock() - seckillStock)
+                    .ge(GoodsSku::getStock, seckillStock)
+                    .eq(GoodsSku::getId, goodsSku.getId());
+            asyncMethodService.seckillScheduleTask(goodsSeckill);
         }
     }
+
 
     /**
      * 获取秒杀商品列表的分页数据
@@ -198,6 +97,7 @@
      * @param upd 商品秒杀数据传输对象
      */
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void updGoodsSeckill(GoodsSeckillUpd upd) {
         //查询秒杀商品
         GoodsSeckill goodsSeckill = this.getById(upd.getId());
@@ -206,6 +106,7 @@
         }
         GoodsSeckill goodsSeckillUpd = BeanUtils.copyBean(upd, GoodsSeckill.class);
         this.updateById(goodsSeckillUpd);
+        asyncMethodService.seckillScheduleTask(goodsSeckill);
     }
 
     /**
diff --git a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/task/GoodsScheduler.java b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/task/GoodsScheduler.java
new file mode 100644
index 0000000..942f3e8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/task/GoodsScheduler.java
@@ -0,0 +1,54 @@
+package com.ruoyi.goods.task;
+
+import com.ruoyi.common.core.enums.ListingStatusEnum;
+import com.ruoyi.common.core.enums.StartStatusEnum;
+import com.ruoyi.goods.domain.GoodsGroupPurchase;
+import com.ruoyi.goods.domain.GoodsSeckill;
+import com.ruoyi.goods.service.IGoodsGroupPurchaseService;
+import com.ruoyi.goods.service.IGoodsSeckillService;
+import com.ruoyi.goods.service.async.AsyncMethodService;
+import java.time.LocalDateTime;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author mitao
+ * @date 2024/5/24
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class GoodsScheduler {
+
+    private final AsyncMethodService asyncMethodService;
+    private final IGoodsSeckillService goodsSeckillService;
+    private final IGoodsGroupPurchaseService goodsGroupPurchaseService;
+
+    @Scheduled(cron = "0 0 */1 * * ?")
+    private void timingTask() {
+        handleTaskStart();
+    }
+
+    private void handleTaskStart() {
+        log.info(">>>>>>>>>>>>>>>>>>>>定时任务秒杀/团购开始执行<<<<<<<<<<<<<<<<<<<<");
+        LocalDateTime checkTime = LocalDateTime.now().plusHours(1);
+        List<GoodsSeckill> list = goodsSeckillService.lambdaQuery()
+                .eq(GoodsSeckill::getListingStatus, ListingStatusEnum.ON_SHELVES)
+                .eq(GoodsSeckill::getStartStatus, StartStatusEnum.NOT_STARTED)
+                .le(GoodsSeckill::getStartTime, checkTime)
+                .list();
+        for (GoodsSeckill goodsSeckill : list) {
+            asyncMethodService.seckillScheduleTask(goodsSeckill);
+        }
+        List<GoodsGroupPurchase> groupPurchaseList = goodsGroupPurchaseService.lambdaQuery()
+                .eq(GoodsGroupPurchase::getListingStatus, ListingStatusEnum.ON_SHELVES)
+                .eq(GoodsGroupPurchase::getStartStatus, StartStatusEnum.NOT_STARTED)
+                .le(GoodsGroupPurchase::getStartTime, checkTime).list();
+        for (GoodsGroupPurchase goodsGroupPurchase : groupPurchaseList) {
+            asyncMethodService.groupPurchaseScheduleTask(goodsGroupPurchase);
+        }
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java
index 0f36576..4219436 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/OrderController.java
@@ -4,7 +4,9 @@
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.security.annotation.InnerAuth;
 import com.ruoyi.order.service.IOrderService;
+import com.ruoyi.system.api.domain.Order;
 import com.ruoyi.system.api.domain.dto.OrderDTO;
+import java.util.List;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.poi.ss.formula.functions.T;
@@ -64,4 +66,16 @@
     R<Integer> getGroupPurchasesGoodsNum(@PathVariable("id") Long id) {
         return R.ok(orderService.getGroupPurchasesGoodsNum(id));
     }
+
+    /**
+     * 获取团购商品已购订单列表
+     *
+     * @param id 团购商品id
+     * @return List<Order> 订单列表
+     */
+    @InnerAuth
+    @GetMapping("/group-purchase-id/{id}")
+    R<List<Order>> getOrderByGroupPurchaseId(@PathVariable("id") Long id) {
+        return R.ok(orderService.getOrderByGroupPurchaseId(id));
+    }
 }
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/mapper/OrderMapper.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/mapper/OrderMapper.java
index d6a61c7..0711b57 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/mapper/OrderMapper.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/mapper/OrderMapper.java
@@ -1,7 +1,8 @@
 package com.ruoyi.order.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.ruoyi.order.domain.pojo.Order;
+import com.ruoyi.system.api.domain.Order;
+import java.util.List;
 import org.apache.ibatis.annotations.Param;
 
 /**
@@ -14,5 +15,19 @@
  */
 public interface OrderMapper extends BaseMapper<Order> {
 
+    /**
+     * 获取某个商品的已购会员数
+     *
+     * @param id 秒杀商品id
+     * @return 已购会员数
+     */
     Integer getSeckillMembers(@Param("id") Long id);
+
+    /**
+     * 根据团购商品id获取团购商品订单
+     *
+     * @param id 团购商品id
+     * @return 订单列表
+     */
+    List<Order> getOrderByGroupPurchaseId(@Param("id") Long id);
 }
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/IOrderService.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/IOrderService.java
index 37a1954..9fed17b 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/IOrderService.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/IOrderService.java
@@ -1,8 +1,9 @@
 package com.ruoyi.order.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.ruoyi.order.domain.pojo.Order;
+import com.ruoyi.system.api.domain.Order;
 import com.ruoyi.system.api.domain.dto.OrderDTO;
+import java.util.List;
 
 /**
  * <p>
@@ -16,6 +17,12 @@
 
     void saveOrderOne(OrderDTO OrderDTO);
 
+    /**
+     * 获取某个商品的已购会员数
+     *
+     * @param id 秒杀商品id
+     * @return 已购会员数
+     */
     Integer getSeckillMembers(Long id);
 
     /**
@@ -25,4 +32,12 @@
      * @return 团购商品已购数量
      */
     Integer getGroupPurchasesGoodsNum(Long id);
+
+    /**
+     * 根据团购商品id获取团购商品订单
+     *
+     * @param id 团购商品id
+     * @return 订单列表
+     */
+    List<Order> getOrderByGroupPurchaseId(Long id);
 }
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
index 520643c..55b91da 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
@@ -2,12 +2,12 @@
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.core.enums.OrderStatusEnum;
-import com.ruoyi.order.domain.pojo.Order;
 import com.ruoyi.order.domain.pojo.OrderMall;
 import com.ruoyi.order.mapper.OrderMapper;
 import com.ruoyi.order.service.IOrderMallService;
 import com.ruoyi.order.service.IOrderService;
 import com.ruoyi.order.util.OrderUtil;
+import com.ruoyi.system.api.domain.Order;
 import com.ruoyi.system.api.domain.dto.OrderDTO;
 import java.util.List;
 import java.util.Set;
@@ -50,6 +50,13 @@
         order.setBound(OrderDTO.getBound());
         orderService.save(order);
     }
+
+    /**
+     * 获取某个商品的已购会员数
+     *
+     * @param id 秒杀商品id
+     * @return 已购会员数
+     */
     @Override
     public Integer getSeckillMembers(Long id) {
         return baseMapper.getSeckillMembers(id);
@@ -72,4 +79,15 @@
                         OrderStatusEnum.GOODS_TO_BE_RECEIVED, OrderStatusEnum.FINISHED).list();
         return list.stream().map(Order::getGoodsQuantity).reduce(0, Integer::sum);
     }
+
+    /**
+     * 根据团购商品id获取团购商品订单
+     *
+     * @param id 团购商品id
+     * @return 订单列表
+     */
+    @Override
+    public List<Order> getOrderByGroupPurchaseId(Long id) {
+        return baseMapper.getOrderByGroupPurchaseId(id);
+    }
 }
diff --git a/ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml b/ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml
index e86ecaf..74e9b67 100644
--- a/ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml
+++ b/ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml
@@ -14,4 +14,17 @@
     GROUP BY
       o.member_id
   </select>
+  <select id="getOrderByGroupPurchaseId" resultType="com.ruoyi.system.api.domain.Order"
+    parameterType="java.lang.Long">
+    SELECT
+    o.*
+    FROM
+    t_order_mall tom
+    LEFT JOIN t_order o ON tom.order_id = o.id
+    <where>
+      o.order_status = 2
+      AND o.order_from = 3
+      AND tom.activity_id = #{id}
+    </where>
+  </select>
 </mapper>
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/listener/RedisListener.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/listener/RedisListener.java
index 0421920..f484dae 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/listener/RedisListener.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/listener/RedisListener.java
@@ -86,31 +86,31 @@
     //延时任务表
     @Async
     public void autoStartSeckill(Long seckillId) {
-        log.info("autoStartSeckill scheduler task is running :" + seckillId);
+        log.info("autoStartSeckill scheduler task is running :{}", seckillId);
         goodsSkuClient.startSeckill(seckillId);
 
     }
 
     @Async
     public void autoEndSeckill(Long seckillId) {
-        log.info("autoEndSeckill scheduler task is running :" + seckillId);
+        log.info("autoEndSeckill scheduler task is running :{}", seckillId);
         goodsSkuClient.endSeckill(seckillId);
     }
 
     @Async
     public void autoStartGroupPurchase(Long GroupPurchaseId) {
-        log.info("autoStartGroupPurchase scheduler task is running :" + GroupPurchaseId);
+        log.info("autoStartGroupPurchase scheduler task is running :{}", GroupPurchaseId);
         goodsSkuClient.startGroupPurchase(GroupPurchaseId);
     }
 
     @Async
     public void autoEndGroupPurchase(Long GroupPurchaseId) {
-        log.info("autoEndGroupPurchase scheduler task is running :" + GroupPurchaseId);
+        log.info("autoEndGroupPurchase scheduler task is running :{}", GroupPurchaseId);
         goodsSkuClient.endGroupPurchase(GroupPurchaseId);
     }
 
     @Async
     public void autoCancelOrder(Long orderId) {
-        log.info("autoCancelOrder scheduler task is running :" + orderId);
+        log.info("autoCancelOrder scheduler task is running :{}", orderId);
     }
 }

--
Gitblit v1.7.1