上一篇博文我们已经介绍了购物车的原理及实现, 那么购物车再往后就是提交订单了, 订单的实现方式是怎么样的呢? 那么下面就让我们来一起学习下.
提交订单有几个关键点:
1, 用户必须登录
2, 购物车必须要有购物项
3, 购物车中购物项库存必须小于库存
4, 结算成功, 清理购物车(这个只清理购物车中已经结算的购物项)
接下来我们再来看下订单相关的两张表的设计:
订单表
订单详情表
在这里我们可以发现 订单表和 我们的购物车很像, 订单详情表和我们的购物车中的购物项很像. 明白了这些原理后我们就来看下代码的具体实现.
我们来先写Service层的方法: CartServiceImpl.java
1 @Autowired 2 private OrderDao orderDao; 3 @Autowired 4 private DetailDao detailDao; 5 //保存订单 6 public void insertOrder(Order order, String username){ 7 //订单ID 8 Long id = jedis.incr("oid"); 9 order.setId(id); 10 //用户id 11 String buyerId = jedis.get(username); 12 order.setBuyerId(Long.parseLong(buyerId)); 13 BuyerCart buyerCart = selectBuyerCartFromRedis(username); 14 List<BuyerItem> items = buyerCart.getItems(); 15 for (BuyerItem item : items) { 16 item.setSku(selectSkuById(item.getSku().getId())); 17 } 18 //运费, 由运费提供 19 order.setDeliverFee(buyerCart.getFee()); 20 //订单总金额, 由购物车提供 21 order.setTotalPrice(buyerCart.getTotalPrice()); 22 //订单金额, 由购物车提供 23 order.setOrderPrice(buyerCart.getProductPrice()); 24 //支付状态: 0到付 1待付款 2已付款 3待退款 4退款成功 5退款失败 25 if (order.getPaymentWay() == 1) { 26 order.setIsPaiy(0); 27 }else { 28 //我们这里页面上只有 两种选择: 0到付 1待付款 29 order.setIsPaiy(1); 30 } 31 //订单状态: 0提交订单 1仓库配货 2商品出库 3等待收货 4完成 5待退货 6已退货 32 order.setOrderState(0); 33 //订单生成时间 34 order.setCreateDate(new Date()); 35 //生成订单 36 orderDao.insertSelective(order); 37 38 //保存订单详情 39 for (BuyerItem item : items) { 40 Detail detail = new Detail(); 41 //订单详情表 42 /* 43 * ID:自增长 44 * 订单ID, 商品编号ID, 商品名称, 颜色中文名称, 尺码, 价格, 数量, 购物车中购物项提交数量 45 */ 46 detail.setOrderId(id); 47 detail.setProductId(item.getSku().getProductId()); 48 detail.setProductName(item.getSku().getProduct().getName()); 49 detail.setColor(item.getSku().getColor().getName()); 50 detail.setSize(item.getSku().getSize()); 51 detail.setPrice(item.getSku().getPrice()); 52 detail.setAmount(item.getAmount()); 53 54 //保存购物车中购物项 55 detailDao.insertSelective(detail); 56 57 //减库存 58 59 //清空购物车, 这里只写全部删除的方法, 如果删除某个购物项需使用jedis.hdel(); 60 jedis.del("buyerCart:" + username); 61 } 62 }
这里 是利用Redis生成主键ID, 我们前面也有对比过Redis生成主键和数据库生成主键 以及UUID的对比, 这里就不再细说了.
剩下的就是取购物车, 在这里我们可以通过username去取出skuId和购买数量amount, 因为我们在Redis存储的表名就是"buyerCart:"+username就是key是:skuId , value是amount.
剩下的就是将购物车中的内容装配到Order中即可.
接着来看下 Controller层的代码: CartController.java:
1 //去结算 2 @RequestMapping(value="/buyer/trueBuy") 3 public String trueBuy(String[] skuIds, Model model, HttpServletRequest request, HttpServletResponse response){ 4 //1, 购物车必须有商品, 5 //取出用户名 再取出购物车 6 String username = sessionProviderService.getAttributterForUsername(RequestUtils.getCSessionId(request, response)); 7 //取出所有购物车 8 BuyerCart buyerCart = cartService.selectBuyerCartFromRedisBySkuIds(skuIds, username); 9 List<BuyerItem> items = buyerCart.getItems(); 10 if (items.size() > 0) { 11 //购物车中有商品 12 //判断所勾选的商品是否都有货, 如果有一件无货, 那么就刷新页面. 13 Boolean flag = true; 14 //2, 购物车中商品必须有库存 且购买大于库存数量时视为无货. 提示: 购物车原页面不动. 有货改为无货, 加红提醒. 15 for (BuyerItem buyerItem : items) { 16 //装满购物车的购物项, 当前购物项只有skuId这一个东西, 我们还需要购物项的数量去判断是否有货 17 buyerItem.setSku(cartService.selectSkuById(buyerItem.getSku().getId())); 18 //校验库存 19 if (buyerItem.getAmount() > buyerItem.getSku().getStock()) { 20 //无货 21 buyerItem.setIsHave(false); 22 flag = false; 23 } 24 if (!flag) { 25 //无货, 原页面不动, 有货改成无货, 刷新页面. 26 model.addAttribute("buyerCart", buyerCart); 27 return "cart"; 28 } 29 } 30 }else { 31 //购物车没有商品 32 //没有商品: 1>原购物车页面刷新(购物车页面提示没有商品) 33 return "redirect:/shopping/toCart"; 34 } 35 36 37 //3, 正常进入下一个页面 38 return "order"; 39 } 40 41 42 //提交订单 43 @RequestMapping(value="/buyer/submitOrder") 44 public String submitOrder(Order order, HttpServletRequest request, HttpServletResponse response){ 45 String username = sessionProviderService.getAttributterForUsername(RequestUtils.getCSessionId(request, response)); 46 47 //保存订单 48 cartService.insertOrder(order, username); 49 50 return "success"; 51 }
上一篇 关于购物车的博文我们已经讲过, 对于"/buyer/"这样格式的请求我们的springmvc都会拦截, 拦截的形式 就是判断用户是否登录. 这里我们也不会详细说明.
这里要判断购物项中的数量是否大于库存, 如果大于库存就刷新购物车页面, 且显示该购物项无货状态.
剩下的提交订单 就是保存order到订单表, 这里面也包含保存购物详情到订单详情表.
整体来说订单这一环节还是挺简单的, 这里需注意的是订单表和订单详情表的设计. 但是上面的code做的也有很多不完善的地方, 比如说减库存和 清除购物车的选项. 当然这只是一个练习的项目, 整个项目做到这里也就 完结了, 后期我会将代码以及所有资料都上传到 网上供大家使用, 当然资料里还包含12天的讲解视频. 希望大家能在闲暇之余 一起来学习下.
内容大概就是这么多, 感谢阅读本系列和回复的园友们.