flask 与小程序 购物车删除和编辑库存功能

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

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_infoif not member_info:resp['code'] = -1resp['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_listreturn jsonify(resp)@route_api.route("/cart/set", methods=["POST"])
def setCart():resp = {'code': 200, 'msg': '添加购物车成功~', 'data': {}}req = request.valuesfood_id = int(req['id']) if 'id' in req else 0number = int(req['number']) if 'number' in req else 0if food_id < 1 or number < 1:resp['code'] = -1resp['msg'] = "添加购物车失败-1~~"return jsonify(resp)member_info = g.member_infoif not member_info:resp['code'] = -1resp['msg'] = "添加购物车失败-2~~"return jsonify(resp)food_info = Food.query.filter_by( id =  food_id ).first()if not food_info:resp['code'] = -1resp['msg'] = "添加购物车失败-3~~"return jsonify(resp)if food_info.stock < number:resp['code'] = -1resp['msg'] = "添加购物车失败,库存不足~~"return jsonify(resp)ret =  CartService.setItems( member_id=member_info.id,food_id = food_info.id,number = number )if not ret:resp['code'] = -1resp['msg'] = "添加购物车失败-4~~"return jsonify(resp)return jsonify(resp)@route_api.route("/cart/del", methods=["POST"])
def delCart():resp = {'code': 200, 'msg': '添加购物车成功~', 'data': {}}req = request.valuesparams_goods = req['goods'] if 'goods' in req else Noneitems = []if params_goods:items = json.loads(params_goods)if not items or len( items ) < 1:return jsonify(resp)member_info = g.member_infoif not member_info:resp['code'] = -1resp['msg'] = "删除购物车失败-1~~"return jsonify(resp)ret = CartService.deleteItem( member_id = member_info.id, items = items )if not ret:resp['code'] = -1resp['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 jsonjson_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():@staticmethoddef deleteItem( member_id = 0,items = None ):if member_id < 1 or not items:return Falsefor item in items:MemberCart.query.filter_by( food_id = item['id'],member_id = member_id ).delete()db.session.commit()return True@staticmethoddef setItems( member_id = 0,food_id = 0,number = 0 ):if member_id < 1 or food_id < 1 or number < 1:return Falsecart_info = MemberCart.query.filter_by( food_id = food_id, member_id= member_id ).first()if cart_info:model_cart = cart_infoelse:model_cart = MemberCart()model_cart.member_id = member_idmodel_cart.created_time = getCurrentDate()model_cart.food_id = food_idmodel_cart.quantity = numbermodel_cart.updated_time = getCurrentDate()db.session.add(model_cart)db.session.commit()return True

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/636023.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】第三十站:进程间通信

文章目录 一、是什么二、为什么三、怎么办四、管道1.什么是管道2.管道的原理3.接口4.编码实现5.管道的特征6.管道的四种情况 一、是什么 两个或者多个进程实现数据层面的交互 因为进程独立性的存在&#xff0c;导致进程通信的成本比较高 通信是有成本的&#xff0c;体现在要打破…

Curl- go的自带包 net/http实现

Curl- go的自带包 net/http实现 case http包中的Request 发送请求的步骤&#xff1a;1. 创建客户端 2. 发送请求 3. 接受响应 client : &http.Client{}req, _ : http.NewRequest("POST", url, nil) // request中有很多参数可以设置//设置头部 req.Header.se…

【禅道】的介绍及安装使用

文章目录 一、禅道入门1.1 概述1.2 特点1.2.1 私有化部署&#xff08;禅道&#xff09;&#xff1a;1.2.2 SaaS云部署&#xff08;云禅道&#xff09;&#xff1a; 1.3 安装1.4 启动禅道 二、禅道的使用2.1 编辑公司信息2.2 搭建组织架构2.2.1 创建部门2.2.2 增加员工 2.2 产品…

axios封装-reques.js

1. 简介 参考网址&#xff1a;http://www.axios-js.com/zh-cn/docs/#axios-create-config 在现代的前端开发中&#xff0c;我们经常需要与后端API进行交互&#xff0c;而axios是其中的一个非常流行的选择。为了简化请求的处 理和增强代码的可读性&#xff0c;我们经常需要对…

Solana Mobile开启第二代Saga手机预售,怎么购买Solana Mobile?

PANews 1月17日消息&#xff0c;Solana Mobile官方宣布开启其第二代Saga手机&#xff08;Chapter 2&#xff09;的预售&#xff0c;预购押金为450美元&#xff0c;预计将于2025年上半年发货。同时&#xff0c;Chapter 2的发售将会包括推荐&#xff08;Referrals&#xff09;和积…

用MATLAB函数在图表中建立模型

本节介绍如何使用Stateflow图表创建模型&#xff0c;该图表调用两个MATLAB函数meanstats和stdevstats。meanstats计算平均值&#xff0c;stdevstats计算vals中值的标准偏差&#xff0c;并将它们分别输出到Stateflow数据平均值和stdev。 请遵循以下步骤&#xff1a; 1.使用以下…

sql570 | 至少有5名下属的经理 | join on | group by | having

讲给一张表&#xff0c;表字段分别为 id 、姓名、部分、经理id&#xff0c;可能存在张三既是下属也是经理 现在找出下属起码有5名员工的经理 CREATE TABLE Employee (id INT,name VARCHAR(255),department VARCHAR(255),managerId INT );INSERT INTO Employee (id, name, depar…

数据库的内连接和外连接

数据库的内连接和外连接 内连接: 两个或两个以上的表进行关联查询时&#xff0c;查询的结果集中 返回所有满足连接条件的行。 外连接: 两个或两个以上的表进行关联查询时&#xff0c;查询的结果集中 除了返回满足连接条件的行以外&#xff0c;还返回左&#xff08;或右&…

rabbitmq的介绍、使用、案例

1.介绍 rabbitmq简单来说就是个消息中间件&#xff0c;可以让不同的应用程序之间进行异步的通信&#xff0c;通过消息传递来实现解耦和分布式处理。 消息队列&#xff1a;允许将消息发到队列&#xff0c;然后进行取出、处理等操作&#xff0c;使得生产者和消费者之间能够解耦&…

scratch打蝙蝠 2023年12月中国电子学会 图形化编程 scratch编程等级考试二级真题和答案解析

目录 scratch打蝙蝠 一、题目要求 1、准备工作 2、功能实现 二、案例分析

基于SpringBoot Vue博物馆管理系统

大家好✌&#xff01;我是Dwzun。很高兴你能来阅读我&#xff0c;我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结&#xff0c;还为大家分享优质的实战项目&#xff0c;本人在Java项目开发领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#x…

Qt拖拽组件与键盘事件

1.相关说明 1.设置widget或view的拖拽和放置模式函数setDragDropMode参数说明&#xff0c;NoDragDrop(无拖拽和放置)、DragOnly(只允许拖拽)、DropOnly(只允许放置)、DragDrop(允许拖拽和放置)、InternalMove(只移动不复制) 2.设置widget或view的放置动作函数setDefaultDropAct…

MacOS X 安装免费的 LaTex 环境

最近把工作终端一步步迁移到Mac上来了&#xff0c;搭了个 Latex的环境&#xff0c;跟windows上一样好用。 选择了 Mactex 做编译&#xff0c;用 Texmaker 做编辑&#xff1b; 1. 下载与安装 1.1 Mactex 下载安装 MacOS 安装和示例 LaTex 的编译器 与 编辑器 编译器使用免费…

Cocos在VsCode中调试-端口安全问题 net::ERR_UNSAFE_PORT

问题: POST http://127.0.0.1:6000/api/login net::ERR_UNSAFE_PORT 原因&#xff1a; 这个错误表明你在尝试使用一个被认为是不安全的端口进行网络请求。通常情况下&#xff0c;浏览器会限制使用一些特定的端口&#xff0c;因为它们被认为是潜在的安全风险。 在这种情况下&a…

IO、NIO、IO多路复用

IO是什么&#xff1f; IO分为两类&#xff0c;它们之间是有区别的&#xff0c;而且有很大的区别&#xff1b;1. 文件系统的IO 也叫本地io&#xff0c;就是和磁盘或者外围存储设备进行读写操作&#xff0c;外围设备有USB、移动硬盘等等&#xff1b;2. 网络的IO 将数据发送给对方…

Jetson Orin Nano使用OpenCV获取视频帧率和帧数的方法

测试过程 首先确认下视频的播放时间 使用cv库来获取帧率和帧数&#xff0c;测试代码如下 import cv2 cap cv2.VideoCapture("xxx.mp4") if not cap.isOpened():print("Cannot open camera")exit()# get default video FPS fps cap.get(cv2.CAP_PROP_F…

Peter算法小课堂—拓扑排序与最小生成树

拓扑排序 讲拓扑排序前&#xff0c;我们要先了解什么是DAG树。所谓DAG树&#xff0c;就是指“有向无环图”。请判断下列图是否是DAG图 第一幅图&#xff0c;它不是DAG图&#xff0c;因为它形成了一个环。第二幅图&#xff0c;它也不是DAG图&#xff0c;因为它没有方向。第三幅…

手把手教你如何快速定位bug,如何编写测试用例,快来观摩......

手把手教你如何快速定位bug,如何编写测试用例,快来观摩......手把手教你如何快速定位bug,如何编写测试用例,快来观摩......作为一名测试人员如果连常见的系统问题都不知道如何分析&#xff0c;频繁将前端人员问题指派给后端人员&#xff0c;后端人员问题指派给前端人员&#xf…

开发安全之:JSON Injection

Overview 在 XXX.php 的第 X 行中&#xff0c;responsemsg() 方法将未经验证的输入写入 JSON。攻击者可以利用此调用将任意元素或属性注入 JSON 实体。 Details JSON injection 会在以下情况中出现&#xff1a; 1. 数据从一个不可信赖的数据源进入程序。 2. 将数据写入到 …

pytest log配置

发现用print在console里面打不出来&#xff0c;所以查了一下关于pytest的log配置&#xff0c;记录 首先需要在根目录新建 pytest.ini 如果你只需要使用print打印日志的话&#xff0c;就只需要这样写 [pytest] addopts -s #addopts 是一个配置项&#xff0c;用于指定传递给 p…