您的位置:首页 > 运维架构 > 网站架构

电商网站购物车功能分析与实现

2018-12-25 22:15 246 查看

最近刚做了一个分布式的电商项目,关于购物车模块,借鉴了某东的购物车系统。

结合国内两大电商巨头某宝和某东,发现某宝中要向使用购物车就必要先登录,而某东可以不需要登录就添加商品到购物车中。

由于项目借鉴了某东的方式,所以在未登录的时候也是可以使用购物车的。

步骤:
一、用户在对商品进行添加到购物车操作时,通过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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: