1. 程式人生 > 程式設計 >Java實現商城訂單超時取消功能

Java實現商城訂單超時取消功能

大多數的B2C商城專案都會有限時活動,當用戶下單後都會有支付超時時間,當訂單超時後訂單的狀態就會自動變成已取消 ,這個功能的實現有很多種方法,本文的實現方法適合大多數比較小的商城使用。

實現原理:

利用 jdk 的 DelayQueue的阻塞佇列的特性實現。在專案啟動時開啟一個執行緒處理 DelayQueue 佇列裡彈出的超時訂單物件,訂單未超時該執行緒處於等待中。

DelayQueue的簡單介紹:

DelayQueue類的主要作用:是一個無界的BlockingQueue,用於放置實現了Delayed介面的物件,其中的物件只能在其到期時才能從佇列中取走。這種佇列是有序的,即隊頭物件的延遲到期時間最長。注意:不能將null元素放置到這種佇列中。

實現方式 :

1.建立一個實現Delayed介面的 order 類並重寫compareTo和 getDelay方法

2.建立一個幫助類OrderCollection(訂單的增刪查)

3. 建立CancellOrder類

在生成訂單時將訂單號建立時間和過期時間封裝成一個實現Delayed介面的物件存入DelayQueue佇列中,當該訂單支付完成後將該物件從佇列中移除,(為了保證不丟失訂單建議在專案啟動時將資料庫中的符合條件的訂單初始化到DelayQueue佇列中 )

實現程式碼如下:

/**
 * 類說明
 *
 * @author grl
 * @date 2019年12月16日 新建
 */
public class Order implements Delayed {
  private String orderShopNum;
  /**
  * 1-普通活動 2-限時活動 3-拼購活動
  */
  private int orderType;
  private long orderCreateTime;
  private long expTime;
  public Order(String orderShopNum,int orderType,Date createTime) {
   if (StringUtils.isNotBlank(orderShopNum)) {
     this.orderShopNum = orderShopNum.trim();
   }
   if (createTime == null) {
     this.orderCreateTime = System.currentTimeMillis();
   } else {
     this.orderCreateTime = createTime.getTime();
   }
   this.orderType = orderType;
   if (orderType == 2) {
     this.expTime = TimeUnit.MILLISECONDS.convert(Const.LIMIT_ACTIVITY_EXPIRATION_TIME,TimeUnit.MINUTES)
        + createTime.getTime();
   }if(orderType == 3){
     this.expTime = TimeUnit.MILLISECONDS.convert(Const.LIMIT_GROUP_BUY_EXPIRATION_TIME,TimeUnit.MINUTES)
        + createTime.getTime();
   } else {
     this.expTime = TimeUnit.MILLISECONDS.convert(Const.ORDER_PAYMENT_DEADLINE,TimeUnit.DAYS)
        + createTime.getTime();
   }
  }
  public String getOrderShopNum() {
   return orderShopNum;
  }
  public long getOrderCreateTime() {
   return orderCreateTime;
  }
  public long getExpTime() {
   return expTime;
  }
  public int getOrderType() {
   return orderType;
  }
  @Override
  public int compareTo(Delayed o) {
   return Long.valueOf(this.expTime).compareTo(Long.valueOf(((Order) o).expTime));
  }
  @Override
  public long getDelay(TimeUnit unit) {
   return unit.convert(this.expTime - System.currentTimeMillis(),TimeUnit.MILLISECONDS);
  }
 
}
 
/**
 * 類說明
 *
 * @author grl
 * @date 2019年12月16日 新建
 */
public class OrderCollection {
  /**
  * 訂單管理集合
  */
  private static DelayQueue<Order> orderList = new DelayQueue<Order>();
  private OrderCollection() {
  }
  /**
  * 獲取訂單集合
  * @author grl
  * @return
  */
  protected static DelayQueue getOrderCollection() {
   return orderList;
  } 
  /**
  * 向集合中新增訂單
  * 
  * @author grl
  * @param order
  * @return
  */
  public static boolean add(Order order) {
   boolean flag = false;
   if (order != null && StringUtils.isNotBlank(order.getOrderShopNum())) {
     flag = orderList.offer(order);
   }
   return flag;
  }
  /**
  * 從集合中刪除訂單
  * 
  * @author grl
  * @param orderShopNum
  * @return
  */
  public static boolean remove(String orderShopNum) {
   boolean flag = false;
   Order thisOrder = null;
   if (StringUtils.isNotBlank(orderShopNum)) {
     orderShopNum = orderShopNum.trim();
     for (Order order : orderList) {
      String orderNum = order.getOrderShopNum();
      if (orderNum.equals(orderShopNum)) {
        thisOrder = order;
      }
     }
     if (thisOrder != null) {
      flag = orderList.remove(thisOrder);
     }
   }
   return flag;
  }
  /**
  * 獲取訂單的過期剩餘時間
  * 
  * @author grl
  * @param orderShopNum
  * @param unit
  * @return -1 已經過期
  */
  public static long getDelay(String orderShopNum) {
   long time = -1;
   if (StringUtils.isNotBlank(orderShopNum)) {
     orderShopNum = orderShopNum.trim();
     for (Order order : orderList) {
      String orderNum = order.getOrderShopNum();
      if (orderNum.equals(orderShopNum)) {
        time = order.getDelay(TimeUnit.MILLISECONDS);
        if(time<5000) {
         time = -1;
        }
      }
     }
   }
   return time;
  }
}
 

/**
 * 類說明
 *
 * @author grl
 * @date 2019年12月16日 新建
 */
@Component
public class CancellOrder implements Runnable {
  private static final Logger log = LoggerFactory.getLogger(CancellOrder.class);
  @Override
  public void run() {
   while (true) {
     try {
      Order take = OrderCollection.getOrderCollection().take();
      String orderShopNum = take.getOrderShopNum();
      int orderType = take.getOrderType();
      // 業務邏輯操作
     } catch (InterruptedException e) {
      e.printStackTrace();
      log.error("CancellOrder DelayQueue 錯誤 {}",e.getMessage());
     }
   }
  }
}

總結

以上所述是小編給大家介紹的Java實現商城訂單超時取消功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對我們網站的支援!
如果你覺得本文對你有幫助,歡迎轉載,煩請註明出處,謝謝!