上一篇博文我們已經介紹了購物車的原理及實現, 那么購物車再往后就是提交訂單了, 訂單的實現方式是怎么樣的呢? 那么下面就讓我們來一起學習下.
提交訂單有幾個關鍵點:
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到訂單表, 這里面也包含保存購物詳情到訂單詳情表.
內容大概就是這么多, 感謝閱讀本系列和回復的園友們.