【瑞吉外卖部分功能补充】
瑞吉外卖部分功能补充
菜品的启售和停售
在浏览器控制台点击对应功能后可以看到前端发送的请求是:http://localhost:9999/dish/status/1?ids=1413342036832100354,请求方式为POST。
接收到前端参数后,进行controller层代码补全,在DishController中添加下面的接口代码;
/*** 对菜品进行停售或者是起售* @return*/
@PostMapping("/status/{status}")
public R<String> status(@PathVariable("status") Integer status,Long ids){log.info("status:{}",status);log.info("ids:{}",ids);Dish dish = dishService.getById(ids);if (dish != null){dish.setStatus(status);dishService.updateById(dish);return R.success("开始启售");}return R.error("售卖状态设置异常");
}
菜品批量启售和批量停售
把上面对单个菜品的售卖状态的方法进行修改;
/*** 对菜品批量或者是单个 进行停售或者是起售* @return*/
@PostMapping("/status/{status}")
//这个参数这里一定记得加注解才能获取到参数,否则这里非常容易出问题
public R<String> status(@PathVariable("status") Integer status,@RequestParam List<Long> ids){//log.info("status:{}",status);//log.info("ids:{}",ids);LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper();queryWrapper.in(ids !=null,Dish::getId,ids);//根据数据进行批量查询List<Dish> list = dishService.list(queryWrapper);for (Dish dish : list) {if (dish != null){dish.setStatus(status);dishService.updateById(dish);}}return R.success("售卖状态修改成功");
}
注意:controller层的代码是不可以直接写业务的,建议把它抽离到service层,controller调用一下service的方法就行;下面的批量删除功能是抽离的,controller没有写业务代码;
菜品的批量删除
前端发来的请求:
在DishFlavor实体类中,在private Integer isDeleted;字段上加上@TableLogic注解,表示删除是逻辑删除,由mybatis-plus提供的;
在DishController中添加接口:
/*** 套餐批量删除和单个删除* @return*/
@DeleteMapping
public R<String> delete(@RequestParam("ids") List<Long> ids){//删除菜品 这里的删除是逻辑删除dishService.deleteByIds(ids);//删除菜品对应的口味 也是逻辑删除LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.in(DishFlavor::getDishId,ids);dishFlavorService.remove(queryWrapper);return R.success("菜品删除成功");
}
DishServicez中添加相关的方法:
//根据传过来的id批量或者是单个的删除菜品
void deleteByIds(List<Long> ids);
在实现类实现该方法:
/***套餐批量删除和单个删除* @param ids*/
@Override
@Transactional
public void deleteByIds(List<Long> ids) {//构造条件查询器LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();//先查询该菜品是否在售卖,如果是则抛出业务异常queryWrapper.in(ids!=null,Dish::getId,ids);List<Dish> list = this.list(queryWrapper);for (Dish dish : list) {Integer status = dish.getStatus();//如果不是在售卖,则可以删除if (status == 0){this.removeById(dish.getId());}else {//此时应该回滚,因为可能前面的删除了,但是后面的是正在售卖throw new CustomException("删除菜品中有正在售卖菜品,无法全部删除");}}}
功能测试:单个删除,批量删除,批量删除中有启售的…
测试成功!
菜品删除逻辑优化
上面写的菜品的删除功能有点小简单,下面完善一下相关的逻辑;
相关的service的注入,这里就不列举出来了,代码中使用了哪个service,你就autowire就行;
下面的代码可能会有点冗余,这里我就不进行抽离了;
/*** 菜品批量删除和单个删除* 1.判断要删除的菜品在不在售卖的套餐中,如果在那不能删除* 2.要先判断要删除的菜品是否在售卖,如果在售卖也不能删除* @return*///遇到一个小问题,添加菜品后,然后再添加套餐,但是套餐可选择添加的菜品选项是没有刚刚添加的菜品的?//原因:redis存储的数据没有过期,不知道为什么redis没有重新刷新缓存// (与DishController中的@GetMapping("/list")中的缓存设置有关,目前不知道咋配置刷新缓存。。。。。// 解决方案,把redis中的数据手动的重新加载一遍,或者是等待缓存过期后再添加相关的套餐,或者改造成使用spring catch@DeleteMappingpublic R<String> delete(@RequestParam("ids") List<Long> ids){//根据菜品id在stemeal_dish表中查出哪些套餐包含该菜品LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();setmealDishLambdaQueryWrapper.in(SetmealDish::getDishId,ids);List<SetmealDish> SetmealDishList = setmealDishService.list(setmealDishLambdaQueryWrapper);//如果菜品没有关联套餐,直接删除就行 其实下面这个逻辑可以抽离出来,这里我就不抽离了if (SetmealDishList.size() == 0){//这个deleteByIds中已经做了菜品起售不能删除的判断力dishService.deleteByIds(ids);LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.in(DishFlavor::getDishId,ids);dishFlavorService.remove(queryWrapper);return R.success("菜品删除成功");}//如果菜品有关联套餐,并且该套餐正在售卖,那么不能删除//得到与删除菜品关联的套餐idArrayList<Long> Setmeal_idList = new ArrayList<>();for (SetmealDish setmealDish : SetmealDishList) {Long setmealId = setmealDish.getSetmealId();Setmeal_idList.add(setmealId);}//查询出与删除菜品相关联的套餐LambdaQueryWrapper<Setmeal> setmealLambdaQueryWrapper = new LambdaQueryWrapper<>();setmealLambdaQueryWrapper.in(Setmeal::getId,Setmeal_idList);List<Setmeal> setmealList = setmealService.list(setmealLambdaQueryWrapper);//对拿到的所有套餐进行遍历,然后拿到套餐的售卖状态,如果有套餐正在售卖那么删除失败for (Setmeal setmeal : setmealList) {Integer status = setmeal.getStatus();if (status == 1){return R.error("删除的菜品中有关联在售套餐,删除失败!");}}//要删除的菜品关联的套餐没有在售,可以删除//这下面的代码并不一定会执行,因为如果前面的for循环中出现status == 1,那么下面的代码就不会再执行dishService.deleteByIds(ids);LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.in(DishFlavor::getDishId,ids);dishFlavorService.remove(queryWrapper);return R.success("菜品删除成功");}
套餐管理的启售,停售
前端发来的请求:
根据前面菜品模块自己实现的功能,我们可以知道,我们只需要写一个批量处理的方法就可以完成单个或者是批量套餐的启售,停售;
SetmealController中的controller层代码:
/*** 对套餐批量或者是单个 进行停售或者是起售* @return*/
@PostMapping("/status/{status}")
//这个参数这里一定记得加注解才能获取到参数,否则这里非常容易出问题
public R<String> status(@PathVariable("status") Integer status,@RequestParam List<Long> ids){setmealService.updateSetmealStatusById(status,ids);return R.success("售卖状态修改成功");
}
SetmealService中添加下面方法:
/*** 根据套餐id修改售卖状态* @param status* @param ids*/
void updateSetmealStatusById(Integer status,List<Long> ids);
该方法的实现
/*** 根据套餐id修改售卖状态* @param status* @param ids*/
@Override
public void updateSetmealStatusById(Integer status, List<Long> ids) {LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper();queryWrapper.in(ids !=null,Setmeal::getId,ids);List<Setmeal> list = this.list(queryWrapper);for (Setmeal setmeal : list) {if (setmeal != null){setmeal.setStatus(status);this.updateById(setmeal);}}
}
功能测试成功:
相关文章:

【瑞吉外卖部分功能补充】
瑞吉外卖部分功能补充 菜品的启售和停售 在浏览器控制台点击对应功能后可以看到前端发送的请求是:http://localhost:9999/dish/status/1?ids1413342036832100354,请求方式为POST。 接收到前端参数后,进行controller层代码补全,…...

react的setState做了什么
1、为什么需要setState setState的作用是帮助我们更改数据的同时并且通知视图进行渲染。因为React并不会绑定视图和state,需要我们手动去更新视图。 2、setState什么时候是同步的,什么时候是异步的 setState这个方法在调用的时候是同步的,…...

ubuntu18.04 RTX3060 rangnet++训练 bonnetal语义分割
代码链接: https://github.com/PRBonn/lidar-bonnetal 安装anaconda环境为 CUDA 11.0(11.1也可以) anaconda环境如下 numpy1.17.2 torchvision0.2.2 matplotlib2.2.3 tensorflow1.13.1 scipy0.19.1 pytorch1.7.1 vispy0.5.3 opencv_python…...

Linux:权限是什么
本篇文章来简单介绍一下Linux操作系统中权限的基本概念和一些操作方法,对Linux权限有一个基本的了解,希望对大家学习Linux有所帮助。 目录 1.权限的概念 2.Linux权限管理 2.1 文件访问者的分类 2.2 文件类型与访问权限(事物属性ÿ…...
uni-app yrkDataPicker 日期和时间选择控件
uni-app 选择日期时间控件有 2 月份有 31 天的问题,一直没有修复,uni-calendar 苹果有选择年份和月份后无法显示问题。自己写了一个,只支持 H5 和微信小程序,其他没有试过。 <template><view class"yrk-data-picke…...

PAM从入门到精通(十九)
接前一篇文章:PAM从入门到精通(十八) 本文参考: 《The Linux-PAM Application Developers Guide》 PAM 的应用开发和内部实现源码分析 先再来重温一下PAM系统架构: 更加形象的形式: 六、整体流程示例 2.…...

apache httpd 多后缀解析漏洞
形成原因 Apache HTTPD 支持一个文件拥有多个后缀,并为不同后缀执行不同的指令 在有多个后缀的情况下,只要一个文件含有.php后缀的文件即将被识别成PHP文件,没必要是最后一个后缀。利用这个特性,将会造成一个可以绕过上传白名单…...
Flutter ☞ 数据类型
数值类型 int、double、num int 整型,取值通常在 -253 ~ 253 之间 int class double 64-bt(双精度)浮点数,符合 IEEE 754 标准。 double class num 数值类型的基类,int 和 double 都继承自num。 num class 数值转换 // String -> …...

MyBatis-Plus 实战教程一
这里写目录标题 简介快速上手数据库建立创建实体类修改参数引入依赖测试常见注解介绍TableNameTableIdTableField 常见配置仓库地址 简介 MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,…...

闭包(函数)
把内部函数通过return扔出去 必要条件...

Go包介绍与初始化:搞清Go程序的执行次序
Go包介绍与初始化:搞清Go程序的执行次序 文章目录 Go包介绍与初始化:搞清Go程序的执行次序一、main.main 函数:Go 应用的入口函数1.1 main.main 函数1.2 main.main 函数特点 二、包介绍2.1 包介绍与声明2.2 非 main包的 main 函数2.3 包的命名…...

Python教程(15)——Python流程控制语句详解
目录 if语句else if语句for循环遍历类型range关键字 while循环break语句continue语句 Python流程控制是Python编程中非常重要的一部分,它用于控制程序的执行流程。Python提供了多种流程控制语句,包括if语句、while循环、for循环、break和continue语句等。…...

JavaScript基础知识16——分支语句
哈喽,大家好,我是雷工。 今天学习JavaScript基础知识的分支语句,以下为学习笔记。 1、程序三大流程控制语句 ○写几句就从上往下执行几句,这种叫做顺序结构; ○有时要根据条件选择执行代码,这种叫分支结构…...

web开发初级工程师学习笔记
web开发初级工程师学习笔记 前端开发工具实验1 VS Code 初体验介绍 前端开发工具 实验1 VS Code 初体验 介绍 VS Code 环境提供的是一个可以在浏览器中使用原生 VS Code 编辑代码的程序。在该环境中,你可以使用到与本地安装近乎一致的 VS Code 程序来编辑代码文件…...

Linux下Samba服务安装及启用全攻略
Linux下Samba服务安装及启用全攻略 前言一、安装SSH Server二、安装Samba Server1.安装net-tool2.建立账号的samba3.windows通过Samba与linux共享文件4.使用远程工具登录Linux 总结 前言 提示:本文详解了在Linux系统下如何安装和启用Samba服务,涵盖了从…...

【C++】引用’‘的深入解析
💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …...
java链式编程对象序列化问题
在使用 openfeign 进行服务之间数据传输时发现了一个问题,数据在下游正常处理,响应到调用端数据也读取到了,但是就是 jackson 转对象序列化时出了问题,异常如下 Failed to complete request: feign.codec.DecodeException: Type d…...
关于Redis(Redisson)超时问题的分析
概述 生产环境中流量高峰期会出现短时间的redis异常,主要报错如下: Redis server response timeoutRedisTimeoutException: Command execution timeout for command: (PING)Command still hasn’t been written into connection! 根据redisson官方所述…...

Redis 主从复制,哨兵,集群——(2)哨兵篇
目录 1. Redis 哨兵是什么? 2. Redis 哨兵有什么用? 2.1 主动监控 2.2 消息通知 2.3 故障转移 2.4 配置中心 3. Redis 哨兵数量配备要求 4. 哨兵配置文件详解 5. quorum 投票数详解 5.1 quorum 的含义 5.2 网络抖动导致主观下线 5.3 quorum …...
C++入门笔记分享
有道云笔记...

大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...

uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...