学习笔记(19)购物车

学习笔记(19)购物车

购物车有两种情况:

​ 在线购物车;

​ 离线购物车;

离线购物车:

只要每次看购物车。都有一个user-key=uuid;如果这个user-key丢了,购物车就没了。

如果我们要看购物车肯定会带上这个user-key的cookie;如果有就用自带的,没有就新建一个以后用这个。

登录以后离线的和在线的合并了,并且清空了离线购物车里面的数据。

京东怎么做购物车?

​ 购物车有一个cookie对应的key关联,即使没有登录也有,登录以后进行购物车合并,合并完成后删除购物车数据;该系统也设计离线在线购物车。

离线购物车:永远用 cart-key=uuid;购物车数据都在redis中提升系统的性能。cart:temp: uuid;

在线购物车:cart:1={};放在redis中;cart:user:1;

在这里插入图片描述

在这里插入图片描述

抽取购物项:

private BigDecimal totalPrice;//当前购物项总价
//算价格用BigDecimal ,否则带小数的运算有问题

用hash存储,key为skuid,value为json字符串。

想改1号商品数量,拿Cart:user:1 查到整个购物车,然后get出1号商品,得到json字符串,反序列化成CartItem,把CartItem中的数量改成5,然后json重新覆盖。

用k-v最大的另一个好处,可以多加一个字段checked ,value是数组,这样不用遍历购物车就可获取选中商品。

最终购物车的结构:

在这里插入图片描述

reddison 的分布式集合:

做分布式一定要序列化接口

测试Reddsion:

@Test
public void userRedissonMap(){
    RMap<String, String> cart = redissonClient.getMap("cart");
    CartItem item = new CartItem();
    item.setPrice(new BigDecimal("12.98"));
    item.setSkuId(1L);
    item.setCount(1);
    String s = JSON.toJSONString(item);
    cart.put("2",s);
}

测试后redis如下:

在这里插入图片描述

/**
 * 根据accessToken查询用户信息
 */
public Member getMemberByAccessToken(String accessToken){
    String userJson = redisTemplate.opsForValue().get(SysCacheConstant.LOGIN_MEMBER + accessToken);
    return JSON.parseObject(userJson, Member.class);
}
//系统中存用户的json
//经常要用,封装成组件
@Component
public class MemberComponent {

    @Autowired
    StringRedisTemplate redisTemplate;


    public UserCartKey getCartKey(String accessToken, String cartKey){
        UserCartKey userCartKey = new UserCartKey();
        Member member = null;
        if(!StringUtils.isEmpty(accessToken)){
            member = getMemberByAccessToken(accessToken);
        }

        if(member!=null){
            //获取到了在线用户;用户登录用这个
            userCartKey.setLogin(true);
            userCartKey.setUserId(member.getId());
            userCartKey.setFinalCartKey(CartConstant.USER_CART_KEY_PREFIX+member.getId());
            return userCartKey;
        }else if(!StringUtils.isEmpty(cartKey)){
            //用户有临时的用这个
            userCartKey.setLogin(false);
            userCartKey.setFinalCartKey(CartConstant.TEMP_CART_KEY_PREFIX+cartKey);
            return userCartKey;
        }else {
            //用户既没有登录也没有零时购物车
            String replace = UUID.randomUUID().toString().replace("-", "");
            userCartKey.setLogin(false);
            userCartKey.setFinalCartKey(CartConstant.TEMP_CART_KEY_PREFIX+replace);
            userCartKey.setTempCartKey(replace);

            return userCartKey;
        }

    }
    /**
     * 根据accessToken查询用户信息
     */
    public Member getMemberByAccessToken(String accessToken){
        String userJson = redisTemplate.opsForValue().get(SysCacheConstant.LOGIN_MEMBER + accessToken);
        return JSON.parseObject(userJson, Member.class);
    }
}

几种购物车:

String oldCartKey = CartConstant.TEMP_CART_KEY_PREFIX+cartKey;
String userCartKey = CartConstant.USER_CART_KEY_PREFIX+id.toString();
if(member!=null){
    //获取到了在线用户;用户登录用这个
    userCartKey.setLogin(true);
    userCartKey.setUserId(member.getId());
    userCartKey.setFinalCartKey(CartConstant.USER_CART_KEY_PREFIX+member.getId());
    return userCartKey;
}else if(!StringUtils.isEmpty(cartKey)){
    //用户有临时的用这个
    userCartKey.setLogin(false);
    userCartKey.setFinalCartKey(CartConstant.TEMP_CART_KEY_PREFIX+cartKey);
    return userCartKey;
}else {
    //用户既没有登录也没有零时购物车
    String replace = UUID.randomUUID().toString().replace("-", "");
    userCartKey.setLogin(false);
    userCartKey.setFinalCartKey(CartConstant.TEMP_CART_KEY_PREFIX+replace);
    userCartKey.setTempCartKey(replace);

    return userCartKey;
}

购物车postman测试:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

直接写类似于双写,写map其实是在写缓存。

回写,把map写完后,开个异步任务,写缓存。

//自动续期 ,防止购物车撑爆
//redisTemplate.expire(finalCartKey,30L, TimeUnit.DAYS);

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

HashSet改成LinkedHashSet,也是有序的了,添加物品时有序,如上图的1,2,3,4各行按操作顺序排列。

//删除购物车先维护购物车状态,再删json。若反,删除了json也没有了,再改json数据有问题
@Override
public CartResponse delCartItem(Long skuId, String cartKey, String accessToken) {

    UserCartKey userCartKey = memberComponent.getCartKey(accessToken, cartKey);


    String finalCartKey = userCartKey.getFinalCartKey();
    //维护购物项的checked状态
    checkItem(Arrays.asList(skuId),false,finalCartKey);

    //获取购物车删除购物项
    RMap<String, String> map = redissonClient.getMap(finalCartKey);
    map.remove(skuId.toString());



    //整个购物车再返回出去
    CartResponse cartResponse = listCart(cartKey, accessToken);
    return cartResponse;
}

1)、购物车数据保存在redis中,使用分布式集合;【redisson.getMap】

2)、用户对于购物车的所有操作,都需要传入cart-key,如果用户登录了,还需要传入token

购物车需要提供的所有方法;

1)、添加到购物车

2)、修改购物项

3)、删除购物项

4)、选中/选不中购物项

5)、返回整个购物车

6)、点击去结算-获取购物车中需要结算的数据

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值