全屏网站 欣赏,不懂见网站怎么办,更换wordpress登录界面,小程序搭建需要什么前几天对实习还是继续学习技术产生了抉择#xff0c;问了一个前辈#xff0c;他抛给我一个问题#xff0c;怎么做15分钟订单自动取消#xff0c;我说然后到时间之后#xff0c;自动执行这个订单关闭业务#xff0c;比如把锁了的库存给解开等等操作#xff0c;然后在数据… 前几天对实习还是继续学习技术产生了抉择问了一个前辈他抛给我一个问题怎么做15分钟订单自动取消我说然后到时间之后自动执行这个订单关闭业务比如把锁了的库存给解开等等操作然后在数据库里肯定要有体现比如抖音查我的订单内一块在前段应该显示已过期把支付的按钮变灰或者取消支付的时候不能直接对库存进行操作应该是支付模块调用订单模块调用库存模块。 然后把理论予以实现发现需要考虑的点还是有一些的。
功能架构 该功能使用了三大模块解除耦合保证高可用性从高层到底层分别是支付模块-订单模块-商品模块各司其职支付模块主要负责支付退款等相应功能订单模块主要负责订单查询订单创建删除订单相关功能商品模块主要负责商品上下架补货查货相关功能是环环相扣的支付模块通过操控订单实现支付订单模块通过操控商品来实现订单创建等操作。
功能实现流程 由于是全栈开发本功能实现流程会涵盖前后端都有。由于管理模块就是添加商品等等操作在前端并没有实现就先在数据库里加一些商品。sql如下 然后写一个接口获取商品列表然后前端进行渲染效果如下 测试阶段未接入微信支付等但有字段标识后期方便扩展渲染的时候只需要有一点判断支付类型如果是钱支付就渲染成的形式如果是积分就渲染成积分的形式。然后点击兑换会弹出一个弹出框如下 扩展一些信息也会变得非常简单由于数据库里设置了两个字段一个是销售价也就是优惠后的价格一个是原价直接在前端算出优惠金额即可。然后点击提交订单就会向后端去发送一个创建的请求java代码如下所示 // 这里先把订单持续事件设置成15秒// 1.1 先校验参数看看该商品是否有库存CommonGoodPo good goodMapper.queryGoodById(dto.getGoodId());if (good null) return Result.error(已查询不到该商品);Boolean isPut good.getIsPut();if (!isPut) return Result.error(无法对已下架的商品下订单);// 1.2 看看库存还够不够Boolean haveStore good.getHaveStore();Integer store good.getStore();if (haveStore store 0) return Result.error(库存不足无法下单);// 库存足就锁定一个库存if (haveStore) goodMapper.lockStore(good.getId());// 1.3 todo 如果有一个人只能买一单等等限制可继续扩展// 2.1 然后就要生成订单的信息了比如订单的id这里起始应该使用杂乱的数字字母等作为id图方便就直接使用自增id// 2.2 然后生成开始时间和结束时间LocalDateTime now LocalDateTime.now();LocalDateTime end LocalDateTime.now().plusMinutes(15); // 15分钟写死PopOrderVo popOrderVo new PopOrderVo(null, good.getId(), now, end, 15 * 60, dto.getAccount());orderMapper.creatOrder(popOrderVo);// 3 准备对象发送消息String mes JSON.toJSONString(popOrderVo);sendDelayMessage(mes, 60 * 15, RabbitConstants.DELAY_ORDER_DEL_DIRECT_EXCHANGE, RabbitConstants.DELAY_ORDER_KEY);// 然后封装一下给前端然后前端得到信息后弹出弹出层在我的订单里也可以找到该信息return Result.ok(popOrderVo); 代码逻辑主要分为三部分校验参数然后去执行sql就是向数据库的order表里去添加一条订单消息并且要锁库存最后向rabbitMQ里发一条延迟消息这个是封装好的方法。到期执行的方法如下所示 log.error(我要开始喽);// 把msg转成对象PopOrderVo popOrderVo null;try {popOrderVo JSON.parseObject(msg, PopOrderVo.class);} catch (Exception e) {throw new RuntimeException(请调用符合规定的api类型转换错误无法转换为PopOrderVo);}// 自动取消订单逻辑LocalDateTime now LocalDateTime.now();Integer orderId popOrderVo.getOrderId();Integer goodId popOrderVo.getGoodId();// 修改订单状态orderMapper.finishOrder(orderId, now, ORDER_STATUS_OVERTIME);// 把锁了的库存释放goodMapper.unLockStore(goodId);log.error(我结束喽);
就是去校验一下参数然后去解锁库存然后修改订单状态。
订单表如下所示 然后在点击提交订单后弹出支付页面并有前端实现的倒计时。 然后会显示一些订单信息倒计时到了之后按钮会变成灰色并无法点击点击支付按钮后进入到后端逻辑。代码如下 OverrideTransactionalpublic Result payOrder(PayOrderDto dto) {Integer orderId dto.getOrderId();OrderPo orderInfo orderMapper.getOrderInfo(orderId);Integer goodId orderInfo.getGoodId();LocalDateTime now LocalDateTime.now();CommonGoodPo good goodMapper.queryGoodById(goodId);// 1 先需要校验参数// 1.1 看过没过期如果现在的时间在截止时间之后则证明过期了if (now.isAfter(orderInfo.getEndTime())) {return Result.error(该订单已经过期请重新下单);}// 1.2 看一下状态是不是待支付状态if (orderInfo.getStatus() ! 0) return Result.error(该订单已被处理请刷新重试);// 1.3 看余额够不够Boolean isEnough payMapper.checkBalance(orderInfo.getAccount(), good.getSalePrice());// 2.1 如果不够直接报错余额不足if (!isEnough) return Result.error(你的余额不足无法完成支付);// 2.2 如果够扣减余额payMapper.decreaseBalance(orderInfo.getAccount(), good.getSalePrice());// 2 需要进行三个方面的处理// 2.1 商品给增加销量等等goodMapper.increaseSales(goodId);// 2.2 设置订单状态截至时间等orderMapper.finishOrder(orderId, now, ORDER_STATUS_SUCCESS);// 2.3 记录支付日志payMapper.logPay(good.getSalePrice(), good.getPayType(), orderInfo.getAccount(), now, goodId);
// return null;return Result.ok(支付成功);}
支付逻辑比较简单就是校验参数但需要注意需要检验一下订单状态因为可能因为网络问题等等导致请求到后端的时候出现时间延迟问题出现状态已经不是待支付状态已经被修改的问题处理幂等问题余额不足问题这时就不能再进行支付要对订单进行一下处理。如果满足条件就进行sql操作。
然后在前端为了订单的丢失又写了一个我的订单页面如下所示 可以根据不同的状态去筛选不同的订单列表然后并可以在此页面完成支付。
至此本功能结束使用的是rabbitMQ的延迟队列实现定时操作也可以使用xxl-job直接使用策略模式扩展一下即可在复习专栏里有关于设计模式的文章和例子后续有时间会讲一下定时操作策略的扩展。