1. 程式人生 > 其它 >akash測試網挑戰5疑難點-非保姆級教程

akash測試網挑戰5疑難點-非保姆級教程

購物車

一、購物車需求

1、需求描述

  • 使用者可以在登入狀態下將商品新增到購物車【使用者購物車/線上購物車】
    • 放入資料庫
    • mongodb
    • 放入 redis(採用
      登入以後, 會將臨時購物車的資料全部合併過來, 並清空臨時購物車
  • 使用者可以在未登入狀態下將商品新增到購物車【遊客購物車/離線購物車/臨時購物車】
    • 放入 localstorage(客戶端儲存, 後臺不存)
    • cookie
    • WebSQL
    • 放入 redis(採用)
      瀏覽器即使關閉, 下次進入, 臨時購物車資料都在
  • 使用者可以使用購物車一起結算下單
  • 給購物車新增商品
  • 使用者可以查詢自己的購物車
  • 使用者可以在購物車中修改購買商品的數量。
  • 使用者可以在購物車中刪除商品。
  • 選中不選中商品
  • 在購物車中展示商品優惠資訊
  • 提示購物車商品價格變化

2、資料結構

因此每一個購物項資訊, 都是一個物件, 基本欄位包括:

{
    skuId: 2131241,
    check: true,
    title: "Apple iphone.....",
    defaultImage: "...",
    price: 4999,
    count: 1,
    totalPrice: 4999,
    skuSaleVO: {...}
}

另外, 購物車中不止一條資料, 因此最終會是物件的陣列。 即:

[
    {...},{...},{...}
]
  • 資料儲存方式
    購物車是一個讀多寫多的場景,因此放入資料庫並不合適,但購物車又是需要持久化,因此這裡我們選用redis儲存購物車資料。

  • 資料儲存結構
    一個購物車是由多個購物項組成的,但是我們用List進行儲存並不合適,因為使用List查詢某個購物項時需要挨個遍歷每個購物項,會造成大量時間損耗,為保證查詢速度,我們使用hash進行儲存

  • 首先不同使用者應該有獨立的購物車, 因此購物車應該以使用者的作為 key 來儲存, Value 是使用者的所有購物車資訊。 這樣看來基本的k-v結構就可以了。

  • 但是, 我們對購物車中的商品進行增、 刪、 改操作, 基本都需要根據商品 id 進行判斷,為了方便後期處理, 我們的購物車也應該是k-v結構, key 是商品 id, value 才是這個商品的購物車資訊。

    綜上所述, 我們的購物車結構是一個雙層 Map: Map<String,Map<String,String>>

  • 第一層 Map, Key 是使用者 id

  • 第二層 Map, Key 是購物車中商品 id, 值是購物項資料

3、流程

參照京東

user-key 是隨機生成的 id, 不管有沒有登入都會有這個 cookie 資訊。
兩個功能: 新增商品到購物車、 查詢購物車。
新增商品: 判斷是否登入

  • 是: 則新增商品到後臺 Redis 中, 把 user 的唯一識別符號作為 key。
  • 否: 則新增商品到後臺 redis 中, 使用隨機生成的 user-key 作為 key。

查詢購物車列表: 判斷是否登入

  • 否: 直接根據 user-key 查詢 redis 中資料並展示
  • 是: 已登入, 則需要先根據 user-key 查詢 redis 是否有資料。
    • 有: 需要提交到後臺新增到 redis, 合併資料, 而後查詢。
    • 否: 直接去後臺查詢 redis, 而後返回

二、臨時購物車

/**
* 獲取到我們要操作的購物車
* @return
*/
private BoundHashOperations<String, Object, Object> getCartOps() {
UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
String cartKey = "";
if (userInfoTo.getUserId() != null) {
//gulimall:cart:1
cartKey = CART_PREFIX + userInfoTo.getUserId();
} else {
cartKey = CART_PREFIX + userInfoTo.getUserKey();
} B
oundHashOperations<String, Object, Object> operations =
redisTemplate.boundHashOps(cartKey);
return operations;
}

三、登入購物車

@Override
public Cart getCart() throws ExecutionException, InterruptedException {
Cart cart = new Cart();
UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
if(userInfoTo.getUserId()!=null){
//1、 登入
String cartKey =CART_PREFIX+ userInfoTo.getUserId();
//2、 如果臨時購物車的資料還沒有進行合併【合併購物車】
String tempCartKey = CART_PREFIX + userInfoTo.getUserKey();
List<CartItem> tempCartItems = getCartItems(tempCartKey);
if(tempCartItems!=null){
//臨時購物車有資料, 需要合併
for (CartItem item : tempCartItems) {
addToCart(item.getSkuId(),item.getCount());
} //
清除臨時購物車的資料
clearCart(tempCartKey);
} //
3、 獲取登入後的購物車的資料【包含合併過來的臨時購物車的資料, 和登入後的購
物車的資料】
List<CartItem> cartItems = getCartItems(cartKey);
cart.setItems(cartItems);
}else{
//2、 沒登入
String cartKey =CART_PREFIX+ userInfoTo.getUserKey();
//獲取臨時購物車的所有購物項
List<CartItem> cartItems = getCartItems(cartKey);
cart.setItems(cartItems);
} r
eturn cart;
}