ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/DelayTask.java
@@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import java.io.Serializable; import java.util.Date; import java.time.LocalDateTime; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; @@ -45,9 +45,9 @@ * 执行时间 */ @TableField("end_time") private Date endTime; private LocalDateTime endTime; @TableField("create_time") private Date createTime; private LocalDateTime createTime; } ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/SysUserFallbackFactory.java
@@ -1,6 +1,7 @@ package com.ruoyi.system.api.factory; import com.ruoyi.common.core.domain.R; import com.ruoyi.system.api.domain.DelayTask; import com.ruoyi.system.api.domain.SysRole; import com.ruoyi.system.api.domain.SysUser; import com.ruoyi.system.api.feignClient.SysUserClient; @@ -61,6 +62,21 @@ public R<SysUser> queryUserByUserName(String userName) { return R.fail("通过账号查询用户失败:" + cause.getMessage()); } @Override public R<DelayTask> getDelayTask(String key) { return R.fail("获取延时任务失败:" + cause.getMessage()); } @Override public R<?> addDelayTask(DelayTask delayTask) { return R.fail("添加延时任务失败:" + cause.getMessage()); } @Override public R<?> deleteDelayTask(String key) { return R.fail("删除延时任务失败:" + cause.getMessage()); } }; } } ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/feignClient/SysUserClient.java
@@ -2,6 +2,7 @@ import com.ruoyi.common.core.constant.ServiceNameConstants; import com.ruoyi.common.core.domain.R; import com.ruoyi.system.api.domain.DelayTask; import com.ruoyi.system.api.domain.SysRole; import com.ruoyi.system.api.domain.SysUser; import com.ruoyi.system.api.factory.SysUserFallbackFactory; @@ -71,4 +72,15 @@ @PostMapping("/user/queryUserByUserName") R<SysUser> queryUserByUserName(@RequestBody String userName); /** * 延时任务控制 */ @PostMapping("/config/getDelayTask") public R<DelayTask> getDelayTask(@RequestBody String key); @PostMapping("/config/addDelayTask") public R<?> addDelayTask(@RequestBody DelayTask delayTask); @PostMapping("/config/deleteDelayTask") public R<?> deleteDelayTask(@RequestBody String key); } ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/GoodsGroupPurchaseController.java
@@ -2,6 +2,7 @@ import com.ruoyi.common.core.domain.R; import com.ruoyi.common.security.annotation.InnerAuth; import com.ruoyi.goods.service.IGoodsGroupPurchaseService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -26,12 +27,24 @@ private final IGoodsGroupPurchaseService goodsGroupPurchaseService; /** * 团购商品开始团购 * * @param groupPurchaseId 团购商品id */ @InnerAuth @GetMapping("/start/{groupPurchaseId}") R<?> startGroupPurchase(@PathVariable("groupPurchaseId") Long groupPurchaseId) { goodsGroupPurchaseService.startGroupPurchase(groupPurchaseId); return R.ok(); } /** * 团购商品结束团购 * * @param groupPurchaseId 团购商品id */ @InnerAuth @GetMapping("/end/{groupPurchaseId}") R<?> endGroupPurchase(@PathVariable("groupPurchaseId") Long groupPurchaseId) { goodsGroupPurchaseService.endGroupPurchase(groupPurchaseId); ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/controller/GoodsSeckillController.java
@@ -2,6 +2,7 @@ import com.ruoyi.common.core.domain.R; import com.ruoyi.common.security.annotation.InnerAuth; import com.ruoyi.goods.service.IGoodsSeckillService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -31,6 +32,7 @@ * * @param seckillId 秒杀id */ @InnerAuth @GetMapping("/start/{seckillId}") R<?> startSeckill(@PathVariable("seckillId") Long seckillId) { goodsSeckillService.startSeckill(seckillId); @@ -42,6 +44,7 @@ * * @param seckillId 秒杀id */ @InnerAuth @GetMapping("/end/{seckillId}") R<?> endSeckill(@PathVariable("seckillId") Long seckillId) { goodsSeckillService.endSeckill(seckillId); ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/IGoodsGroupPurchaseService.java
@@ -48,7 +48,17 @@ */ void updStatus(ListStatusDTO dto); /** * 团购商品开始团购 * * @param groupPurchaseId 团购商品id */ void startGroupPurchase(Long groupPurchaseId); /** * 团购商品结束团购 * * @param groupPurchaseId 团购商品id */ void endGroupPurchase(Long groupPurchaseId); } ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsGroupPurchaseServiceImpl.java
@@ -109,19 +109,35 @@ this.updateById(groupPurchase); } /** * 团购商品开始团购 * * @param groupPurchaseId 团购商品id */ @Override public void startGroupPurchase(Long groupPurchaseId) { log.info(">>>>>>>>>>>>>>>>>>>>团购商品开始团购<<<<<<<<<<<<<<<<<<<<"); log.info(">>>>>>>>>>>>>>>>>>>>{}团购商品开始团购<<<<<<<<<<<<<<<<<<<<", groupPurchaseId); GoodsGroupPurchase groupPurchase = this.getById(groupPurchaseId); if (StringUtils.isNotNull(groupPurchase)) { this.lambdaUpdate().set(GoodsGroupPurchase::getStartStatus, StartStatusEnum.STARTED) .eq(GoodsGroupPurchase::getId, groupPurchaseId).update(); //TODO 通知小程勋 //TODO 通知小程序 } } /** * 团购商品结束团购 * * @param groupPurchaseId 团购商品id */ @Override public void endGroupPurchase(Long groupPurchaseId) { log.info(">>>>>>>>>>>>>>>>>>>>{}团购商品结束团购<<<<<<<<<<<<<<<<<<<<", groupPurchaseId); GoodsGroupPurchase groupPurchase = this.getById(groupPurchaseId); if (StringUtils.isNotNull(groupPurchase)) { this.lambdaUpdate().set(GoodsGroupPurchase::getStartStatus, StartStatusEnum.ENDED) .eq(GoodsGroupPurchase::getId, groupPurchaseId).update(); //TODO 通知小程序 } } } ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsSeckillServiceImpl.java
@@ -17,12 +17,19 @@ import com.ruoyi.goods.mapper.GoodsSeckillMapper; import com.ruoyi.goods.service.IGoodsSeckillService; import com.ruoyi.goods.service.IGoodsSkuService; import com.ruoyi.system.api.constants.DelayTaskEnum; import com.ruoyi.system.api.domain.DelayTask; 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; @@ -42,6 +49,9 @@ private final IGoodsSkuService goodsSkuService; private final OrderClient orderClient; private final RedisService redisService; private final SysUserClient sysUserClient; private final RedissonClient redissonClient; @Override @Transactional(rollbackFor = Exception.class) public void addGoodsSeckill(GoodsSeckillDTO dto) { @@ -55,7 +65,118 @@ goodsSeckill.setStartStatus(StartStatusEnum.NOT_STARTED); } this.saveBatch(goodsSeckills); //TODO 添加调度任务控制开始结束 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); } } } } } /** ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/DelayTaskController.java
New file @@ -0,0 +1,45 @@ package com.ruoyi.system.controller; import com.ruoyi.common.core.domain.R; import com.ruoyi.system.api.domain.DelayTask; import com.ruoyi.system.service.DelayTaskService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * <p> * 前端控制器 * </p> * * @author mitao * @since 2024-05-21 */ @RestController @RequestMapping("/delay-task") @RequiredArgsConstructor public class DelayTaskController { private final DelayTaskService delayTaskService; @PostMapping("/getDelayTask") public R<DelayTask> getDelayTask(@RequestBody String key) { DelayTask delayTask = delayTaskService.getDelayTask(key); return R.ok(delayTask); } @PostMapping("/addDelayTask") public R<?> addDelayTask(@RequestBody DelayTask delayTask) { delayTaskService.addDelayTask(delayTask); return R.ok(); } @PostMapping("/deleteDelayTask") public R<?> deleteDelayTask(@RequestBody String key) { delayTaskService.deleteDelayTask(key); return R.ok(); } }