OrderCancelService.java 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. package com.izouma.nineth.service;
  2. import com.izouma.nineth.config.GeneralProperties;
  3. import com.izouma.nineth.domain.Order;
  4. import com.izouma.nineth.domain.SysConfig;
  5. import com.izouma.nineth.enums.OrderStatus;
  6. import com.izouma.nineth.exception.BusinessException;
  7. import com.izouma.nineth.repo.*;
  8. import lombok.AllArgsConstructor;
  9. import lombok.extern.slf4j.Slf4j;
  10. import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  11. import org.springframework.data.redis.core.RedisTemplate;
  12. import org.springframework.scheduling.annotation.Scheduled;
  13. import org.springframework.stereotype.Service;
  14. import javax.annotation.PostConstruct;
  15. import java.time.LocalDateTime;
  16. import java.util.List;
  17. @Service
  18. @ConditionalOnProperty(value = "general.notify-server", havingValue = "true")
  19. @Slf4j
  20. @AllArgsConstructor
  21. public class OrderCancelService {
  22. private final GeneralProperties generalProperties;
  23. private final OrderRepo orderRepo;
  24. private final OrderService orderService;
  25. private final SysConfigRepo sysConfigRepo;
  26. private final MintOrderRepo mintOrderRepo;
  27. private final MintOrderService mintOrderService;
  28. private final GiftOrderRepo giftOrderRepo;
  29. private final GiftOrderService giftOrderService;
  30. private final OrderPayService orderPayService;
  31. private final RedisTemplate<String, Object> redisTemplate;
  32. private final AuctionOrderRepo auctionOrderRepo;
  33. private final AuctionOrderService auctionOrderService;
  34. private static int orderCancelInterval = 210;
  35. public static void setOrderCancelInterval(int orderCancelInterval) {
  36. log.info("设置订单取消时间间隔为 {}S", orderCancelInterval);
  37. OrderCancelService.orderCancelInterval = orderCancelInterval;
  38. }
  39. @PostConstruct
  40. public void init() {
  41. orderCancelInterval = sysConfigRepo.findByName("order_cancel_time")
  42. .map(SysConfig::getValue).map(Integer::parseInt).orElse(210);
  43. }
  44. @Scheduled(fixedRate = 30000, initialDelay = 10000)
  45. @RedisLock(value = "order_batch_cancel", expire = 3, unit = TimeUnit.MINUTES)
  46. public void batchCancel() {
  47. List<Order> orders = orderRepo.findByStatusAndCreatedAtBeforeAndDelFalse(OrderStatus.NOT_PAID,
  48. LocalDateTime.now().minusSeconds(orderCancelInterval));
  49. orders.parallelStream().forEach(o -> {
  50. try {
  51. Order order = orderRepo.findById(o.getId()).orElseThrow(new BusinessException("订单不存在"));
  52. if (order.getStatus() == OrderStatus.NOT_PAID && canCancel(order.getId().toString())) {
  53. orderService.cancel(order);
  54. }
  55. } catch (Exception e) {
  56. log.error("取消订单错误 " + o.getId(), e);
  57. }
  58. });
  59. }
  60. @Scheduled(fixedRate = 30000, initialDelay = 20000)
  61. @RedisLock(value = "mint_order_batch_cancel", expire = 3, unit = TimeUnit.MINUTES)
  62. public void batchCancelMintOrder() {
  63. List<MintOrder> orders = mintOrderRepo.findByStatusAndCreatedAtBeforeAndDelFalse(MintOrderStatus.NOT_PAID,
  64. LocalDateTime.now().minusSeconds(orderCancelInterval));
  65. orders.forEach(o -> {
  66. try {
  67. MintOrder order = mintOrderRepo.findById(o.getId()).orElseThrow(new BusinessException("订单不存在"));
  68. if (order.getStatus() == MintOrderStatus.NOT_PAID && canCancel(order.getId().toString())) {
  69. mintOrderService.cancel(order, false);
  70. }
  71. } catch (Exception ignored) {
  72. }
  73. });
  74. }
  75. @Scheduled(fixedRate = 30000, initialDelay = 30000)
  76. @RedisLock(value = "gift_order_batch_cancel", expire = 3, unit = TimeUnit.MINUTES)
  77. public void batchCancelGiftOrder() {
  78. List<GiftOrder> orders = giftOrderRepo.findByStatusAndCreatedAtBeforeAndDelFalse(OrderStatus.NOT_PAID,
  79. LocalDateTime.now().minusSeconds(orderCancelInterval));
  80. orders.forEach(o -> {
  81. try {
  82. GiftOrder order = giftOrderRepo.findById(o.getId()).orElseThrow(new BusinessException("订单不存在"));
  83. if (order.getStatus() == OrderStatus.NOT_PAID && canCancel(order.getId().toString())) {
  84. giftOrderService.cancel(order);
  85. }
  86. } catch (Exception ignored) {
  87. }
  88. });
  89. }
  90. private boolean canCancel(String id) {
  91. String channel = null;
  92. Object payTmp = redisTemplate.opsForValue().get(RedisKeys.PAY_TMP + id);
  93. log.info("payTmp {}", payTmp);
  94. if (payTmp != null) {
  95. channel = (String) payTmp;
  96. }
  97. PayQuery query = new PayQuery();
  98. try {
  99. query = orderPayService.query(id, channel);
  100. } catch (Exception e) {
  101. query.setExist(false);
  102. }
  103. if (query.isExist()) {
  104. if (query.getStatus() != null) {
  105. switch (query.getStatus()) {
  106. case SUCCESS:
  107. case PENDING:
  108. log.info("订单 {}, 状态 {}, 不能取消", id, query.getStatus().name());
  109. return false;
  110. default:
  111. log.info("订单 {}, 状态 {}, 可以取消", id, query.getStatus().name());
  112. return true;
  113. }
  114. }
  115. }
  116. return true;
  117. }
  118. @Scheduled(fixedRate = 30000)
  119. public void batchCancelledAuctionOrder() {
  120. List<AuctionOrder> orders = auctionOrderRepo
  121. .findByStatusAndCreatedAtBeforeAndDelFalse(AuctionOrderStatus.NOT_PAID,
  122. LocalDateTime.now().minusSeconds(orderCancelInterval));
  123. orders.parallelStream().forEach(o -> {
  124. try {
  125. AuctionOrder order = auctionOrderRepo.findById(o.getId()).orElseThrow(new BusinessException("订单不存在"));
  126. if (order.getStatus() == AuctionOrderStatus.NOT_PAID) {
  127. auctionOrderService.cancel(order);
  128. }
  129. } catch (Exception e) {
  130. log.error("取消拍卖订单错误 " + o.getId(), e);
  131. }
  132. });
  133. }
  134. }