商品购物车功能实现 添加/查看

购物车

后端

由于购物车数据量小,且数据变化比较频繁,所以采用Redis内存数据库来存储,采用的数据类型如下:

  1. 存储商品数据,采用hash结构,如cart_1:{3:5}。其中的数字部分分别代表用户id,加购的商品id,购买的该商品的数量。
  2. 存储商品的选中状态,采用set结构,如cart_selected_1: {3, 5,…}
    集合中的数字为勾选的商品id。
    Redis hash&set数据类型操作回顾:
    python的操作方法
r = redis.Redis(host='localhost', port=6379, db=0)
#存储商品数据
r.hset('cart_1', key=2, value=3)
r.hget("cart_1", 2) #注意是字节数据byte类型
r.hdel("cart_1", 2) #删除
#存储集合数据
r.sadd("cart_selected_1", 2)
r.sadd("cart_selected_1", 2,3)
r.smembers("cart_selected_1")
r.srem("cart_selected_1", 2)

#关闭连接
r.close()
#添加购物车视图
class Cartview(APIView):
    def post(self,request,goods_id):
    	#获取到中间件检测完登录,传递过来的用户信息
        user=request.META.get('USER')  
        if not user:
            return Response({
                'code':400,
                'msg':'用户未登录'
            })
        user_id=user['user_id']
        r=redis.Redis(host='127.0.0.1',port=6379,password='redis密码')
        key='cart:'+str(user_id)
        #存入数据库
        #先判断商品是否存在
        goods_info=Goods.objects.filter(id=goods_id).first()
        if not goods_info:
            return Response({
                'code':400,
                'msg':'商品不存在'
            })
        cart={   #前端vuex里的数据结构
            'id': goods_id, # 购物车id
            'productID': goods_id, # 商品id
            'productName': goods_info.sku_name, # 商品名称
            'productImg': goods_info.img, # 商品图片
            'price': goods_info.selling_price, # 商品价格
            'num': 1, # 加购的商品数量
            'maxNum': goods_info.stock, # 商品限购数量
            'check': False # 是否勾选
        }
        #当前商品是否已经存在购物车
        is_exist=r.hexists(key,goods_id)
        if is_exist:
            #判断一下商品数量是非法已经超出库存量
            goods_count=r.hget(key,goods_id)#当前商品加入购物车的数量 返回的是byte类型
            goods_count_int=int(goods_count.decode())
            if goods_count_int>=goods_info.stock:
                return Response({
                    'code':400,
                    'msg':'购物车商品已达到上限'
                })
            #购物车数量加1
            r.hincrby(key,goods_id,1)
            cart['num']=goods_count_int+1
            return Response({
                'code':201,
                'msg':'商品已经在购物车,购物车数量加一',
                'cart':cart
            })
        else:
            #把商品添加到购物车
            r.hset(key,goods_id,str(1))
            return Response({
                'code':200,
                'msg':'加入购物车成功',
                'cart':cart
            })
# 查看购物车
class Showcartview(APIView):
    def get(self,request):
        user=request.META.get('USER')  #获取到中间件检测完登录,传递过来的用户信息、
        if not user:
            return Response({
                'code':400,
                'msg':'用户未登录'
            })
        user_id=user['user_id']
        #获取到redis里面存储的商品信息
        r=redis.Redis(host='127.0.0.1',port=6379,password='redis密码')
        key = 'cart:' + str(user_id)
        goods_list=r.hgetall(key)
        goods_all=[]
        for (k,v) in goods_list.items():
            k=k.decode()  #商品id
            v=v.decode()  #商品加购数量
            goods_info=Goods.objects.filter(id=k).first()
            if not goods_info:    #如果商品不存在,跳过该商品
                continue
            select_key = 'cart_select:%s' % user_id
            is_exists=r.sismember(select_key,k)
            info={  #前端vuex里的数据结构
                'id': k, # 购物车id
                'productID': k, # 商品id
                'productName': goods_info.sku_name, # 商品名称
                'productImg': goods_info.img, # 商品图片
                'price': goods_info.selling_price, # 商品价格
                'num': int(v), # 加购的商品数量
                'maxNum': goods_info.stock, # 商品限购数量
                'check': is_exists # 是否勾选
            }
            goods_all.append(info)
        return Response({
            'code':200,
            'msg':'商品获取成功',
            'goods':goods_all
        })

配置路由

from django.urls import path
from goods import views
urlpatterns = [
    path('cart/<int:goods_id>/',views.Cartview.as_view()),   #购物车增删改
    path('cart/',views.Showcartview.as_view()),  #查看购物车
]

前端

找到相对应的vue文件
找到相关的功能函数进行配置
例如:Details.vue

methods: {
	...mapActions(['unshiftShoppingCart','addShoppingCartNum']),
	addShoppingCart() { //
      // 判断是否登录,没有登录则显示登录组件
      if (!this.$store.getters.getUser) {
        this.$store.dispatch("setShowLogin", true);
        return;
      }
      // 已经登录
      console.log("@@getUser,已登录用户:", this.$store.getters.getUser)
      // TODO 加入购物车数据,成功后管理 vuex 内容
      this.$axios.post('/goods/cart/'+this.productID+'/',{},{
        'headers':{
          'token':localStorage.getItem('token')
        }
      }).then((result) => {
        if (result.data.code==200){
          this.unshiftShoppingCart(result.data.cart)
          this.notifySucceed(result.data.msg)
          // alert(result.data.msg)
        }else if (result.data.code==201){
          this.addShoppingCartNum(result.data.cart.productID)
          this.notifySucceed(result.data.msg)
          // alert(result.data.msg)
        }else{
          this.notifyError(result.data.msg)
        }
      }).catch((err) => {
        console.log(err)
      });

    },
}

查看购物车
例如:App.vue

watch: {
    // 管理vuex中的shoppingCart数据
    getUser: function (val) {//val为登录的用户,如{"userName":'laufing'}
      if (val === "") {
        // 退出登录,清空购物车
        this.setShoppingCart([]);//置空购物车,即state.shoppingCart=[]
      } else {
        // TODO  用户完成登录,获取该用户的购物车数据
        this.$axios.get('/goods/cart/',{
          'headers':{
            'token':localStorage.getItem('token')
          }
        }).then((result) => {
          if (result.data.code==200){
            var goods_all=result.data.goods //暗道后台传过来的购物车数据
            this.setShoppingCart(goods_all) //把购物车的数据,赋值到vuex里面
          }else{
            this.notiftError(result.data.msg)
          }
        }).catch((err) => {
          console.log(err)
        });
      }
    },
  },
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值