购物车操作
添加购物车:
需求分析和接口设计:
-
接口设计:
-
请求方式:POST
- 请求路径:/user/shoppingCart/add
- 请求参数:套餐id、菜品id、口味
- 返回结果:code、data、msg
数据库设计:
这上面出现了一些冗余字段。
这些冗余字段出现的原因是:
我们仔细观察这张图,当我们点开购物车的时候,我们需要知道这个套餐或者这个菜品的名称和图片,我们可以在加入数据的时候,将这些数据加入,这样就可以避免我们既要查找购物车这张表,然后又要取数据库中查询对应的名称和图片,提高效率,不过这也是一种空间换时间的做法,冗余字段不宜过多
添加购物车具体代码实现:
Controller层:
/*** 添加购物车* @param shoppingCartDTO* @return*/@PostMapping("/add")@ApiOperation("添加购物车")public Result insert(@RequestBody ShoppingCartDTO shoppingCartDTO){log.info("添加购物车:{}",shoppingCartDTO);shoppingCartService.add(shoppingCartDTO);return Result.success();}
Service层:
/*** 添加购物车* @param shoppingCartDTO* @return*/@Overridepublic void add(ShoppingCartDTO shoppingCartDTO) {//判断当前加入到购物车的商品是否已经存在了ShoppingCart shoppingCart = new ShoppingCart();BeanUtils.copyProperties(shoppingCartDTO,shoppingCart);Long userId = BaseContext.getCurrentId();shoppingCart.setUserId(userId);List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);//如果存在,直接数量加 1 (update)if(!list.isEmpty()){ShoppingCart cart = list.get(0);cart.setNumber(cart.getNumber()+1);shoppingCartMapper.updateById(cart);}else {//如果不存在在插入一条购物车数据(insert)//不存在的情况下,我们也是需要取判断传进来的是套餐还是菜品Long dishId = shoppingCart.getDishId();if(dishId!=null){//dishId不等于0,说明传进来的是一个菜品//传进来的是一个菜品,我们需要取设置这个菜品的值System.out.println(dishId);Dish dish = dishMapper.selectById(dishId);shoppingCart.setName(dish.getName());shoppingCart.setImage(dish.getImage());shoppingCart.setAmount(dish.getPrice());}else{//说明不是菜品,是套餐Long setmealId = shoppingCart.getSetmealId();Setmeal setmeal = setmealMapper.getById(setmealId);shoppingCart.setName(setmeal.getName());shoppingCart.setImage(setmeal.getImage());shoppingCart.setAmount(setmeal.getPrice());}shoppingCart.setNumber(1);shoppingCart.setCreateTime(LocalDateTime.now());shoppingCartMapper.insertById(shoppingCart);}}
添加购物车主要做了以下四步:
- 判断购物车中是否存在我们添加的商品或者套餐
- 如果存在,直接让数量+1(update)
- 如果不存在,再插入购物车(insert)
- 当我们插入的时候,我们还需要考虑插入的是菜品还是套餐。
注意点:
这里我们在判断购物车中是否有商品的时候,我们用了LocalThread中获取用户id的方法
这个道理很简单,我们不能把我们的商品添加到别人的购物车里去,
同时在下面的删除购物车的操作中,我们也用到了这个方法
结合之前写过的一些crud的操作,我发现我在新增员工的操作中也用了类似的方法
所以,可以总结,碰到用户或者是员工这种带有身份信息的情况的时候,可以采用LocalThread的方法来获取id。
Mapper层及注解:
/**** @param shoppingCart* @return*/List<ShoppingCart> list(ShoppingCart shoppingCart);/*** 如果商品存在,更新商品数量* @param cart*/@Update("update sky_take_out.shopping_cart set number = #{number} where id = #{id}")void updateById(ShoppingCart cart);@Insert("INSERT into sky_take_out.shopping_cart(name, image, user_id, dish_id, setmeal_id, dish_flavor, amount, create_time)" +"values " +"(#{name},#{image},#{userId},#{dishId},#{setmealId},#{dishFlavor},#{amount},#{createTime})")void insertById(ShoppingCart shoppingCart);
<select id="list" resultType="com.sky.entity.ShoppingCart">select * from sky_take_out.shopping_cart<where><if test="userId != null">and user_id = #{userId}</if><if test="setmealId != null">and setmeal_id = #{setmealId}</if><if test="dishId != null">and dish_id = #{dishId}</if><if test="dishFlavor != null">and dish_flavor = #{dishFlavor}</if></where></select>
删除购物车:
具体代码实现:
Controller层:
/*** 删除购物车中的一个商品* @param shoppingCartDTO* @return*/@PostMapping("/sub")@ApiOperation("删除购物车中的一个商品")public Result subShoppingCart(@RequestBody ShoppingCartDTO shoppingCartDTO){log.info("删除购物车中的一个商品:{}",shoppingCartDTO);shoppingCartService.subShoppingCart(shoppingCartDTO);return Result.success();}
Service层:
/*** 删除购物车中的一个商品* @param shoppingCartDTO* @return*/@Overridepublic void subShoppingCart(ShoppingCartDTO shoppingCartDTO) {ShoppingCart shoppingCart = new ShoppingCart();BeanUtils.copyProperties(shoppingCartDTO,shoppingCart);//设置查询条件,查询当前登录用户的购物车数据Long userId = BaseContext.getCurrentId();shoppingCart.setUserId(userId);List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);shoppingCart = list.get(0);Integer number = shoppingCart.getNumber();System.out.println(number);//判断数量,如果>1,直接update -1即可if(number>1){shoppingCart.setNumber(shoppingCart.getNumber()-1);shoppingCartMapper.updateById(shoppingCart);}else {//如果数量只有一个,就执行删除操作shoppingCartMapper.deleteById(shoppingCart.getId());}}
这个删除购物车的思路总体和添加差不多,
就是先根据用户id获取对应的购物车数据。
然后判断数量,数量如果大于1,直接修改数据库中的操作就行
如果等于1,就删除就行。
Mapper层:
/*** 删除购物车中的一个商品* @param Id* @return*/@Delete("delete from sky_take_out.shopping_cart where id=#{Id}")void deleteById(Long Id);
下面的几个操作已经没有什么难点了,主要就是记录一下,
查看购物车:
/*** 查看购物车* @param* @return*/@GetMapping("/list")@ApiOperation("查看购物车")public Result<List<ShoppingCart>> list(){log.info("查看购物车");List<ShoppingCart> shoppingCartList = shoppingCartService.selectShoppingCart();return Result.success(shoppingCartList);}
/*** 查看购物车* @param* @return*/@Overridepublic List<ShoppingCart> selectShoppingCart() {final Long currentId = BaseContext.getCurrentId();ShoppingCart shoppingCart = ShoppingCart.builder().userId(currentId).build();final List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);return list;}
/**** @param shoppingCart* @return*/List<ShoppingCart> list(ShoppingCart shoppingCart);
清空购物车:
/*** 清空购物车* @return*/@DeleteMapping("/clean")@ApiOperation("清空购物车")public Result cleanShoppingCart(){log.info("清空购物车");shoppingCartService.cleanShoppingCart();return Result.success();}
/*** 清空购物车* @return*/@Overridepublic void cleanShoppingCart() {final Long currentId = BaseContext.getCurrentId();shoppingCartMapper.deleteAll(currentId);}
/*** 清空购物车* @return*/@Delete("delete from sky_take_out.shopping_cart where user_id = #{currentId}")void deleteAll(Long currentId);
相关文章:

购物车操作
添加购物车: 需求分析和接口设计: 接口设计: 请求方式:POST 请求路径:/user/shoppingCart/add请求参数:套餐id、菜品id、口味返回结果:code、data、msg 数据库设计: 这上面出现了…...

华为手机 鸿蒙系统-android studio识别调试设备,开启adb调试权限
1.进入设置-关于手机-版本号,连续点击7次 认证:有锁屏密码需要输入密码, 开启开发者配置功能ok 进入开发者配置界面 打开调试功能 重新在androd studio查看可运行running devices显示了, 不行的话,重启一下android …...

计算机网络——Dijkstra路由算法
实验目的 实现基于 Dijkstra 算法的路由软件 实验内容 网络拓扑如图所示 实验过程 先编写开辟应该图的空间,然后给点映射数字,构建图。程序获取用户输入的学号,构建图中边的权值。接下来程序从用户输入获取最短路径的搜索起点࿰…...

AI智能化逐渐趋于成熟后,预测今后最吃香的开发职业
AI智能化正在成熟的路途中,这中间会有波折,但终有一天会来的,我相信等到了这一天,我们的开发效率和代码质量,将会大大不同,而我们的团队与个人,也会面临着很棒的体验。 那么在AI智能化真正趋于成…...
Acwing2024蓝桥杯BFS
AcWing 1355. 母亲的牛奶 bfs: #include<iostream> #include<queue> using namespace std; const int N21; int A,B,C; bool flag[N][N][N]; struct node{int a,b,c; }; queue<node>q; void check(int a,int b,int c){if(!flag[a][b][c]){q.push({a,b,c})…...

vue打包报错:CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
前言: vue项目,打包报错:CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 报错现象: 报错原因: 这个错误是由Node.js在尝试分配内存时因为系统的可用内存不足而发生的。"JavaScript heap…...

计算机组成原理网课笔记
无符号整数的表示与运算 带符号整数的表示与运算 原反补码的特性对比 移码 定点小数...
Python学习第四部分 函数式编程
文章目录 高阶函数lambda 表达式和匿名函数偏函数闭包map函数reduce函数filter 函数sorted函数 函数式编程主要学习:高阶函数、闭包closure、匿名函数、偏函数,map函数、reduce函数、filter函数、sorted函数 函数式编程是个很古老的概念,最古…...

数据结构-二叉树-AVL树(平衡二叉树)
红黑树是平衡二叉树的一个变种。 一、 产生平衡二叉树的原因。 二叉搜索树的问题在于极端场景下退化为类似链表的结构,所以搜索的时间复杂度就变成了O(N)。为了保证二叉树不退化为链表,我们必须保证二叉树的的平衡性。 二叉平衡搜索树就是解决上面的问…...

【Qt问题】windeployqt如何提取Qt依赖库
往期回顾 【Qt问题】Qt Creator 如何链接第三方库-CSDN博客 【Qt问题】Qt 如何带参数启动外部进程-CSDN博客 【Qt问题】VS2019 Qt win32项目如何添加x64编译方式-CSDN博客 【Qt问题】windeployqt如何提取Qt依赖库 考虑这个问题主要是:当我们的程序运行好之后&#…...

VS2019下使用MFC完成科技项目管理系统
背景: (一)实验目的 通过该实验,使学生掌握windows程序设计的基本方法。了解科技项目组织管理的主要内容和管理方面的基本常识,熟练应用数据库知识,通过处理过程对计算机软件系统工作原理的进一步理解&…...

【Android】Kotlin学习之数据容器(数组for循环遍历)
数组遍历 1. for ( item in arr){…} 2. for ( i in arr.indeces ) {…} (遍历下标) 3. for ((index, item) in arr.withInfex()) {…} (遍历下标和元素) 4. arr.forEach {} ( 遍历元素 ) 5. arr.forEachIndexed{index, item -> …}...

JavaWeb_请求响应_简单参数实体参数
一、SpringBoot方式接收携带简单参数的请求 简单参数:参数名与形参变量名相同,定义形参即可接收参数。并且在接收过程中,会进行自动的类型转换。 启动应用程序后,在postman中进行测试: 请求成功,响应回了O…...

windows端口复用
1. 概述 使用 HTTP.sys 中的 Net.tcp Port Sharing 服务,配合 WinRM 实现端口复用。 优点: HTTP.sys 为 windows 原生机制, WinRM 为 windows 自带功能,动作较小,不易触发主 动防御。 需要管理员权限。 2. 原理 (…...

[Redis] 使用布隆过滤器和分布式锁实现用户注册
布隆过滤器(Bloom Filter)是一种数据结构,用于快速判断一个元素是否可能存在于一个集合中。它通过使用多个哈希函数和一个位数组来表示一个集合,当一个元素被加入到集合时,通过哈希函数计算出多个哈希值,并…...
Okhttp 发送https请求,忽略ssl认证
工具类 import lombok.extern.slf4j.Slf4j;import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509Tru…...

IT项目管理-大题【太原理工大学】
一、根据进度网络写出时间参数表、关键路径、总工期 此类题一般是给一个表,问三问。 第一问会问某个活动的时间参数,但我们需要把整个表都求出来,否则单求一个很困难(如果你就是不想求整张表也行,不是硬性要求…...
【代码随想录】day48
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、198打家劫舍二、213打家劫舍II三、337打家劫舍III 一、198打家劫舍 class Solution { public:int rob(vector<int>& nums) {vector<int> dp(n…...
【补充】1-auth的使用、扩写auth的user表、django支持缓存
1 Auth的使用 1.1 扩写auth的user表 2 缓存 1 Auth的使用 # django 的一个app---》用户的登录,退出,注册。。。# 配置文件中配置:---》表会被迁移INSTALLED_APPS [django.contrib.auth,]# auth有哪些表---权限控制:-Permission&a…...

力扣-21. 合并两个有序链表-js实现
/*** Definition for singly-linked list.* function ListNode(val, next) {* this.val (valundefined ? 0 : val)* this.next (nextundefined ? null : next)* }*/ /*** param {ListNode} list1* param {ListNode} list2* return {ListNode}*/ const mergeTwoList…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...