首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >商城业务:购物车

商城业务:购物车

作者头像
一个风轻云淡
发布2023-10-15 09:46:11
发布2023-10-15 09:46:11
5500
举报
文章被收录于专栏:java学习javajava学习java

人生在世如身处荆棘之中,心不动,人不妄动,不动则不伤;如心动则人妄动,伤其身痛其骨,于是体会到世间诸般痛苦。

1、购物车需求

1)、需求描述:

- 用户可以在登录状态下将商品添加到购物车【用户购物车/在线购物车】

- 放入数据库 - mongodb - 放入 redis(采用) 登录以后,会将临时购物车的数据全部合并过来,并清空临时购物车;

- 用户可以在未登录状态下将商品添加到购物车【游客购物车/离线购物车/临时购物车】

- 放入 localstorage(客户端存储,后台不存) - cookie - WebSQL - 放入 redis(采用) 浏览器即使关闭,下次进入,临时购物车数据都在

- 用户可以使用购物车一起结算下单 - 给购物车添加商品 - 用户可以查询自己的购物车 - 用户可以在购物车中修改购买商品的数量。 - 用户可以在购物车中删除商品。 - 选中不选中商品 - 在购物车中展示商品优惠信息 - 提示购物车商品价格变化

2)、数据结构 

因此每一个购物项信息,都是一个对象,基本字段包括: 

另外,购物车中不止一条数据,因此最终会是对象的数组。即: 

Redis 有 5 种不同数据结构,这里选择哪一种比较合适呢?

- 首先不同用户应该有独立的购物车,因此购物车应该以用户的作为 key 来存储,Value 是 用户的所有购物车信息。这样看来基本的`k-v`结构就可以了。

- 但是,我们对购物车中的商品进行增、删、改操作,基本都需要根据商品 id 进行判断, 为了方便后期处理,我们的购物车也应该是`k-v`结构,key 是商品 id,value 才是这个商品的 购物车信息。

综上所述,我们的购物车结构是一个双层 Map:Ma<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,而后返回。

2、临时购物车 

代码语言:javascript
复制
    /**
     * 获取到我们要操作的购物车
     * @return
     */
    private BoundHashOperations<String, Object, Object> getCartOps() {
        UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
        //1.
        String cartKey = "";
        if (userInfoTo.getUserId() != null) {
            cartKey = CART_PREFIX + userInfoTo.getUserId();
        } else {
            cartKey = CART_PREFIX + userInfoTo.getUserKey();
        }
        BoundHashOperations<String, Object, Object> operations = redisTemplate.boundHashOps(cartKey);
        return operations;
    }

3、登录购物车 

代码语言:javascript
复制
 @Override
    public CartItem addToCart(Long skuId, Integer num) {

        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        String res = (String) cartOps.get(skuId.toString());
        if(StringUtils.isEmpty(res)){
            CartItem cartItem = new CartItem();
            // 1.运程查询当前要添加的商品信息
            CompletableFuture<Void> getSkuInfoTask = CompletableFuture.runAsync(() -> {
                //2.商品添加到购物车(新商品)
                R skuInfo = productFeignService.getSkuInfo(skuId);
                SkuInfoVo data = skuInfo.getData("skuInfo", new TypeReference<SkuInfoVo>() {
                });

                cartItem.setCheck(true);
                cartItem.setCount(1);
                cartItem.setImage(data.getSkuDefaultImg());
                cartItem.setTitle(data.getSkuTitle());
                cartItem.setPrice(data.getPrice());
                cartItem.setSkuId(data.getSkuId());
            },executor);

            CompletableFuture<Void> getSkuSaleAttr = CompletableFuture.runAsync(() -> {
                //运程查询sku的组合信息
                List<String> values = productFeignService.getSkuSaleAttrValues(skuId);
                cartItem.setSkuAttr(values);
            }, executor);

            CompletableFuture<Void> allOf = CompletableFuture.allOf(getSkuInfoTask, getSkuSaleAttr);
            try {
                allOf.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            String s = JSON.toJSONString(cartItem);

            cartOps.put(skuId.toString(),s);
            return cartItem;
        }
        else
        {
            //购物车有这个商品
            CartItem cartItem = JSON.parseObject(res, CartItem.class);
            cartItem.setCount(cartItem.getCount()+num);
            cartOps.put(skuId.toString(),JSON.toJSONString(cartItem));

            return cartItem;

        }


    }

    @Override
    public CartItem getCartItem(Long skuId) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        String str = (String) cartOps.get(skuId.toString());
        CartItem cartItem = JSON.parseObject(str, CartItem.class);
        return  cartItem;
    }
代码语言:javascript
复制
   @Override
    public Cart getCart() {
        UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
        Cart cart = new Cart();
        if(userInfoTo.getUserId()!=null){
            //登录
            String cartKey = CART_PREFIX+userInfoTo.getUserId();
            //如果临时购物车的数据还没有合并【合并购物车】
           String tempCartKey= CART_PREFIX + userInfoTo.getUserKey();
            List<CartItem> tempCartItems = getCartItems(tempCartKey);
            if(tempCartItems!=null){
                //合并
                for (CartItem item : tempCartItems) {
                    addToCart(item.getSkuId(),item.getCount());
                }
            }
            //3.获取登录后的数据
            List<CartItem> cartItems = getCartItems(cartKey);
            cart.setItems(cartItems);
            //清除临时购物车数据
            clearCart(tempCartKey);

        }else {
            //没登陆
            String cartKey = CART_PREFIX+userInfoTo.getUserKey();
           //获取临时购物车的所有购物项
            List<CartItem> cartItems = getCartItems(cartKey);
            cart.setItems(cartItems);


        }
        return cart;
    }
代码语言:javascript
复制
    @Override
    public void checkItem(Long skuId, Integer check) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();

        CartItem cartItem = getCartItem(skuId);
        cartItem.setCheck(check==1?true:false);
        String s = JSON.toJSONString(cartItem);
        cartOps.put(skuId.toString(),s);

    }

    @Override
    public void changeItemCount(Long skuId, Integer num) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        CartItem cartItem = getCartItem(skuId);
        cartItem.setCount(num);
        String s = JSON.toJSONString(cartItem);
        cartOps.put(skuId.toString(),s);

    }

    @Override
    public void deleteItem(Long skuId) {
        BoundHashOperations<String, Object, Object> cartOps = getCartOps();
        cartOps.delete(skuId.toString());
    }

人生在世如身处荆棘之中,心不动,人不妄动,不动则不伤;如心动则人妄动,伤其身痛其骨,于是体会到世间诸般痛苦。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、购物车需求
    • 1)、需求描述:
    • 2)、数据结构 
    • 3)、流程 
    • 2、临时购物车 
    • 3、登录购物车 
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档