OrderCancelService.java 7.4 KB

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