package com.ruoyi.schedule; import cn.hutool.core.collection.CollectionUtil; import com.ruoyi.shop.constants.ShopConstants; import com.ruoyi.shop.order.domain.ShopOrderDetail; import com.ruoyi.shop.order.service.IShopOrderDetailService; import com.ruoyi.shop.order.service.IShopOrderService; import com.ruoyi.shop.product.domain.bo.ProductViewUpdate; import com.ruoyi.shop.product.service.IProductService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.Map; @Component @Configuration @EnableScheduling @Lazy(false) @Slf4j @RequiredArgsConstructor public class ProjectSchedule { private final StringRedisTemplate redisTemplate; private final IProductService productService; private final IShopOrderDetailService shopOrderDetailService; private final IShopOrderService shopOrderService; /** * 每30秒执行一次 商品浏览量同步 */ @Scheduled(fixedDelay = 30_000) public void syncProductViewCountToDb() { // 获取所有待同步的商品浏览增量 Map increments = redisTemplate.opsForHash().entries(ShopConstants.PRODUCT_VIEW_KEY); if (increments.isEmpty()) { return; }; // 批量更新数据库(使用 batch update) List updates = new ArrayList<>(); try { for (Map.Entry entry : increments.entrySet()) { if (entry.getKey() == null || entry.getValue() == null) { continue; } Long productId; Integer incr; try { productId = Long.valueOf(entry.getKey().toString()); incr = Integer.valueOf(entry.getValue().toString()); } catch (NumberFormatException e) { // 跳过无法解析的条目 continue; } updates.add(new ProductViewUpdate(productId, incr)); } if (CollectionUtil.isNotEmpty(updates)) { // 执行批量更新(例如 MyBatis Batch) productService.batchUpdateViewCount(updates); // 清空 Redis 中已同步的数据 redisTemplate.delete(ShopConstants.PRODUCT_VIEW_KEY); } } catch (Exception e) { // 记录日志,处理同步失败的情况 log.error("商品浏览量同步失败", e); throw e; } } /** * 每晚一点执行一次 订单封单 */ @Scheduled(cron = "${task1h}") public void autoEnd() { List list = shopOrderDetailService.needAutoEndOrder(); list.forEach(v -> { try { log.info(String.format("订单:%s,购买商品【%s】封单开始", v.getOrderNo(),v.getProductTitle())); shopOrderService.autoEnd(v); log.info(String.format("订单:%s,购买商品【%s】封单完成", v.getOrderNo(),v.getProductTitle())); } catch (Exception ex) { log.error(String.format("订单:%s,购买商品【%s】封单完成,出错%s", v.getOrderNo(),v.getProductTitle(), ex.getMessage())); } }); } }