编辑  :   数量加减   价格汇总  数据清空

mina/pages/cart/index.wxml

<!--index.wxml-->
<view class="container">
    <view class="title-box" wx:if="{{ !list.length }}">
        购物车空空如也~
    </view>
    <view class="to-index-btn" bindtap="toIndexPage" wx:if="{{ !list.length }}">
        去逛逛
    </view>

    <view class="list-top" wx:if="{{ list.length }}">
        <view class="label">购物车</view>
        <view class="edit-btn" hidden="{{!saveHidden}}" bindtap="editTap">编辑</view>
        <view class="edit-btn" hidden="{{saveHidden}}" bindtap="saveTap">完成</view>
    </view>

    <view class="goodsList" wx:if="{{ list.length }}">
        <view class="a-gooods" wx:for="{{ list }}"  wx:key="{{index}}" >
            <view class="a-goods-conts {{item.active? 'active':''}}" bindtap="selectTap" data-index="{{index}}">
                <view class="goods-info">
                    <view class="img-box">
                        <image src="{{item.pic_url}}" class="img"/>
                    </view>
                    <view class="text-box">
                        <view class="goods-title">{{item.name}}</view>
                        <view class="goods-price">¥ {{item.price}}</view>
                        <view class="buy-num">
                            <view class="jian-btn" catchtap="jianBtnTap" data-index="{{index}}">-</view>
                            <input  type="number" value="{{item.number}}" disabled/>
                            <view class="jia-btn" catchtap="jiaBtnTap" data-index="{{index}}">+</view>
                        </view>
                    </view>
                </view>
            </view>
        </view>
    </view>
    <view class="jiesuan-box" wx:if="{{ list.length }}">
        <view class="left-price">
            <view class="all-selected  {{allSelect?'active':''}}" bindtap="bindAllSelect">全选</view>
            <view class="total" hidden="{{noSelect}}">合计:¥ {{totalPrice}}</view>
        </view>
        <view class="to-pay-btn {{noSelect?'no-select':''}}" hidden="{{!saveHidden}}" bindtap="toPayOrder">去结算</view>
        <view class="to-pay-btn {{noSelect?'no-select':''}}" hidden="{{saveHidden}}" bindtap="deleteSelected">删除</view>
    </view>
</view>

知识点1: <view class="jian-btn" catchtap="jianBtnTap" data-index="{{index}}">

是一个微信小程序中的一个视图组件,具有以下特点:

  • class="jian-btn":该组件的样式类名为jian-btn,可以通过CSS样式表对其进行样式设置。
  • catchtap="jianBtnTap":该组件绑定了一个catchtap事件,当用户点击该组件时,会触发名为jianBtnTap的事件处理函数。微信小程序 事件_w3cschool
  • data-index="{{index}}":该组件设置了一个自定义属性data-index,其值为{{index}},可以在事件处理函数中获取该属性的值。

根据提供的信息,这个组件可能是一个按钮,当用户点击该按钮时,会触发jianBtnTap事件处理函数,并且可以通过data-index属性传递一些额外的数据。

请注意,以上是根据提供的引用内容推测的答案,具体的功能和效果还需要根据实际代码和上下文来确定。

mina/pages/cart/index.js

//index.js
var app = getApp();
Page({
    data: {},
    onLoad: function () {

    },
    onShow:function(){
        this.getCartList();
    },
    //每项前面的选中框
    selectTap: function (e) {
        var index = e.currentTarget.dataset.index;
        var list = this.data.list;
        if (index !== "" && index != null) {
            list[ parseInt(index) ].active = !list[ parseInt(index) ].active;
            this.setPageData(this.getSaveHide(), this.totalPrice(), this.allSelect(), this.noSelect(), list);
        }
    },
    //计算是否全选了
    allSelect: function () {
        var list = this.data.list;
        var allSelect = false;
        for (var i = 0; i < list.length; i++) {
            var curItem = list[i];
            if (curItem.active) {
                allSelect = true;
            } else {
                allSelect = false;
                break;
            }
        }
        return allSelect;
    },
    //计算是否都没有选
    noSelect: function () {
        var list = this.data.list;
        var noSelect = 0;
        for (var i = 0; i < list.length; i++) {
            var curItem = list[i];
            if (!curItem.active) {
                noSelect++;
            }
        }
        if (noSelect == list.length) {
            return true;
        } else {
            return false;
        }
    },
    //全选和全部选按钮
    bindAllSelect: function () {
        var currentAllSelect = this.data.allSelect;
        var list = this.data.list;
        for (var i = 0; i < list.length; i++) {
            list[i].active = !currentAllSelect;
        }
        this.setPageData(this.getSaveHide(), this.totalPrice(), !currentAllSelect, this.noSelect(), list);
    },
    //加数量
    jiaBtnTap: function (e) {
        var that = this;
        var index = e.currentTarget.dataset.index;
        var list = that.data.list;
        list[parseInt(index)].number++;
        that.setPageData(that.getSaveHide(), that.totalPrice(), that.allSelect(), that.noSelect(), list);
        this.setCart( list[parseInt(index)].food_id,list[parseInt(index)].number );
    },
    //减数量
    jianBtnTap: function (e) {
        var index = e.currentTarget.dataset.index;
        var list = this.data.list;
        if (list[parseInt(index)].number > 1) {
            list[parseInt(index)].number--;
            this.setPageData(this.getSaveHide(), this.totalPrice(), this.allSelect(), this.noSelect(), list);

            this.setCart( list[parseInt(index)].food_id,list[parseInt(index)].number );
        }
    },
    //编辑默认全不选
    editTap: function () {
        var list = this.data.list;
        for (var i = 0; i < list.length; i++) {
            var curItem = list[i];
            curItem.active = false;
        }
        this.setPageData(!this.getSaveHide(), this.totalPrice(), this.allSelect(), this.noSelect(), list);
    },
    //选中完成默认全选
    saveTap: function () {
        var list = this.data.list;
        for (var i = 0; i < list.length; i++) {
            var curItem = list[i];
            curItem.active = true;
        }
        this.setPageData(!this.getSaveHide(), this.totalPrice(), this.allSelect(), this.noSelect(), list);
    },
    getSaveHide: function () {
        return this.data.saveHidden;
    },
    totalPrice: function () {
        var list = this.data.list;
        var totalPrice = 0.00;
        for (var i = 0; i < list.length; i++) {
            if ( !list[i].active) {
                continue;
            }
            totalPrice = totalPrice + parseFloat( list[i].price ) * list[i].number;
        }
        return totalPrice;
    },
    setPageData: function (saveHidden, total, allSelect, noSelect, list) {
        this.setData({
            list: list,
            saveHidden: saveHidden,
            totalPrice: total,
            allSelect: allSelect,
            noSelect: noSelect,
        });
    },
    //去结算
    toPayOrder: function () {
        var data = {
            type:"cart",
            goods: []
        };

        var list = this.data.list;
        for (var i = 0; i < list.length; i++) {
            if ( !list[i].active) {
                continue;
            }
            data['goods'].push({
                "id": list[i].food_id,
                "price": list[i].price,
                "number": list[i].number
            });
        }

        wx.navigateTo({
            url: "/pages/order/index?data=" + JSON.stringify(data)
        });
    },
    //如果没有显示去光光按钮事件
    toIndexPage: function () {
        wx.switchTab({
            url: "/pages/food/index"
        });
    },
    //选中删除的数据
    deleteSelected: function () {
        var list = this.data.list;
        var goods = [];
        list = list.filter(function ( item ) {
            if( item.active ){
                goods.push( {
                    "id":item.food_id
                } )
            }

            return !item.active;
        });

        this.setPageData( this.getSaveHide(), this.totalPrice(), this.allSelect(), this.noSelect(), list);
        //发送请求到后台删除数据
        wx.request({
            url: app.buildUrl("/cart/del"),
            header: app.getRequestHeader(),
            method: 'POST',
            data: {
                goods: JSON.stringify( goods )
            },
            success: function (res) {
            }
        });
    },
    getCartList: function () {
        var that = this;
        wx.request({
            url: app.buildUrl("/cart/index"),
            header: app.getRequestHeader(),
            success: function (res) {
                var resp = res.data;
                if (resp.code != 200) {
                    app.alert({"content": resp.msg});
                    return;
                }
                that.setData({
                    list:resp.data.list,
                    saveHidden: true,
                    totalPrice: 0.00,
                    allSelect: true,
                    noSelect: false
                });

                that.setPageData(that.getSaveHide(), that.totalPrice(), that.allSelect(), that.noSelect(), that.data.list);
            }
        });
    },
    setCart:function( food_id, number ){
        var that = this;
        var data = {
            "id": food_id,
            "number": number
        };
        wx.request({
            url: app.buildUrl("/cart/set"),
            header: app.getRequestHeader(),
            method: 'POST',
            data: data,
            success: function (res) {
            }
        });
    }
});

setCart 数据统一提交

问题1: .push()

JavaScript push() 方法_w3cschool     类似python中append

push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。

注意: 新元素将添加在数组的末尾。

注意: 此方法改变数组的长度。

提示: 在数组起始位置添加元素请使用 unshift() 方法。

问题2:  JSON.stringify(  )

JSON.stringify()方法用于将JavaScript对象转换为JSON字符串。

下面是一个关于goods对象的例子:

const goods = {
  name: "Apple",
  price: 2.99,
  quantity: 10
};

const jsonString = JSON.stringify(goods);
console.log(jsonString);

输出结果为:

{"name":"Apple","price":2.99,"quantity":10}

这里,goods对象被转换为了一个JSON字符串,其中包含了对象的属性和对应的值。注意,JSON.stringify()方法会自动将对象的属性名和属性值转换为字符串,并且会忽略掉不可枚举的属性。

web/controllers/api/Cart.py

# -*- coding: utf-8 -*-
from web.controllers.api import route_api
from  flask import request,jsonify,g
from common.models.food.Food import Food
from common.models.member.MemberCart import MemberCart
from common.libs.member.CartService import CartService
from common.libs.Helper import selectFilterObj,getDictFilterField
from common.libs.UrlManager import UrlManager
from application import app,db
import json

@route_api.route("/cart/index")
def cartIndex():
    resp = {'code': 200, 'msg': '添加购物车成功~', 'data': {}}
    member_info = g.member_info
    if not member_info:
        resp['code'] = -1
        resp['msg'] = "获取失败,伪登录~~"
        return jsonify(resp)
    cart_list = MemberCart.query.filter_by( member_id=member_info.id).all()
    data_cart_list = []
    if cart_list:
        food_ids = selectFilterObj( cart_list,"food_id" )
        food_map = getDictFilterField( Food,Food.id,"id",food_ids )
        for item in cart_list:
            tmp_food_info = food_map[ item.food_id ]
            tmp_data = {
                "id":item.id,
                "number":item.quantity,
                "food_id": item.food_id,
                "name":tmp_food_info.name,
                "price":str( tmp_food_info.price ),
                "pic_url": UrlManager.buildImageUrl( tmp_food_info.main_image ),
                "active":True
            }
            data_cart_list.append( tmp_data )

    resp['data']['list'] = data_cart_list
    return jsonify(resp)

@route_api.route("/cart/set", methods=["POST"])
def setCart():
    resp = {'code': 200, 'msg': '添加购物车成功~', 'data': {}}
    req = request.values
    food_id = int(req['id']) if 'id' in req else 0
    number = int(req['number']) if 'number' in req else 0
    if food_id < 1 or number < 1:
        resp['code'] = -1
        resp['msg'] = "添加购物车失败-1~~"
        return jsonify(resp)

    member_info = g.member_info
    if not member_info:
        resp['code'] = -1
        resp['msg'] = "添加购物车失败-2~~"
        return jsonify(resp)

    food_info = Food.query.filter_by( id =  food_id ).first()
    if not food_info:
        resp['code'] = -1
        resp['msg'] = "添加购物车失败-3~~"
        return jsonify(resp)

    if food_info.stock < number:
        resp['code'] = -1
        resp['msg'] = "添加购物车失败,库存不足~~"
        return jsonify(resp)

    ret =  CartService.setItems( member_id=member_info.id,food_id = food_info.id,number = number )
    if not ret:
        resp['code'] = -1
        resp['msg'] = "添加购物车失败-4~~"
        return jsonify(resp)
    return jsonify(resp)

@route_api.route("/cart/del", methods=["POST"])
def delCart():
    resp = {'code': 200, 'msg': '添加购物车成功~', 'data': {}}
    req = request.values
    params_goods = req['goods'] if 'goods' in req else None

    items = []
    if params_goods:
        items = json.loads(params_goods)
    if not items or len( items ) < 1:
        return jsonify(resp)

    member_info = g.member_info
    if not member_info:
        resp['code'] = -1
        resp['msg'] = "删除购物车失败-1~~"
        return jsonify(resp)

    ret = CartService.deleteItem( member_id = member_info.id, items = items )
    if not ret:
        resp['code'] = -1
        resp['msg'] = "删除购物车失败-2~~"
        return jsonify(resp)
    return jsonify(resp)

@route_api.route("/cart/del", methods=["POST"])

问题1: json.loads()

json.loads()是Python标准库json模块中的一个方法,用于将JSON字符串转换为Python数据类型。它的使用方法如下所示:

import json

json_str = '{"name": "John", "age": 30, "city": "New York"}'
data = json.loads(json_str)

print(data)  # 输出:{'name': 'John', 'age': 30, 'city': 'New York'}

在上面的例子中,我们首先导入了json模块。然后,我们定义了一个JSON字符串json_str,其中包含了一个名为"name"的键和对应的值"John",一个名为"age"的键和对应的值30,以及一个名为"city"的键和对应的值"New York"。接下来,我们使用json.loads()方法将JSON字符串转换为Python数据类型,并将结果赋值给变量data。最后,我们打印出data的值,即转换后的Python字典。

需要注意的是,json.loads()只适用于读取JSON字符串,如果想要从JSON文件中读取数据,请使用json.load()方法。

common/libs/Helper.py

# -*- coding: utf-8 -*-
import hashlib,requests,random,string,json
from application import app,db
from common.models.member.MemberCart import MemberCart
from common.libs.Helper import getCurrentDate
class CartService():

    @staticmethod
    def deleteItem( member_id = 0,items = None ):
        if member_id < 1 or not items:
            return False
        for item in items:
            MemberCart.query.filter_by( food_id = item['id'],member_id = member_id ).delete()
        db.session.commit()
        return True

    @staticmethod
    def setItems( member_id = 0,food_id = 0,number = 0 ):
        if member_id < 1 or food_id < 1 or number < 1:
            return False
        cart_info = MemberCart.query.filter_by( food_id = food_id, member_id= member_id ).first()
        if cart_info:
            model_cart = cart_info
        else:
            model_cart = MemberCart()
            model_cart.member_id = member_id
            model_cart.created_time = getCurrentDate()

        model_cart.food_id = food_id
        model_cart.quantity = number
        model_cart.updated_time = getCurrentDate()
        db.session.add(model_cart)
        db.session.commit()
        return True

01-21 17:21