商品购物车功能删/改/单选/全选功能实现

后端

紧接着添加功能后

#添加购物车视图
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='shayebushi')
        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
            })
    #修改数量
    def put(self,request,goods_id):
        user = request.META.get('USER')  # 获取到中间件检测完登录,传递过来的用户信息、
        if not user:
            return Response({
                'code': 400,
                'msg': '用户未登录'
            })
        user_id = user['user_id']    #当前登录用户
        num=request.data.get('num')  #修改后的数量

        #判断一下商品是否在当前用户的购物车
        r=redis.Redis(host='127.0.0.1',port=6379,password='shayebushi')
        key='cart:%s'%user_id
        is_exists=r.hexists(key,goods_id)  #判断某商品是否在购物车中
        if not is_exists:
            return Response({
                'code':400,
                'msg':'商品不在购物车中'
            })
        #判断一下商品是否存在
        goods_info=Goods.objects.filter(id=goods_id).first()
        if not goods_info:
            return Response({
                'code':400,
                'msg':'商品不存在'
            })
        #判断一下是否超出了库存量
        if int(num)>goods_info.stock:
            return Response({
                'code':400,
                'msg':'超出库存量'
            })
        #修改数据库中的数据
        r.hset(key,goods_id,num)
        r.close()
        #返回
        return Response({
            'code':200,
            'msg':'购物车数量更新成功,当前数量%s'%num,

        })
    #删除购物车
    def delete(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='shayebushi')
        key='cart:%s'%user_id
        select_key='cart_select:%s'%user_id
        #从购物车删除
        r.hdel(key,goods_id)
        #从选中的商品中删除
        r.srem(select_key,goods_id)
        #返回
        return Response({
            'code':200,
            'msg':'删除成功'
        })
# 查看购物车
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='shayebushi')
        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
        })
    #购物车全选与全不选
    def post(self,request):
        user = request.META.get('USER')  # 获取到中间件检测完登录,传递过来的用户信息、
        if not user:
            return Response({
                'code': 400,
                'msg': '用户未登录'
            })
        user_id = user['user_id']
        check=request.data.get('check')  #前台传过来的用户是否全选
        r = redis.Redis(host='127.0.0.1', port=6379, password='shayebushi')
        key='cart:%s'%user_id
        select_key='cart_select:%s'%user_id
        if check=='check':
            #执行全选逻辑
            #获取购物车所有商品id
            goods_ids=r.hkeys(key)
            goods_ids_int=[]
            for i in goods_ids:
                goods_ids_int.append(i.decode())
            #把商品id全部添加到选中的集合里面
            r.sadd(select_key,*goods_ids_int)
            return Response({
                'code':200,
                'msg':'全选成功'
            })
        #走到这就执行全都不选逻辑
        r.delete(select_key)
        return Response({
            'code': 201,
            'msg': '取消全选成功'
        })
#购物车单选
class Cartcheckview(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']
        #判断商品是否存在
        goods_info=Goods.objects.filter(id=goods_id).first()
        if not goods_info:
            return Response({
                'code':400,
                'msg':'商品不存在'
            })
        #链接reids数据库
        #判断商品是否存在购物车
        r=redis.Redis(host='127.0.0.1',port=6379,password='shayebushi')
        key='cart:%s'%user_id
        is_exists=r.hexists(key,goods_id)
        if not is_exists:
            return Response({
                'code':400,
                'msg':'商品不在购物车'
            })
        #判断商品是否选中
        select_key='cart_select:%s'%user_id
        is_check=r.sismember(select_key,goods_id)
        if is_check:  #商品已经选中
            #执行不选中
            r.srem(select_key,goods_id)
            return Response({
                'code':201,
                'msg':'取消选中成功'
            })
        #程序走到这一步,数模商品未选中
        #执行选中
        r.sadd(select_key,goods_id)
        return Response({
            'code': 200,
            'msg': '选中成功'
        })

配置路由

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

前端

找到对应的vue文件,对相关的功能函数进行修改
例如:ShoppingCart.vue

methods: {
    ...mapActions(["updateShoppingCart", "deleteShoppingCart", "checkAll"]),

    // 修改商品数量时,触发
    handleChange(currentValue, key, productID) {
      console.log("@@修改商品数量了......")
      // currentValue,当前商品的新数量
      // key,商品{} 在shoppingChart数组中 的索引
      // productID 当前商品的id
      console.log("商品ID", productID, "数量为", currentValue, "在列表中索引为", key)

      // 1.修改数量时,设置为 勾选状态
      this.updateShoppingCart({key: key, prop: "check", val: true});

      // 2.TODO django后端修改购物车数量
      this.$axios.put('/goods/cart/'+productID+'/',{
        'num':currentValue
      },{
        'headers':{
          'token':localStorage.getItem('token')
        }
      }).then((result) => {
        if (result.data.code==200){
          // 更新vuex中的数据
          this.updateShoppingCart({
            'prop':'num',
            'key':key,
            'val':currentValue,
          })
          this.notifySucceed(result.data.msg)
        }else{
          this.notifyError(result.data.msg)
        }
      }).catch((err) => {
        console.log(err)
      });

    },
    // 单选
    checkChange(val, key, productID) {
      console.log("商品ID:", productID, "选中状态为:", val, "在列表中索引为", key)
      // TODO django 后端设置数据单选
      this.$axios.post('goods/cart/check/'+productID+'/',{},{
        'headers':{
          'token':localStorage.getItem('token')
        }
      }).then((result) => {
        if (result.data.code==200){
          this.updateShoppingCart({
            'prop':'check',
            'key':key,
            'val':true
          })
          this.notifySucceed(result.data.msg)
        }else if(result.data.code==201){
          this.updateShoppingCart({
            'prop':'check',
            'key':key,
            'val':false
          })
          this.notifySucceed(result.data.msg)
        }else{
          this.notifyError(result.data.msg)
        }
      }).catch((err) => {
        console.log(err)
      });
    },

    // 向后端请求删除购物车的 商品信息
    deleteItem(e, productID) {
      console.log("删除的商品ID:", productID)
      // TODO 后端删除商品ID
      this.$axios.delete('/goods/cart/'+productID+'/',{
        'headers':{
          'token':localStorage.getItem('token')
        }
      }).then((result) => {
        if (result.data.code==200){
          this.notifySucceed(result.data.msg)
          this.deleteShoppingCart(productID)
        }else{
          this.notifyError(result.data.msg)
        }
      }).catch((err) => {
        console.log(err)
      });
    }
  },


  computed: {
    ...mapGetters([
      "getShoppingCart", //获取vuex中的购物车数组
      "getCheckNum", //获取购物车中勾选的商品数量
      "getTotalPrice",
      "getNum", //计算属性,获取购物车中的商品总数
    ]),

    isAllCheck: {
      // 读的时候执行getter
      get() {
        return this.$store.getters.getIsAllCheck;
      },
      // 写的时候,执行setter
      set(val) {
        console.log("设置全选状态为", val)
        // TODO 设置全选状态
        var check='check'
        if (!val){
          check=''
        }
        this.$axios.post('/goods/cart/',{
          'check':check,
        },{
          'headers':{
            'token':localStorage.getItem('token')
          }
        }).then((result) => {
          if (result.data.code==201){
            this.notifySucceed(result.data.msg)
            for (var j=0;j < this.getShoppingCart.length;j++){
              this.updateShoppingCart({
                'prop':'check',
                'key':j,
                'val':false,
              })
            }
          }else if (result.data.code==200){
            this.notifySucceed(result.data.msg)
            for (var i=0;i < this.getShoppingCart.length;i++){
              this.updateShoppingCart({
                'prop':'check',
                'key':i,
                'val':true
              })
            }
          }else{
            this.notifyError(result.data.msg)
          }
        }).catch((err) => {
          console.log(err)
        });
      }
    }
  }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在UniApp中实现购物车全选单选和反选功能,可以通过以下步骤进行操作: 1. 数据结构设计:首先,你需要定义一个购物车数据结构,可以使用数组或对象来表示每个商品的信息,例如商品名称、价格、数量等。同时,为每个商品添加一个选中状态的属性,用于记录是否被选中。 2. 渲染购物车列表:在页面中使用`v-for`指令遍历购物车数据,并将商品信息展示出来。同时,为每个商品的选中状态绑定一个`v-model`指令,用于实现单选功能。 3. 实现全选功能添加一个全选复选框,通过绑定一个变量来控制全选的状态。当全选复选框被点击时,遍历购物车数据,将每个商品的选中状态与全选状态保持一致。 4. 实现反选功能添加一个反选按钮,当点击反选按钮时,遍历购物车数据,将每个商品的选中状态取反。 5. 计算总价和总数量:通过遍历购物车数据,累加选中商品的价格和数量,得到总价和总数量。 6. 相关代码示例: ```html <template> <div> <div> <input type="checkbox" v-model="selectAll" @change="handleSelectAll" /> 全选 <button @click="handleInverseSelect">反选</button> </div> <div v-for="(item, index) in cartList" :key="index"> <input type="checkbox" v-model="item.selected" @change="handleSelectItem(index)" /> {{ item.name }} - ¥{{ item.price }} - 数量:{{ item.quantity }} </div> <div> 总价:¥{{ totalPrice }},总数量:{{ totalQuantity }} </div> </div> </template> <script> export default { data() { return { selectAll: false, cartList: [ { name: '商品1', price: 10, quantity: 1, selected: false }, { name: '商品2', price: 20, quantity: 2, selected: false }, { name: '商品3', price: 30, quantity: 3, selected: false } ] }; }, computed: { totalPrice() { let total = 0; for (let item of this.cartList) { if (item.selected) { total += item.price * item.quantity; } } return total; }, totalQuantity() { let total = 0; for (let item of this.cartList) { if (item.selected) { total += item.quantity; } } return total; } }, methods: { handleSelectAll() { for (let item of this.cartList) { item.selected = this.selectAll; } }, handleSelectItem(index) { this.cartList[index].selected = !this.cartList[index].selected; }, handleInverseSelect() { for (let item of this.cartList) { item.selected = !item.selected; } } } }; </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值