完整电商项目--(七)购物车模块(1)

购物车存储方案

  • 分两种情况

用户登录

  • 描述一条完整的购物车记录需要
    • 用户、商品、数量、勾选状态
    • 存储数据:user_id、sku_id、count、selected
    • 存储位置:
      • 选择redis数据库
      • 数据存储类型
        • (1)选择hash类型,保存用户,商品,数量等信息。
          在这里插入图片描述
          存储的数据应为:carts_user_id: {sku_id1: count, sku_id3: count, sku_id5: count, …}

        • (2)勾选状态:采用set类型存储

        • 只将已勾选商品的sku_id存储到set中,比如,1号和3号商品是被勾选的

        • 形式selected_user_id: [sku_id1, sku_id3, …]

1111111111111111111111111111111111

  • 存储逻辑说明
    • 当要添加到购物车的商品已存在时,对商品数量进行累加计算
    • 当要添加到购物车的商品不存在时,向hash中新增field和value即可

用户未登录

存储数据

  • 和上面是一样的user_id、sku_id、count、selected

存储位置

  • 由于用户未登录,服务端无法拿到用户的ID
  • 我们可以将未登录用户的购物车数据缓存到用户浏览器的cookie中,每个用户自己浏览器的cookie中存储属于自己的购物车数据

存储类型

  • (1)浏览器的cookie中存储的数据类型是字符串
  • (2)JSON字符串可以描述复杂结构的字符串数据,可以保证一条购物车记录不用分开存储
  • 数据结构展示
{
    "sku_id1":{
        "count":"1",
        "selected":"True"
    },
    "sku_id3":{
        "count":"3",
        "selected":"True"
    },
    "sku_id5":{
        "count":"3",
        "selected":"False"
    }
}

存储逻辑说明

  • 当要添加到购物车的商品已存在时,对商品数量进行累加计算。
  • 当要添加到购物车的商品不存在时,向JSON中新增field和value即可

数据安全处理:

  • (1)浏览器cookie中存储的是字符串明文数据
    • 我们需要对数据进行加密
  • (2) 解决方案:pickle模块 和 base64模块

pickle模块介绍

  • pickle模块是Python的标准模块,提供了对Python数据的序列化操作,可以将数据转换为bytes类型,且序列化速度快
  • 使用方法:
    • pickle.dumps()将Python数据序列化为bytes类型数据
    • pickle.loads()将bytes类型数据反序列化为python数据。

base64模块介绍

  • 注意!!! : pickle模块序列化转换后的数据是bytes类型,浏览器cookie无法存储
  • 介绍:
    • base64模块是Python的标准模块,可以对bytes类型数据进行编码,并得到bytes类型的密文数据
    • 使用:
      • base64.b64encode()将bytes类型数据进行base64编码,返回编码后的bytes类型数据
      • base64.b64deocde()将base64编码后的bytes类型数据进行解码,返回解码后的bytes类型数据。

下面是具体的代码实现

增加购物车

redis中

在这里插入图片描述

redis_conn = get_redis_connection('carts')
            pl = redis_conn.pipeline()
            # 新增购物车数据
            pl.hincrby('carts_%s' % user.id, sku_id, count)
            # 新增选中的状态
            if selected:
                pl.sadd('selected_%s' % user.id, sku_id)
            # 执行管道
            pl.execute()

cookie中

# 用户未登录,操作cookie购物车
            cart_str = request.COOKIES.get('carts')
            # 如果用户操作过cookie购物车
            if cart_str:
                # 将cart_str转成bytes,再将bytes转成base64的bytes,最后将bytes转字典
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:  # 用户从没有操作过cookie购物车
                cart_dict = {}

            # 判断要加入购物车的商品是否已经在购物车中,如有相同商品,累加求和,反之,直接赋值
            if sku_id in cart_dict:
                # 累加求和
                origin_count = cart_dict[sku_id]['count']
                count += origin_count
            cart_dict[sku_id] = {
                'count': count,
                'selected': selected
            }
            # 将字典转成bytes,再将bytes转成base64的bytes,最后将bytes转字符串
            cookie_cart_str = base64.b64encode(pickle.dumps(cart_dict)).decode()

            # 创建响应对象
            response = http.JsonResponse({'code': RETCODE.OK, 'errmsg': '添加购物车成功'})
            # 响应结果并将购物车数据写入到cookie
            response.set_cookie('carts', cookie_cart_str, max_age=constants.CARTS_COOKIE_EXPIRES)

删除购物车

redis中

 redis_conn = get_redis_connection('carts')
            pl = redis_conn.pipeline()
            # 删除键,就等价于删除了整条记录
            pl.hdel('carts_%s' % user.id, sku_id)
            pl.srem('selected_%s' % user.id, sku_id)
            pl.execute()

删除cookie购物车

cart_str = request.COOKIES.get('carts')
            if cart_str:
                # 将cart_str转成bytes,再将bytes转成base64的bytes,最后将bytes转字典
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:
                cart_dict = {}

            # 创建响应对象
            response = http.JsonResponse({'code': RETCODE.OK, 'errmsg': '删除购物车成功'})
            if sku_id in cart_dict:
                del cart_dict[sku_id]
                # 将字典转成bytes,再将bytes转成base64的bytes,最后将bytes转字符串
                cookie_cart_str = base64.b64encode(pickle.dumps(cart_dict)).decode()
                # 响应结果并将购物车数据写入到cookie
                response.set_cookie('carts', cookie_cart_str, max_age=constants.CARTS_COOKIE_EXPIRES)
            return response

其余的修改,展示购物车都是类似的,这里就不说了

全选购物车

redis中:

# 用户已登录,操作redis购物车
            redis_conn = get_redis_connection('carts')
            cart = redis_conn.hgetall('carts_%s' % user.id)
            sku_id_list = cart.keys()
            if selected:
                # 全选
                redis_conn.sadd('selected_%s' % user.id, *sku_id_list)
            else:
                # 取消全选
                redis_conn.srem('selected_%s' % user.id, *sku_id_list)
            return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '全选购物车成功'})

cookie中

# 用户已登录,操作cookie购物车
            cart = request.COOKIES.get('carts')
            response = http.JsonResponse({'code': RETCODE.OK, 'errmsg': '全选购物车成功'})
            if cart is not None:
                cart = pickle.loads(base64.b64decode(cart.encode()))
                for sku_id in cart:
                    cart[sku_id]['selected'] = selected
                cookie_cart = base64.b64encode(pickle.dumps(cart)).decode()
                response.set_cookie('carts', cookie_cart, max_age=constants.CARTS_COOKIE_EXPIRES)

合并购物车

# 获取cookie中的购物车数据
    cookie_cart_str = request.COOKIES.get('carts')
    # cookie中没有数据就响应结果
    if not cookie_cart_str:
        return response
    cookie_cart_dict = pickle.loads(base64.b64decode(cookie_cart_str.encode()))

    new_cart_dict = {}
    new_cart_selected_add = []
    new_cart_selected_remove = []
    # 同步cookie中购物车数据
    for sku_id, cookie_dict in cookie_cart_dict.items():
        new_cart_dict[sku_id] = cookie_dict['count']

        if cookie_dict['selected']:
            new_cart_selected_add.append(sku_id)
        else:
            new_cart_selected_remove.append(sku_id)

    # 将new_cart_dict写入到Redis数据库
    redis_conn = get_redis_connection('carts')
    pl = redis_conn.pipeline()
    pl.hmset('carts_%s' % user.id, new_cart_dict)
    # 将勾选状态同步到Redis数据库
    if new_cart_selected_add:
        pl.sadd('selected_%s' % user.id, *new_cart_selected_add)
    if new_cart_selected_remove:
        pl.srem('selected_%s' % user.id, *new_cart_selected_remove)
    pl.execute()

    # 清除cookie
    response.delete_cookie('carts')

就到这里吧,全是增删改查,操作cookie和redis,其实很繁琐,但是不是很难,大家仔细看懂逻辑实现就可以。

  • 9
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当开发Uniapp项目中的购物车模块时,以下是一些简要的说明: 1. 功能描述: - 购物车模块是一个核心功能,用于管理用户在电商平台上选择的商品。 - 用户可以将商品添加到购物车、编辑购物车中的商品数量和规格、删除购物车中的商品,以及结算购物车中的商品等操作。 2. 页面设计: - 购物车模块通常由一个购物车页面和一个结算页面组成。 - 购物车页面展示用户已添加的商品列表,包括商品名称、价格、数量、规格等信息。用户可以在此页面进行编辑和删除操作。 - 结算页面展示用户选中的商品信息,包括总价、运费等。用户可以选择支付方式并提交订单。 3. 数据管理: - 使用Vuex或其他状态管理工具来统一管理购物车相关的数据,包括购物车商品列表、选中状态、数量等。 - 通过监听数据的变化,实时更新购物车页面和结算页面的展示信息。 4. 交互逻辑: - 用户点击“加入购物车”按钮时,将商品信息添加到购物车列表中,并更新相应的数量和价格。 - 用户可以通过增加或减少商品数量来调整购物车中商品的数量。 - 用户可以勾选或取消勾选商品来选中或取消选中商品。 - 用户点击结算按钮时,根据选中的商品生成订单,并跳转到支付页面。 5. 后端交互: - 与后端进行交互时,需要发送请求将用户的购物车信息保存到数据库中,并在结算页面获取最新的商品信息和价格。 - 在提交订单时,将用户选中的商品信息发送给后端进行订单生成和支付处理。 以上是对Uniapp项目中购物车模块的简要描述。具体的实现方式和细节会根据项目需求和设计进行调整。希望对您有所帮助,如有更多问题,请继续提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值