美多商城项目之购物车模块

美多商城的购物车逻辑,主要分为登录用户的购物车和未登录用户的购物车。

登录用户的购物车:我们通过Redis数据库进行存储,使用HASH表存储购物车商品信息,使用Set存储购物车中被勾选的商品。

未登录用户的购物车:我们通过COOKIE进行存储。

1. 购物车的存储方案如下:

1.1 已登录的用户的购物车:

存储数据:商品(sku_id)、数量(count)、勾选状态(selected)
        存储位置:redis
        存储类型:
            hash存储商品(sku_id)、数量(count)
            set存储勾选状态(selected):那个商品被勾选,就将那个商品的sku_id存储到set中即可
        存储逻辑:
            1.判断要添加的商品在购物车中是否存在
            2.如果不存在,直接保存记录
            3.如果存在,直接累加数量
        存储效果:
            carts_user_id: {sku_id1: count1, sku_id2: count2}
            selected_user_id: [sku_id1]

1.2 未登录用户的购物车:

存储数据:商品(sku_id)、数量(count)、勾选状态(selected)
        存储位置:用户浏览器的cookie
        存储类型:
            购物车密文字符串
        存储逻辑:
            1.判断要添加的商品在购物车中是否存在
            2.如果不存在,直接保存记录
            3.如果存在,直接累加数量
        存储效果:
            JASJ8723447ASDNAKCSCSKC187Y28KAJCN7645397JFJFHF64759JHSFSKFJHB==

1.3 如何操作未登录用户的购物车呢?

我们是用COOKIE来保存未登录用户的购物车信息,那么我们就需要构造一个字符串数据。

这个字符串数据的结构应该是一个字典。

将购物车密文字符串转购物车字典:
    # 先读取cookie中的购物车密文字符串
    cart_str = request.COOKIES.get('carts')
    # 然后将购物车密文字符串转成bytes类型字符串
    cart_str_bytes = cart_str.encode()
    # 再使用base64将bytes类型字符串解码为bytes类型字典
    cart_dict_bytes = base64.b64decode(cart_str_bytes)
    # 最后使用pickle将bytes类型字典反序列化成python字典
    cart_dict = pickle.loads(cart_dict_bytes)

将购物车字典转购物车密文字符串
    # 先使用pickle将购物车字典序列化成bytes类型字典
    cart_dict_bytes = pickle.dumps(cart_dict)
    # 然后使用base64将bytes类型字典编码为bytes类型字符串
    cart_str_bytes = base64.b64encode(cart_dict_bytes)
    # 再将bytes类型字符串转成购物车字符串
    cookie_cart_str = cart_str_bytes.decode()
    # 最后将购物车字符串写入到cookie中
    response.set_cookie('carts', cookie_cart_str)

2. 购物车管理:

2.1 新增购物车      

 2.1.1 实现逻辑
            1.判断要添加的商品在购物车中是否存在
            2.如果不存在,直接保存记录
            3.如果存在,直接累加数量
        2.1.2 用户已登录
      pl.hincrby('carts_%s' % user.id, sku_id, count)
      if selected:
          pl.sadd('selected_%s' % user.id, sku_id)
        2.1.3 用户未登录
            if sku_id in cart_dict:
          origin_count = cart_dict[sku_id]['count']
        count += origin_count
      cart_dict[sku_id] = {
          "count": count,
        "selected": selected
      }    

2.2 查询购物车        

  2.2.1 用户已登录
            核心思想:查询该用户在redis中存储的所有的购物车信息
            实现方式:
                redis_cart = redis_conn.hgetall('carts_%s' % user.id)
        redis_selected = redis_conn.smembers('selected_%s' % user.id)
        2.2.2 用户未登录
            核心思想:查询该用户在cookie中存储的所有的购物车信息
            实现方式:就是从cookie中读取购物车字典即可

2.3 修改购物车        

  2.3.1 用户已登录
            核心思想:直接使用新的购物车数据覆盖旧的购物车数据
            实现方式:
                pl.hset('carts_%s' % user.id, sku_id, count)
        if selected:
            pl.sadd('selected_%s' % user.id, sku_id)
        else:
            pl.srem('selected_%s' % user.id, sku_id)
        2.3.2 用户未登录
            核心思想:直接使用新的购物车数据覆盖旧的购物车数据
            实现方式:
                cart_dict[sku_id] = {
            "count": count,
          "selected": selected        }

2.4 删除购物车        

  2.4.1 用户已登录
            核心思想:直接删除指定商品即可
            实现方式:
                pl.hdel('carts_%s' % user.id, sku_id)
        pl.srem('selected_%s' % user.id, sku_id)
        2.4.2 用户未登录
            核心思想:直接删除指定商品即可
            实现方式:
                if sku_id in cart_dict:

     del cart_dict[sku_id]

2.5全选购物车

  2.5.1 用户已登录
            核心思想:如果用户选择全选,那么将购物车中所有商品的sku_id添加到set中,反之,从set中移除sku_id
            实现方式:
                redis_cart = redis_conn.hgetall('carts_%s' % user.id)
        cart_sku_ids = redis_cart.keys()
        if selected:
            redis_conn.sadd('selected_%s' % user.id, *cart_sku_ids)
        else:
            redis_conn.srem('selected_%s' % user.id, *cart_sku_ids)
        2.5.2 用户未登录
            核心思想:如果用户选择全选,那么将购物车字典中所有的selected设置为True,反之,设置为False
            实现方式:
                for sku_id in cart_dict:
            cart_dict[sku_id]['selected'] = selected

3. 购物车合并逻辑:

购物车合并逻辑有三种,一种是以COOKIE为主,一种是以Redis为主,一种是将COOKIE和Redis中的数据做累加操作。

 3.1 合并时机:账号登录和QQ登录时都要合并购物车
    3.2 合并方向:cookie购物车数据合并到Redis购物车数据中
    3.3 合并数据:购物车商品数据(sku_id、数量)和勾选状态
    3.4 合并逻辑:
    3.4.1 以cookie中购物车数据为主
    3.4.2 判断cookie中的购物车数据在Redis数据库中是否存在
    3.4.3 如果已存在,将cookie购物车数据覆盖Redis购物车数据
    3.4.4 如果不存在,将cookie购物车数据新增到Redis
    3.4.5 最终商品的勾选状态以cookie购物车勾选状态为主
    3.4.6 Redis数据库中独有的购物车数据自己保留

该花的钱要花,该吃的饭要吃。
原文地址:https://www.cnblogs.com/chao666/p/12262609.html