|
|
@@ -0,0 +1,109 @@
|
|
|
+package com.fs.app.redis;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.fs.hisStore.domain.FsStoreOrderScrm;
|
|
|
+import com.fs.hisStore.mapper.FsStoreOrderItemScrmMapper;
|
|
|
+import com.fs.hisStore.mapper.FsStoreOrderScrmMapper;
|
|
|
+import com.fs.hisStore.mapper.FsStoreVerifyCodeScrmMapper;
|
|
|
+import com.fs.hisStore.service.IFsStoreVerifyCodeScrmService;
|
|
|
+import com.fs.hisStore.domain.FsStoreVerifyCodeScrm;
|
|
|
+import com.fs.hisStore.vo.FsStoreOrderItemVO;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.redisson.api.RLock;
|
|
|
+import org.redisson.api.RedissonClient;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
+import org.springframework.scheduling.annotation.Scheduled;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.List;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @description: 订单过期处理
|
|
|
+ * @author: Guos
|
|
|
+ * @time: 2025/12/4 上午10:23
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+public class OrderExpireHandler {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private RedissonClient redissonClient;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private FsStoreOrderScrmMapper orderScrmMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private FsStoreOrderItemScrmMapper orderItemScrmMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private FsStoreVerifyCodeScrmMapper verifyCodeScrmMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IFsStoreVerifyCodeScrmService verifyCodeScrmService;
|
|
|
+
|
|
|
+
|
|
|
+ @Scheduled(fixedDelay = 60_000) // 每分钟跑一次
|
|
|
+ public void handleUnpaidOrders() {
|
|
|
+ RLock lock = redissonClient.getLock("order-expire-handler-lock");
|
|
|
+ try {
|
|
|
+ if (lock.tryLock(3, 30, TimeUnit.SECONDS)) {
|
|
|
+ // 查询所有 status=0 且创建时间超过指定阈值的订单
|
|
|
+ List<FsStoreOrderScrm> orders = orderScrmMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<FsStoreOrderScrm>()
|
|
|
+ .eq(FsStoreOrderScrm::getStatus, 0)
|
|
|
+ .lt(FsStoreOrderScrm::getCreateTime, LocalDateTime.now().minusMinutes(30))
|
|
|
+ );
|
|
|
+
|
|
|
+ for (FsStoreOrderScrm order : orders) {
|
|
|
+ processExpiredOrder(order);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ } finally {
|
|
|
+ if (lock.isHeldByCurrentThread()) {
|
|
|
+ lock.unlock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void processExpiredOrder(FsStoreOrderScrm order) {
|
|
|
+ Long orderId = order.getId();
|
|
|
+
|
|
|
+ List<FsStoreOrderItemVO> items = orderItemScrmMapper.selectMyFsStoreOrderItemListByOrderId(orderId);
|
|
|
+ if (!items.isEmpty()) {
|
|
|
+ List<Long> itemIds = items.stream()
|
|
|
+ .map(FsStoreOrderItemVO::getItemId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<FsStoreVerifyCodeScrm> codes = verifyCodeScrmMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<FsStoreVerifyCodeScrm>()
|
|
|
+ .eq(FsStoreVerifyCodeScrm::getOrderId, orderId)
|
|
|
+ .in(FsStoreVerifyCodeScrm::getOrderItemId, itemIds)
|
|
|
+ .eq(FsStoreVerifyCodeScrm::getIsDel, "0")
|
|
|
+ );
|
|
|
+
|
|
|
+ codes.forEach(code -> {
|
|
|
+ code.setVerifyStatus(0L);
|
|
|
+ code.setOutboundStatus(0L);
|
|
|
+ code.setOrderId(0L);
|
|
|
+ code.setOrderItemId(0L);
|
|
|
+ });
|
|
|
+
|
|
|
+ verifyCodeScrmService.updateBatchById(codes);
|
|
|
+ }
|
|
|
+
|
|
|
+ FsStoreOrderScrm updateOrder = new FsStoreOrderScrm();
|
|
|
+ updateOrder.setId(orderId);
|
|
|
+ updateOrder.setStatus(-3);
|
|
|
+ orderScrmMapper.updateFsStoreOrder(updateOrder);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|