15天自动收货,30分钟不支付订单自动取消是如何实现的?

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/preferG/article/details/80025103


(1)用户支付完成以后,把订单ID插入到内存的一个DelayQueue中,同时插入到Redis中。

(2)15天之内,用户点击了确认收货,则从DelayQueue中删除,从Redis中删除。

(3)超过7天,DelayQueue中的订单ID出队,查询数据库,改状态为自动收货,删除redis。

(4)如果15天之内,web服务器重启过,则web服务器启动以后,从redis中读取待收货的订单,插入到DelayQueue。

看下具体的代码:

[java]  view plain  copy
  1. @Controller  
  2. @RequestMapping(value = "")  
  3. public class OrderController {  
  4.     @Autowired  
  5.     DelayService delayService;  
  6.     @Autowired  
  7.     RedisService redisServie;  
  8.     @Autowired  
  9.     ConfigService configService;  
  10.     //模拟数据库  
  11.     private List<Long> ordeIds = new ArrayList<Long>();  
  12.     private static final Logger log = Logger.getLogger(OrderController.class);  
  13.     @RequestMapping(value = "/order", method = RequestMethod.GET)  
  14.     public String order(final HttpServletRequest request, final Model model) {  
  15.         return "order";  
  16.     }  
  17.     @RequestMapping(value = "/pay", method = RequestMethod.GET)  
  18.     @ResponseBody  
  19.     public Response<Void> pay(final HttpServletRequest request, final Model model) {  
  20.         final long orderId = Long.parseLong(request.getParameter("orderId"));  
  21.         ordeIds.add(orderId);  
  22.         log.error("订单已支付:"+orderId);  
  23.         //把订单插入到待收货的队列和redis  
  24.         ThreadPoolUtil.execute(new Runnable(){  
  25.             @Override  
  26.             public void run() {  
  27.                 //1 插入到待收货队列  
  28.                 DSHOrder dshOrder = new DSHOrder(orderId, configService.getDshTimeOut());  
  29.                 delayService.add(dshOrder);  
  30.                 log.error("订单入队:"+orderId);  
  31.                 //2插入到redis  
  32.                 redisServie.set(Constants.RedisKey.DSH_PREFIX+orderId, dshOrder, RedisService.DB.DSH);  
  33.                 log.error("订单入redis:"+orderId);  
  34.             }  
  35.         });  
  36.         return new Response<Void>(0,"成功");  
  37.     }  
  38.     @RequestMapping(value = "/confirm_delivery", method = RequestMethod.GET)  
  39.     @ResponseBody  
  40.     public Response<Void> confirm_delivery(final HttpServletRequest request, final Model model) {  
  41.         final long orderId = Long.parseLong(request.getParameter("orderId"));  
  42.         ordeIds.remove(orderId);  
  43.         log.error("订单已确认收货:"+orderId);  
  44.         //从delay队列删除,从redis删除  
  45.         ThreadPoolUtil.execute(new Runnable(){  
  46.             public void run(){  
  47.                 //从delay队列删除  
  48.                 delayService.remove(orderId);  
  49.                 log.error("订单手动出队:"+orderId);  
  50.                 //从redis删除  
  51.                 redisServie.delete(Constants.RedisKey.DSH_PREFIX+orderId, RedisService.DB.DSH);  
  52.                 log.error("订单手动出redis:"+orderId);  
  53.             }  
  54.         });  
  55.         return new Response<Void>(0,"成功");  
  56.     }  
  57. }  

[java]  view plain  copy
  1. @Service  
  2. public class DelayService {  
  3.       
  4.     private static final Logger log = Logger.getLogger(DelayService.class);  
  5.       
  6.     @Autowired  
  7.     ConfigService configService;  
  8.       
  9.     private boolean start ;    
  10.     private OnDelayedListener listener;  
  11.     private DelayQueue<DSHOrder> delayQueue = new DelayQueue<DSHOrder>();  
  12.       
  13.     public static interface OnDelayedListener{  
  14.         public void onDelayedArrived(DSHOrder order);  
  15.     }  
  16.   
  17.     public void start(OnDelayedListener listener){  
  18.         if(start){  
  19.             return;  
  20.         }  
  21.         log.error("DelayService 启动");  
  22.         start = true;  
  23.         this.listener = listener;  
  24.         new Thread(new Runnable(){  
  25.             public void run(){  
  26.                 try{  
  27.                     while(true){  
  28.                         DSHOrder order = delayQueue.take();  
  29.                         if(DelayService.this.listener != null){  
  30.                             DelayService.this.listener.onDelayedArrived(order);  
  31.                         }  
  32.                     }  
  33.                 }catch(Exception e){  
  34.                     e.printStackTrace();  
  35.                 }  
  36.             }  
  37.         }).start();;  
  38.     }  
  39.       
  40.     public void add(DSHOrder order){  
  41.         delayQueue.put(order);  
  42.     }  
  43.   
  44.     public boolean remove(DSHOrder order){  
  45.         return delayQueue.remove(order);  
  46.     }  
  47.       
  48.     public void add(long orderId){  
  49.         delayQueue.put(new DSHOrder(orderId, configService.getDshTimeOut()));  
  50.     }  
  51.       
  52.     public void remove(long orderId){  
  53.         DSHOrder[] array = delayQueue.toArray(new DSHOrder[]{});  
  54.         if(array == null || array.length <= 0){  
  55.             return;  
  56.         }  
  57.         DSHOrder target = null;  
  58.         for(DSHOrder order : array){  
  59.             if(order.getOrderId() == orderId){  
  60.                 target = order;  
  61.                 break;  
  62.             }  
  63.         }  
  64.         if(target != null){  
  65.             delayQueue.remove(target);  
  66.         }  
  67.     }  
  68. }  

[java]  view plain  copy
  1. public class DSHOrder implements Delayed {  
  2.       
  3.     private long orderId;  
  4.     private long startTime;  
  5.       
  6.     public DSHOrder(){  
  7.           
  8.     }  
  9.       
  10.     /** 
  11.      * orderId:订单id 
  12.      * timeout:自动收货的超时时间,秒 
  13.      * */  
  14.     public DSHOrder(long orderId, int timeout){  
  15.         this.orderId = orderId;  
  16.         this.startTime = System.currentTimeMillis() + timeout*1000L;  
  17.     }  
  18.     @Override  
  19.     public int compareTo(Delayed other) {  
  20.         if (other == this){  
  21.             return 0;  
  22.         }  
  23.         if(other instanceof DSHOrder){  
  24.             DSHOrder otherRequest = (DSHOrder)other;  
  25.             long otherStartTime = otherRequest.getStartTime();  
  26.             return (int)(this.startTime - otherStartTime);  
  27.         }  
  28.         return 0;  
  29.     }  
  30.   
  31.     @Override  
  32.     public long getDelay(TimeUnit unit) {  
  33.         return unit.convert(startTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);  
  34.     }  
  35.   
  36.     @Override  
  37.     public int hashCode() {  
  38.         final int prime = 31;  
  39.         int result = 1;  
  40.         result = prime * result + (int) (orderId ^ (orderId >>> 32));  
  41.         result = prime * result + (int) (startTime ^ (startTime >>> 32));  
  42.         return result;  
  43.     }  
  44.   
  45.     @Override  
  46.     public boolean equals(Object obj) {  
  47.         if (this == obj)  
  48.             return true;  
  49.         if (obj == null)  
  50.             return false;  
  51.         if (getClass() != obj.getClass())  
  52.             return false;  
  53.         DSHOrder other = (DSHOrder) obj;  
  54.         if (orderId != other.orderId)  
  55.             return false;  
  56.         if (startTime != other.startTime)  
  57.             return false;  
  58.         return true;  
  59.     }  
  60.   
  61.     public long getStartTime() {  
  62.         return startTime;  
  63.     }  
  64.   
  65.     public long getOrderId() {  
  66.         return orderId;  
  67.     }  
  68.   
  69.     public void setOrderId(long orderId) {  
  70.         this.orderId = orderId;  
  71.     }  
  72.   
  73.     public void setStartTime(long startTime) {  
  74.         this.startTime = startTime;  
  75.     }  
  76.   
  77.     @Override  
  78.     public String toString() {  
  79.         return "DSHOrder [orderId=" + orderId + ", startTime=" + startTime + "]";  
  80.     }  
  81. }  

[java]  view plain  copy
  1. @Service  
  2. public class StartupListener implements ApplicationListener<ContextRefreshedEvent> {  
  3.       
  4.     private static final Logger log = Logger.getLogger(StartupListener.class);  
  5.   
  6.     @Autowired  
  7.     DelayService delayService;  
  8.     @Autowired  
  9.     RedisService redisService;  
  10.       
  11.       
  12.     @Override  
  13.     public void onApplicationEvent(ContextRefreshedEvent evt) {  
  14.         log.error(">>>>>>>>>>>>系统启动完成,onApplicationEvent()");  
  15.         if (evt.getApplicationContext().getParent() == null) {  
  16.             return;  
  17.         }  
  18.         //自动收货  
  19.         delayService.start(new OnDelayedListener(){  
  20.             @Override  
  21.             public void onDelayedArrived(final DSHOrder order) {  
  22.                 //异步来做  
  23.                 ThreadPoolUtil.execute(new Runnable(){  
  24.                     public void run(){  
  25.                         long orderId = order.getOrderId();  
  26.                         //查库判断是否需要自动收货  
  27.                         log.error("自动确认收货,onDelayedArrived():"+orderId);  
  28.                         //从redis删除  
  29.                         redisService.delete(Constants.RedisKey.DSH_PREFIX+orderId, RedisService.DB.DSH);  
  30.                         log.error("自动确认收货,删除redis:"+orderId);  
  31.                     }  
  32.                 });  
  33.             }  
  34.         });  
  35.         //查找需要入队的订单  
  36.         ThreadPoolUtil.execute(new Runnable(){  
  37.             @Override  
  38.             public void run() {  
  39.                 log.error("查找需要入队的订单");  
  40.                 //扫描redis,找到所有可能的orderId  
  41.                 List<String> keys = redisService.scan(RedisService.DB.DSH);  
  42.                 if(keys == null || keys.size() <= 0){  
  43.                     return;  
  44.                 }  
  45.                 log.error("需要入队的订单keys:"+keys);  
  46.                 //写到DelayQueue  
  47.                 for(String key : keys){  
  48.                     DSHOrder order = redisService.get(key, DSHOrder.class, RedisService.DB.DSH);  
  49.                     log.error("读redis,key:"+key);  
  50.                     if(order != null){  
  51.                         delayService.add(order);      
  52.                         log.error("订单自动入队:"+order.getOrderId());  
  53.                     }  
  54.                 }   
  55.             }  
  56.         });   
  57.     }  
  58. }  

(1)用户支付完成以后,把订单ID插入到内存的一个DelayQueue中,同时插入到Redis中。

(2)7天之内,用户点击了确认收货,则从DelayQueue中删除,从Redis中删除。

(3)超过7天,DelayQueue中的订单ID出队,查询数据库,改状态为自动收货,删除redis。

(4)如果7天之内,web服务器重启过,则web服务器启动以后,从redis中读取待收货的订单,插入到DelayQueue。

看下具体的代码:

[java]  view plain  copy
  1. @Controller  
  2. @RequestMapping(value = "")  
  3. public class OrderController {  
  4.     @Autowired  
  5.     DelayService delayService;  
  6.     @Autowired  
  7.     RedisService redisServie;  
  8.     @Autowired  
  9.     ConfigService configService;  
  10.     //模拟数据库  
  11.     private List<Long> ordeIds = new ArrayList<Long>();  
  12.     private static final Logger log = Logger.getLogger(OrderController.class);  
  13.     @RequestMapping(value = "/order", method = RequestMethod.GET)  
  14.     public String order(final HttpServletRequest request, final Model model) {  
  15.         return "order";  
  16.     }  
  17.     @RequestMapping(value = "/pay", method = RequestMethod.GET)  
  18.     @ResponseBody  
  19.     public Response<Void> pay(final HttpServletRequest request, final Model model) {  
  20.         final long orderId = Long.parseLong(request.getParameter("orderId"));  
  21.         ordeIds.add(orderId);  
  22.         log.error("订单已支付:"+orderId);  
  23.         //把订单插入到待收货的队列和redis  
  24.         ThreadPoolUtil.execute(new Runnable(){  
  25.             @Override  
  26.             public void run() {  
  27.                 //1 插入到待收货队列  
  28.                 DSHOrder dshOrder = new DSHOrder(orderId, configService.getDshTimeOut());  
  29.                 delayService.add(dshOrder);  
  30.                 log.error("订单入队:"+orderId);  
  31.                 //2插入到redis  
  32.                 redisServie.set(Constants.RedisKey.DSH_PREFIX+orderId, dshOrder, RedisService.DB.DSH);  
  33.                 log.error("订单入redis:"+orderId);  
  34.             }  
  35.         });  
  36.         return new Response<Void>(0,"成功");  
  37.     }  
  38.     @RequestMapping(value = "/confirm_delivery", method = RequestMethod.GET)  
  39.     @ResponseBody  
  40.     public Response<Void> confirm_delivery(final HttpServletRequest request, final Model model) {  
  41.         final long orderId = Long.parseLong(request.getParameter("orderId"));  
  42.         ordeIds.remove(orderId);  
  43.         log.error("订单已确认收货:"+orderId);  
  44.         //从delay队列删除,从redis删除  
  45.         ThreadPoolUtil.execute(new Runnable(){  
  46.             public void run(){  
  47.                 //从delay队列删除  
  48.                 delayService.remove(orderId);  
  49.                 log.error("订单手动出队:"+orderId);  
  50.                 //从redis删除  
  51.                 redisServie.delete(Constants.RedisKey.DSH_PREFIX+orderId, RedisService.DB.DSH);  
  52.                 log.error("订单手动出redis:"+orderId);  
  53.             }  
  54.         });  
  55.         return new Response<Void>(0,"成功");  
  56.     }  
  57. }  

[java]  view plain  copy
  1. @Service  
  2. public class DelayService {  
  3.       
  4.     private static final Logger log = Logger.getLogger(DelayService.class);  
  5.       
  6.     @Autowired  
  7.     ConfigService configService;  
  8.       
  9.     private boolean start ;    
  10.     private OnDelayedListener listener;  
  11.     private DelayQueue<DSHOrder> delayQueue = new DelayQueue<DSHOrder>();  
  12.       
  13.     public static interface OnDelayedListener{  
  14.         public void onDelayedArrived(DSHOrder order);  
  15.     }  
  16.   
  17.     public void start(OnDelayedListener listener){  
  18.         if(start){  
  19.             return;  
  20.         }  
  21.         log.error("DelayService 启动");  
  22.         start = true;  
  23.         this.listener = listener;  
  24.         new Thread(new Runnable(){  
  25.             public void run(){  
  26.                 try{  
  27.                     while(true){  
  28.                         DSHOrder order = delayQueue.take();  
  29.                         if(DelayService.this.listener != null){  
  30.                             DelayService.this.listener.onDelayedArrived(order);  
  31.                         }  
  32.                     }  
  33.                 }catch(Exception e){  
  34.                     e.printStackTrace();  
  35.                 }  
  36.             }  
  37.         }).start();;  
  38.     }  
  39.       
  40.     public void add(DSHOrder order){  
  41.         delayQueue.put(order);  
  42.     }  
  43.   
  44.     public boolean remove(DSHOrder order){  
  45.         return delayQueue.remove(order);  
  46.     }  
  47.       
  48.     public void add(long orderId){  
  49.         delayQueue.put(new DSHOrder(orderId, configService.getDshTimeOut()));  
  50.     }  
  51.       
  52.     public void remove(long orderId){  
  53.         DSHOrder[] array = delayQueue.toArray(new DSHOrder[]{});  
  54.         if(array == null || array.length <= 0){  
  55.             return;  
  56.         }  
  57.         DSHOrder target = null;  
  58.         for(DSHOrder order : array){  
  59.             if(order.getOrderId() == orderId){  
  60.                 target = order;  
  61.                 break;  
  62.             }  
  63.         }  
  64.         if(target != null){  
  65.             delayQueue.remove(target);  
  66.         }  
  67.     }  
  68. }  

[java]  view plain  copy
  1. public class DSHOrder implements Delayed {  
  2.       
  3.     private long orderId;  
  4.     private long startTime;  
  5.       
  6.     public DSHOrder(){  
  7.           
  8.     }  
  9.       
  10.     /** 
  11.      * orderId:订单id 
  12.      * timeout:自动收货的超时时间,秒 
  13.      * */  
  14.     public DSHOrder(long orderId, int timeout){  
  15.         this.orderId = orderId;  
  16.         this.startTime = System.currentTimeMillis() + timeout*1000L;  
  17.     }  
  18.     @Override  
  19.     public int compareTo(Delayed other) {  
  20.         if (other == this){  
  21.             return 0;  
  22.         }  
  23.         if(other instanceof DSHOrder){  
  24.             DSHOrder otherRequest = (DSHOrder)other;  
  25.             long otherStartTime = otherRequest.getStartTime();  
  26.             return (int)(this.startTime - otherStartTime);  
  27.         }  
  28.         return 0;  
  29.     }  
  30.   
  31.     @Override  
  32.     public long getDelay(TimeUnit unit) {  
  33.         return unit.convert(startTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);  
  34.     }  
  35.   
  36.     @Override  
  37.     public int hashCode() {  
  38.         final int prime = 31;  
  39.         int result = 1;  
  40.         result = prime * result + (int) (orderId ^ (orderId >>> 32));  
  41.         result = prime * result + (int) (startTime ^ (startTime >>> 32));  
  42.         return result;  
  43.     }  
  44.   
  45.     @Override  
  46.     public boolean equals(Object obj) {  
  47.         if (this == obj)  
  48.             return true;  
  49.         if (obj == null)  
  50.             return false;  
  51.         if (getClass() != obj.getClass())  
  52.             return false;  
  53.         DSHOrder other = (DSHOrder) obj;  
  54.         if (orderId != other.orderId)  
  55.             return false;  
  56.         if (startTime != other.startTime)  
  57.             return false;  
  58.         return true;  
  59.     }  
  60.   
  61.     public long getStartTime() {  
  62.         return startTime;  
  63.     }  
  64.   
  65.     public long getOrderId() {  
  66.         return orderId;  
  67.     }  
  68.   
  69.     public void setOrderId(long orderId) {  
  70.         this.orderId = orderId;  
  71.     }  
  72.   
  73.     public void setStartTime(long startTime) {  
  74.         this.startTime = startTime;  
  75.     }  
  76.   
  77.     @Override  
  78.     public String toString() {  
  79.         return "DSHOrder [orderId=" + orderId + ", startTime=" + startTime + "]";  
  80.     }  
  81. }  

[java]  view plain  copy
  1. @Service  
  2. public class StartupListener implements ApplicationListener<ContextRefreshedEvent> {  
  3.       
  4.     private static final Logger log = Logger.getLogger(StartupListener.class);  
  5.   
  6.     @Autowired  
  7.     DelayService delayService;  
  8.     @Autowired  
  9.     RedisService redisService;  
  10.       
  11.       
  12.     @Override  
  13.     public void onApplicationEvent(ContextRefreshedEvent evt) {  
  14.         log.error(">>>>>>>>>>>>系统启动完成,onApplicationEvent()");  
  15.         if (evt.getApplicationContext().getParent() == null) {  
  16.             return;  
  17.         }  
  18.         //自动收货  
  19.         delayService.start(new OnDelayedListener(){  
  20.             @Override  
  21.             public void onDelayedArrived(final DSHOrder order) {  
  22.                 //异步来做  
  23.                 ThreadPoolUtil.execute(new Runnable(){  
  24.                     public void run(){  
  25.                         long orderId = order.getOrderId();  
  26.                         //查库判断是否需要自动收货  
  27.                         log.error("自动确认收货,onDelayedArrived():"+orderId);  
  28.                         //从redis删除  
  29.                         redisService.delete(Constants.RedisKey.DSH_PREFIX+orderId, RedisService.DB.DSH);  
  30.                         log.error("自动确认收货,删除redis:"+orderId);  
  31.                     }  
  32.                 });  
  33.             }  
  34.         });  
  35.         //查找需要入队的订单  
  36.         ThreadPoolUtil.execute(new Runnable(){  
  37.             @Override  
  38.             public void run() {  
  39.                 log.error("查找需要入队的订单");  
  40.                 //扫描redis,找到所有可能的orderId  
  41.                 List<String> keys = redisService.scan(RedisService.DB.DSH);  
  42.                 if(keys == null || keys.size() <= 0){  
  43.                     return;  
  44.                 }  
  45.                 log.error("需要入队的订单keys:"+keys);  
  46.                 //写到DelayQueue  
  47.                 for(String key : keys){  
  48.                     DSHOrder order = redisService.get(key, DSHOrder.class, RedisService.DB.DSH);  
  49.                     log.error("读redis,key:"+key);  
  50.                     if(order != null){  
  51.                         delayService.add(order);      
  52.                         log.error("订单自动入队:"+order.getOrderId());  
  53.                     }  
  54.                 }   
  55.             }  
  56.         });   
  57.     }  
  58. }  

猜你喜欢

转载自blog.csdn.net/preferG/article/details/80025103