電商網站購物車功能分析與實現

最近剛做了一個分佈式的電商項目,關於購物車模塊,借鑑了某東的購物車系統。

結合國內兩大電商巨頭某寶和某東,發現某寶中要向使用購物車就必要先登錄,而某東可以不需要登錄就添加商品到購物車中。

由於項目借鑑了某東的方式,所以在未登錄的時候也是可以使用購物車的。

步驟:
一、用戶在對商品進行添加到購物車操作時,通過cookie中的token和redis中的token判斷用戶是否登錄,如果未登錄狀態時,從cookie中獲取到購物車。如果不存在就新建一個。
如果用戶登錄了,就從redis中獲取到購物車,key是用戶id,以String方式存儲的。

二、在用戶進行登錄操作的時候,通過MQ發送消息到購物車系統,將用戶cookie中的購物車與用戶id發送過去。購物車系統的消息監聽器監聽到消息數據,將cookie中的購物車獲取到並與redis中的購物車進行合併。
(當然我這邊是把cookie中的購物車也是存在了redis作爲臨時購物車,具體操作是在新建購物車的時候生成一個不重複的隨機字符串,將字符串作爲value存入到cookie,同時將字符串作爲key,臨時購物車作爲value存入到redis中。這樣就可以通過獲取到cookie中的value向redis中查詢到臨時購物車進行相關操作了)

代碼如下:
購物車合併

public class CartLoginListener implements MessageListener{
	@Autowired
	private JedisClient jedisClient;
	
	@Value("${REDIS_CART}")
	private String REDIS_CART;
	
	public void onMessage(Message message) {
		TextMessage textMessage=(TextMessage)message;
		try {
			String text = textMessage.getText();
			String[] strings = text.split(",");
			//獲取到用戶id
			String uid=strings[0];
			//獲取到cookie中保存的臨時購物車的value
			String value=strings[1];
			//獲取到專屬購物車
			String redisCart = jedisClient.get(REDIS_CART+uid);
			List<CartItem> cartList=null;
			if(StringUtils.isBlank(redisCart)){
				//用戶購物車在redis中不存在,說明購物車時間過期了,或者是個新用戶
				//創建一個購物車
				cartList=new ArrayList<CartItem>();
			}else{
				cartList=JsonUtils.jsonToList(redisCart, CartItem.class);
			}
			//獲取臨時購物車
			if(StringUtils.isNotBlank(value)&&!value.equals("1")){
				//有商品被添加到購物車中,那麼將cookie中的購物車信息添加到redis的購物車中
				//從redis中獲取到臨時購物車
				String string = jedisClient.get(value);
				List<CartItem> carts = JsonUtils.jsonToList(string, CartItem.class);
				//循環遍歷cookie中的購物車商品
				if(cartList==null||cartList.size()==0){
					//說明是個空車,將每個cookie中的商品直接添加到redis中的購物車即可
					for(int j=0;j<carts.size();j++){
						cartList.add(carts.get(j));
					}
				}else{
					//redis中的購物車不是空車
					for(int j=0;j<carts.size();j++){
						//默認redis中沒有cookie中的商品
						boolean flag=false;
						//遍歷cookie中的購物車
						for(int i=0;i<cartList.size();i++){
							//遍歷redis中的購物車,看看是否有同一件商品
							if(carts.get(j).getId().equals(cartList.get(i).getId())){
								//有同一件商品,更新數量即可
								cartList.get(i).setNum(cartList.get(i).getNum()+carts.get(j).getNum());
								flag=true;
								break;
							}
						}
						if(!flag){
							//如果遍歷完之後redis中沒有cookie中同一件商品
							//將該商品添加到redis中
							cartList.add(carts.get(j));
						}
					}
				}
				//將合併後的購物車存放到redis
				jedisClient.set(REDIS_CART+uid, JsonUtils.objectToJson(cartList));
				//設置購物車存在redis最大時間爲七天
				jedisClient.expire(REDIS_CART+uid, 86400);
				//同時刪除redis中的臨時購物車
				jedisClient.expire(value, 0);
			}
			
			
	}

}

獲取到購物車

//獲取到購物車
	private CartMaster getCartList(HttpServletRequest request,HttpServletResponse response){
		CartMaster master=new CartMaster();
		//檢查用戶是否登錄
		//獲取到cookie中的token
		String token = CookieUtils.getCookieValue(request, SESSION_TOKEN);
		if(StringUtils.isNotBlank(token)){
			//說明cookie中有token,即用戶登錄過
			JDResult result = userService.getUserByToken(token);
			if(result.getStatus()==200){
				//說明用戶登錄正常,未超時,獲取到當前登錄對象
				TbUser user=(TbUser)result.getData();
				//從redis中取出購物車
				String redisCart = jedisClient.get(REDIS_CART+user.getId());
				if(StringUtils.isBlank(redisCart)){
					List<CartItem> list=new ArrayList<CartItem>();
					master.setCartList(list);
				}else{
					master.setCartList(JsonUtils.jsonToList(redisCart, CartItem.class));
				}
				master.setUserId(user.getId());
				master.setCartFrom(1);
				return master;
			}
		}
		//用戶未登錄,或者登錄超時,從cookie中獲取臨時購物車的號碼
		String cookieValue = CookieUtils.getCookieValue(request, SHOPPONG_CART,CHARSET);
		if(StringUtils.isNotBlank(cookieValue)){
			//說明cookie中有了臨時購物車號碼,根據號碼從redis中獲取到該用戶的臨時購物車
			String temporaryCart = jedisClient.get(cookieValue);
			if(StringUtils.isNotBlank(temporaryCart)){
				List<CartItem> list = JsonUtils.jsonToList(temporaryCart, CartItem.class);
				master.setCartFrom(2);
				master.setCartList(list);
				return master;
			}
		}
		//說明cookie中沒有購物車的號碼,或者cookie中有,reids沒有,創建購物車
		String cartId=UUID.randomUUID().toString();
		//創建一個購物車
		List<CartItem> list=new ArrayList<CartItem>();
		//將購物車存入redis,設置過期時間七天
		jedisClient.set(cartId, JsonUtils.objectToJson(list));
		jedisClient.expire(cartId, COOKIE_TIME);
		//將id作爲value存入到cookie中
		CookieUtils.setCookie(request, response, SHOPPONG_CART, cartId, COOKIE_TIME);
		master.setCartFrom(2);
		master.setCartList(list);
		return master;
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章