700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 7天自动收货 30分钟不支付订单自动取消是如何实现的?

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

时间:2022-02-09 18:28:49

相关推荐

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

完整的代码在:GitHub - xjs1919/enumdemo: 公众号【爪哇优太儿】用测试代码下面的order_auto_confirm。

1.我们以支付以后7天自动收货为例来说明下:

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

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

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

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

看下具体的代码:

@Controller@RequestMapping(value = "")public class OrderController {@AutowiredDelayService delayService;@AutowiredRedisService redisServie;@AutowiredConfigService configService;//模拟数据库private List<Long> ordeIds = new ArrayList<Long>();private static final Logger log = Logger.getLogger(OrderController.class);@RequestMapping(value = "/order", method = RequestMethod.GET)public String order(final HttpServletRequest request, final Model model) {return "order";}@RequestMapping(value = "/pay", method = RequestMethod.GET)@ResponseBodypublic Response<Void> pay(final HttpServletRequest request, final Model model) {final long orderId = Long.parseLong(request.getParameter("orderId"));ordeIds.add(orderId);log.error("订单已支付:"+orderId);//把订单插入到待收货的队列和redisThreadPoolUtil.execute(new Runnable(){@Overridepublic void run() {//1 插入到待收货队列DSHOrder dshOrder = new DSHOrder(orderId, configService.getDshTimeOut());delayService.add(dshOrder);log.error("订单入队:"+orderId);//2插入到redisredisServie.set(Constants.RedisKey.DSH_PREFIX+orderId, dshOrder, RedisService.DB.DSH);log.error("订单入redis:"+orderId);}});return new Response<Void>(0,"成功");}@RequestMapping(value = "/confirm_delivery", method = RequestMethod.GET)@ResponseBodypublic Response<Void> confirm_delivery(final HttpServletRequest request, final Model model) {final long orderId = Long.parseLong(request.getParameter("orderId"));ordeIds.remove(orderId);log.error("订单已确认收货:"+orderId);//从delay队列删除,从redis删除ThreadPoolUtil.execute(new Runnable(){public void run(){//从delay队列删除delayService.remove(orderId);log.error("订单手动出队:"+orderId);//从redis删除redisServie.delete(Constants.RedisKey.DSH_PREFIX+orderId, RedisService.DB.DSH);log.error("订单手动出redis:"+orderId);}});return new Response<Void>(0,"成功");}}

@Servicepublic class DelayService {private static final Logger log = Logger.getLogger(DelayService.class);@AutowiredConfigService configService;private boolean start ; private OnDelayedListener listener;private DelayQueue<DSHOrder> delayQueue = new DelayQueue<DSHOrder>();public static interface OnDelayedListener{public void onDelayedArrived(DSHOrder order);}public void start(OnDelayedListener listener){if(start){return;}log.error("DelayService 启动");start = true;this.listener = listener;new Thread(new Runnable(){public void run(){try{while(true){DSHOrder order = delayQueue.take();if(DelayService.this.listener != null){DelayService.this.listener.onDelayedArrived(order);}}}catch(Exception e){e.printStackTrace();}}}).start();;}public void add(DSHOrder order){delayQueue.put(order);}public boolean remove(DSHOrder order){return delayQueue.remove(order);}public void add(long orderId){delayQueue.put(new DSHOrder(orderId, configService.getDshTimeOut()));}public void remove(long orderId){DSHOrder[] array = delayQueue.toArray(new DSHOrder[]{});if(array == null || array.length <= 0){return;}DSHOrder target = null;for(DSHOrder order : array){if(order.getOrderId() == orderId){target = order;break;}}if(target != null){delayQueue.remove(target);}}}

public class DSHOrder implements Delayed {private long orderId;private long startTime;public DSHOrder(){}/*** orderId:订单id* timeout:自动收货的超时时间,秒* */public DSHOrder(long orderId, int timeout){this.orderId = orderId;this.startTime = System.currentTimeMillis() + timeout*1000L;}@Overridepublic int compareTo(Delayed other) {if (other == this){return 0;}if(other instanceof DSHOrder){DSHOrder otherRequest = (DSHOrder)other;long otherStartTime = otherRequest.getStartTime();return (int)(this.startTime - otherStartTime);}return 0;}@Overridepublic long getDelay(TimeUnit unit) {return unit.convert(startTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + (int) (orderId ^ (orderId >>> 32));result = prime * result + (int) (startTime ^ (startTime >>> 32));return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;DSHOrder other = (DSHOrder) obj;if (orderId != other.orderId)return false;if (startTime != other.startTime)return false;return true;}public long getStartTime() {return startTime;}public long getOrderId() {return orderId;}public void setOrderId(long orderId) {this.orderId = orderId;}public void setStartTime(long startTime) {this.startTime = startTime;}@Overridepublic String toString() {return "DSHOrder [orderId=" + orderId + ", startTime=" + startTime + "]";}}

@Servicepublic class StartupListener implements ApplicationListener<ContextRefreshedEvent> {private static final Logger log = Logger.getLogger(StartupListener.class);@AutowiredDelayService delayService;@AutowiredRedisService redisService;@Overridepublic void onApplicationEvent(ContextRefreshedEvent evt) {log.error(">>>>>>>>>>>>系统启动完成,onApplicationEvent()");if (evt.getApplicationContext().getParent() == null) {return;}//自动收货delayService.start(new OnDelayedListener(){@Overridepublic void onDelayedArrived(final DSHOrder order) {//异步来做ThreadPoolUtil.execute(new Runnable(){public void run(){long orderId = order.getOrderId();//查库判断是否需要自动收货log.error("自动确认收货,onDelayedArrived():"+orderId);//从redis删除redisService.delete(Constants.RedisKey.DSH_PREFIX+orderId, RedisService.DB.DSH);log.error("自动确认收货,删除redis:"+orderId);}});}});//查找需要入队的订单ThreadPoolUtil.execute(new Runnable(){@Overridepublic void run() {log.error("查找需要入队的订单");//扫描redis,找到所有可能的orderIdList<String> keys = redisService.scan(RedisService.DB.DSH);if(keys == null || keys.size() <= 0){return;}log.error("需要入队的订单keys:"+keys);//写到DelayQueuefor(String key : keys){DSHOrder order = redisService.get(key, DSHOrder.class, RedisService.DB.DSH);log.error("读redis,key:"+key);if(order != null){delayService.add(order);log.error("订单自动入队:"+order.getOrderId());}} }}); }}

完整的代码下载:GitHub - xjs1919/enumdemo: 公众号【爪哇优太儿】用测试代码下面的order_auto_confirm。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。