ProjectSchedule.java 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package com.ruoyi.schedule;
  2. import cn.hutool.core.collection.CollectionUtil;
  3. import com.ruoyi.shop.constants.ShopConstants;
  4. import com.ruoyi.shop.order.domain.ShopOrderDetail;
  5. import com.ruoyi.shop.order.service.IShopOrderDetailService;
  6. import com.ruoyi.shop.order.service.IShopOrderService;
  7. import com.ruoyi.shop.product.domain.bo.ProductViewUpdate;
  8. import com.ruoyi.shop.product.service.IProductService;
  9. import lombok.RequiredArgsConstructor;
  10. import lombok.extern.slf4j.Slf4j;
  11. import org.springframework.beans.factory.annotation.Autowired;
  12. import org.springframework.context.annotation.Configuration;
  13. import org.springframework.context.annotation.Lazy;
  14. import org.springframework.data.redis.core.RedisTemplate;
  15. import org.springframework.data.redis.core.StringRedisTemplate;
  16. import org.springframework.scheduling.annotation.EnableScheduling;
  17. import org.springframework.scheduling.annotation.Scheduled;
  18. import org.springframework.stereotype.Component;
  19. import java.util.ArrayList;
  20. import java.util.List;
  21. import java.util.Map;
  22. @Component
  23. @Configuration
  24. @EnableScheduling
  25. @Lazy(false)
  26. @Slf4j
  27. @RequiredArgsConstructor
  28. public class ProjectSchedule {
  29. private final StringRedisTemplate redisTemplate;
  30. private final IProductService productService;
  31. private final IShopOrderDetailService shopOrderDetailService;
  32. private final IShopOrderService shopOrderService;
  33. /**
  34. * 每30秒执行一次 商品浏览量同步
  35. */
  36. @Scheduled(fixedDelay = 30_000)
  37. public void syncProductViewCountToDb() {
  38. // 获取所有待同步的商品浏览增量
  39. Map<Object, Object> increments = redisTemplate.opsForHash().entries(ShopConstants.PRODUCT_VIEW_KEY);
  40. if (increments.isEmpty()) {
  41. return;
  42. };
  43. // 批量更新数据库(使用 batch update)
  44. List<ProductViewUpdate> updates = new ArrayList<>();
  45. try {
  46. for (Map.Entry<Object, Object> entry : increments.entrySet()) {
  47. if (entry.getKey() == null || entry.getValue() == null) {
  48. continue;
  49. }
  50. Long productId;
  51. Integer incr;
  52. try {
  53. productId = Long.valueOf(entry.getKey().toString());
  54. incr = Integer.valueOf(entry.getValue().toString());
  55. } catch (NumberFormatException e) {
  56. // 跳过无法解析的条目
  57. continue;
  58. }
  59. updates.add(new ProductViewUpdate(productId, incr));
  60. }
  61. if (CollectionUtil.isNotEmpty(updates)) {
  62. // 执行批量更新(例如 MyBatis Batch)
  63. productService.batchUpdateViewCount(updates);
  64. // 清空 Redis 中已同步的数据
  65. redisTemplate.delete(ShopConstants.PRODUCT_VIEW_KEY);
  66. }
  67. } catch (Exception e) {
  68. // 记录日志,处理同步失败的情况
  69. log.error("商品浏览量同步失败", e);
  70. throw e;
  71. }
  72. }
  73. /**
  74. * 每晚一点执行一次 订单封单
  75. */
  76. @Scheduled(cron = "${task1h}")
  77. public void autoEnd() {
  78. List<ShopOrderDetail> list = shopOrderDetailService.needAutoEndOrder();
  79. list.forEach(v -> {
  80. try {
  81. log.info(String.format("订单:%s,购买商品【%s】封单开始", v.getOrderNo(),v.getProductTitle()));
  82. shopOrderService.autoEnd(v);
  83. log.info(String.format("订单:%s,购买商品【%s】封单完成", v.getOrderNo(),v.getProductTitle()));
  84. }
  85. catch (Exception ex) {
  86. log.error(String.format("订单:%s,购买商品【%s】封单完成,出错%s", v.getOrderNo(),v.getProductTitle(), ex.getMessage()));
  87. }
  88. });
  89. }
  90. }