瑞吉外卖项目学习笔记(七)新增菜品、(批量)删除菜品
瑞吉外卖项目学习笔记(一)准备工作、员工登录功能实现
瑞吉外卖项目学习笔记(二)Swagger、logback、表单校验和参数打印功能的实现
瑞吉外卖项目学习笔记(三)过滤器实现登录校验、添加员工、分页查询员工信息
瑞吉外卖项目学习笔记(四)@TableField(fill = FieldFill.INSERT)公共字段填充、启用/禁用/修改员工信息
瑞吉外卖项目学习笔记(五)菜品/套餐分类的增删改查
瑞吉外卖项目学习笔记(六)分页查询菜品列表、实现图片上传和下载
文章目录
- 9 菜品管理
- 9.5 新增菜品
- 9.5.1 加载菜品分类
- 9.5.2 保存口味做法配置
- 9.5.3 新增菜品具体实现
- 9.6 (批量)删除菜品
- 9.6.1 需求分析
- 9.6.2 具体实现
9 菜品管理
9.5 新增菜品
9.5.1 加载菜品分类
在“新增菜品”页面,菜品分类是一个下拉框,因此进入该页面后需要向后端发起查询请求。
这里可以直接调用菜品/套餐分类的分页查询接口,参数要设置成?page=1&pageSize=999999&type=1,表示查询第1页,该页显示999999条记录,相当于查出全部;type=1表示查询的是菜品分类。

9.5.2 保存口味做法配置
由t_dish的表结构可知,“新增菜品”页面的口味做法配置并不保存在t_dish表。所以我们新建一个菜品口味关系表t_dish_flavor表来单独保存。
- 1)在数据库新建菜品口味关系表
t_dish_flavor
DROP TABLE IF EXISTS `t_dish_flavor`;
CREATE TABLE `t_dish_flavor` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',`dish_id` bigint(20) NOT NULL COMMENT '菜品',`name` varchar(64) COLLATE utf8_bin NOT NULL COMMENT '口味名称',`value` varchar(500) COLLATE utf8_bin DEFAULT NULL COMMENT '口味数据list',`create_time` datetime NOT NULL COMMENT '创建时间',`update_time` datetime NOT NULL COMMENT '更新时间',`create_user` bigint(20) NOT NULL COMMENT '创建人',`update_user` bigint(20) NOT NULL COMMENT '修改人',`is_deleted` int(11) NOT NULL DEFAULT '0' COMMENT '是否删除',PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='菜品口味关系表';
- 2)使用MyBatisPlus插件生成代码:

- 3)给
DishFlavor实体类的公共字段添加注解:
// com.itweid.takeout.entity.DishFlavor@ApiModelProperty(value = "创建时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;@ApiModelProperty(value = "更新时间")
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;@ApiModelProperty(value = "创建人")
@TableField(fill = FieldFill.INSERT)
private Long createUser;@ApiModelProperty(value = "修改人")
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateUser;
9.5.3 新增菜品具体实现
| 功能 | 请求方法 | 请求路径 |
|---|---|---|
| 新增菜品 | POST | /dish/add |
该接口的入参较为复杂,下面是一个示例:
{"name":"辣子鸡", //菜品名称"price":14.99, //菜品价格"image":"e7cff7e7-4f63-4e3a-8001-6866e27f82d6.png", //菜品图片"description":"辣子鸡真的好吃!!", //菜品描述"categoryId":"1397844263642378242", //菜品分类ID"flavors":[ //口味做法配置{"name":"甜味","value":"[\"无糖\",\"少糖\",\"半糖\"\"多糖\",\"全糖\"]","showOption":false},{"name":"温度","value":"[\"热饮\",\"常温\",\"去冰\",\"少冰\",\"多冰\"]","showOption":false},{"name":"忌口","value":"[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]","showOption":false},{"name":"辣度","value":"[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]","showOption":false}]
}
- 1)改造
DishQuery类,添加以上参数,并做参数校验
@Data
@EqualsAndHashCode(callSuper=false)
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "DishQuery对象", description = "菜品查询对象")
public class DishQuery extends BaseQuery {@ApiModelProperty(value = "菜品名称")@NotBlank(groups = Add.class, message = "菜品名称不能为空")private String name;@ApiModelProperty(value = "菜品分类ID")@NotBlank(groups = Add.class, message = "菜品分类不能为空")private String categoryId;@ApiModelProperty(value = "菜品价格")@NotNull(groups = Add.class, message = "菜品价格不能为空")private BigDecimal price;@ApiModelProperty(value = "菜品图片")@NotNull(groups = Add.class, message = "菜品图片不能为空")private String image;@ApiModelProperty(value = "菜品描述")private String description;@ApiModelProperty(value = "口味做法配置")private DishFlavor[] flavors;}
- 2)在
DishController类创建add方法,并添加参数校验
@ApiOperation("新增菜品")
@PostMapping("/add")
public BaseResult add(@RequestBody @Validated(Add.class) DishQuery dishQuery) {return dishService.addDish(dishQuery);
}
- 3)在
DishServiceImpl类具体实现addDish方法
// com.itweid.takeout.service.impl.DishServiceImpl@Override
public BaseResult addDish(DishQuery dishQuery) {// 1 菜品名称不能重复if(lambdaQuery().eq(Dish::getName, dishQuery.getName()).exists()) {return BaseResult.error(ErrorCode.DISH_EXIST);}// 2 新增菜品Dish dish = new Dish();dish.setName(dishQuery.getName());dish.setCategoryId(Long.valueOf(dishQuery.getCategoryId()));dish.setPrice(dishQuery.getPrice());dish.setImage(dishQuery.getImage());dish.setDescription(dishQuery.getDescription());// 随机指定商品码dish.setCode(UUID.randomUUID().toString());save(dish);// 3 新增菜品口味配置DishFlavor[] flavors = dishQuery.getFlavors();if(flavors != null && flavors.length > 0) {for(DishFlavor f : flavors) {f.setDishId(dish.getId());Db.save(f);}}return BaseResult.success();
}
- 4)重启服务,测试新增菜品功能


- 5)完善“菜品分类”的显示
在Dish实体类中增加categoryName字段:
// com.itweid.takeout.entity.Dish@ApiModelProperty(value = "菜品分类名称")
@TableField(exist = false)
private String categoryName;
改造DishServiceImpl类的pageQueryDish方法,处理菜品分类名称字段:
// com.itweid.takeout.service.impl.DishServiceImpl@Override
public BaseResult<Page<Dish>> pageQueryDish(DishQuery dishQuery) {Page<Dish> page = new Page<>(dishQuery.getPage(), dishQuery.getPageSize());lambdaQuery().like(StringUtils.isNoneBlank(dishQuery.getName()), Dish::getName, dishQuery.getName()).page(page);if(page.getTotal() > 0){for (Dish record : page.getRecords()) {// 处理菜品分类Category category = Db.getById(record.getCategoryId(), Category.class);if(category != null){record.setCategoryName(category.getName());}}}return BaseResult.success(page);
}
重启服务,测试菜品分类是否显示:

9.6 (批量)删除菜品
9.6.1 需求分析
在“菜品管理”页面,可以直接删除一个菜品,也可以选择多个菜品后批量删除:

| 功能 | 请求方法 | 请求路径 | 请求参数 |
|---|---|---|---|
| 新增菜品 | DELETE | /dish/delete | {“ids”:“1,2,3”} |
9.6.2 具体实现
- 1)在
DishController类中添加delete方法,并添加参数校验
// com.itweid.takeout.controller.DishController@ApiOperation("(批量)删除菜品")
@DeleteMapping("/delete")
public BaseResult delete(@NotBlank(message = "待删除菜品ID不能为空") String ids) {return dishService.deleteDish(ids);
}
- 2)在
DishServiceImpl中具体实现deleteDish方法
// com.itweid.takeout.service.impl.DishServiceImpl@Value("${dir.upload}")
private String uploadDir;@Override
public BaseResult deleteDish(String ids) {String[] idArray = ids.split(",");for (String id : idArray) {log.info("delete id = {}", id);// 先查询出菜品Dish dish = getById(id);if(dish != null) {// 删除菜品removeById(dish.getId());// 删除菜品口味配置Db.lambdaUpdate(DishFlavor.class).eq(DishFlavor::getDishId, dish.getId()).remove();// 删除菜品图片File file = new File(uploadDir + dish.getImage());if(file.exists()) {log.info("delete file = {} => {}", file.getAbsolutePath(), file.delete());}}}return BaseResult.success();
}
- 3)重启服务,测试删除菜品功能

同样由于精度问题导致删除失败。我们只需要给Dish实体类的id字段添加一个@JsonSerialize注解:
// com.itweid.takeout.entity.Dish@ApiModelProperty(value = "ID")
@TableId(value = "id", type = IdType.AUTO)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
- 4)重启服务,再次测试删除菜品功能


…
本节完,更多内容查阅:瑞吉外卖项目实战
相关文章:
瑞吉外卖项目学习笔记(七)新增菜品、(批量)删除菜品
瑞吉外卖项目学习笔记(一)准备工作、员工登录功能实现 瑞吉外卖项目学习笔记(二)Swagger、logback、表单校验和参数打印功能的实现 瑞吉外卖项目学习笔记(三)过滤器实现登录校验、添加员工、分页查询员工信息 瑞吉外卖项目学习笔记(四)TableField(fill FieldFill.INSERT)公共字…...
es快速扫描
介绍 Elasticsearch简称es,一款开源的分布式全文检索引擎 可组建一套上百台的服务器集群,处理PB级别数据 可满足近实时的存储和检索 倒排索引 跟正排索引相对,正排索引是根据id进行索引,所以查询效率非常高,但是模糊…...
前端对页面数据进行缓存
页面录入信息,退出且未提交状态下,前端对页面数据进行存储 前端做缓存,一般放在local、session和cookies里面,但是都有大小限制,如果页面东西多,比如有上传的图片、视频,浏览器会抛出一个Quota…...
leetCode322.零钱兑换
题目: 给你一个整数数组coins,表示不同面额的硬币;以及一个整数amount,表示总金额。 计算并返回可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回-1。 你可以认为每种硬币的数量是无限的。 示例1࿱…...
jsp-servlet开发
STS中开发步骤 建普通jsp项目过程 1.建项目(非Maven项目) new----project----other----Web----Dynamic Web Project 2.下载包放到LIB目录中,如果是Maven项目可以自动导包(pom.xml中设置好) 3.设置工作空间,网页…...
从零玩转CanMV-K230(7)-I2C例程
文章目录 前言一、IIC API二、示例总结 前言 K230内部包含5个I2C硬件模块,支持标准100kb/s,快速400kb/s模式,高速模式3.4Mb/s。 通道输出IO配置参考IOMUX模块。 一、IIC API I2C类位于machine模块下。 i2c I2C(id, freq100000) 【参数】…...
n阶Legendre多项式正交性的证明
前言 在《n次Legendre(勒让德)多项式在区间(-1, 1)上根的分布及证明》这篇文章中,我们阐述了Legendre多项式在 [ − 1 , 1 ] [-1,1] [−1,1]上的根分布情况并给出了证明。本文将证明Legendre多项式在 [ − 1 , 1 ] [-1,1] [−1,1]上的正交性质。 正交多项式的定义…...
HarmonyOS NEXT - Dialog 和完全自定义弹框
demo 地址: https://github.com/iotjin/JhHarmonyDemo 组件对应代码实现地址 代码不定时更新,请前往github查看最新代码 在demo中这些组件和工具类都通过module实现了,具体可以参考HarmonyOS NEXT - 通过 module 模块化引用公共组件和utils HarmonyOS NE…...
内容与资讯API优质清单
作为开发者,拥有一套API合集是必不可少的。这个开发者必备的API合集汇集了各种实用的API资源,为你的开发工作提供了强大的支持!无论你是在构建网站、开发应用还是进行数据分析,这个合集都能满足你的需求。你可以通过这些免费API获…...
开源 JS PDF 库比较
原文查看:开源JavaScript PDF Library对比 对于需要高性能、复杂功能或强大支持处理复杂 PDF 的项目,建议选择商业 PDF 库, 如ComPDFKit for Web。但是,如果您的目标只是在 Web 应用程序中显示 PDF,则可以使用几个可靠的开源…...
AnaPico信号源在通信测试中的应用案例
AnaPico信号源在通信测试中的应用案例广泛,涉及多种通信技术和测试需求。以下是一些具体的应用实例: 1. APPH系列信号源分析仪(相位噪声分析仪) APPH系列是一款高性能相位噪声分析仪和VCO测试仪,其不同型号的频率范围…...
《智启新材:人工智能重塑分子结构设计蓝图》
在当今科技飞速发展的时代,新材料的研发宛如一场激烈的竞赛,而人工智能(AI)作为一匹黑马,正以前所未有的速度和力量驰骋于这片赛场,为新材料的分子结构设计带来了革命性的突破,成为推动行业发展…...
进阶岛-L2G5000
茴香豆:企业级知识库问答工具 茴香豆本地标准版搭建 环境搭建 安装茴香豆 知识库创建 测试知识助手 Gradio UI 界面测试...
单点登录平台Casdoor搭建与使用,集成gitlab同步创建删除账号
一,简介 一般来说,公司有很多系统使用,为了实现统一的用户名管理和登录所有系统(如 GitLab、Harbor 等),并在员工离职时只需删除一个主账号即可实现权限清除,可以采用 单点登录 (SSO) 和 集中式…...
PaddlePaddle飞桨Linux系统Docker版安装
PaddlePaddle飞桨Linux系统Docker版安装 最近学习和了解PP飞桨,一切从安装开始。官网的安装教程很详细: https://www.paddlepaddle.org.cn/install/quick?docurl/documentation/docs/zh/install/docker/linux-docker.html 记录我在安装过程中遇到的问题…...
一款基于.NET开发的简易高效的文件转换器
前言 今天大姚给大家分享一款基于.NET开发的免费(GPL-3.0 license)、简易、高效的文件转换器,允许用户通过Windows资源管理器的上下文菜单来转换和压缩一个或多个文件:FileConverter。 使用技术栈 ffmpeg:作为文件转换…...
Spring Boot教程之三十一:入门 Web
Spring Boot – 入门 Web 如今,大多数应用程序都需要模型-视图-控制器(MVC) 架构来满足各种需求,例如处理用户数据、提高应用程序效率、为应用程序提供动态特性。它主要用于构建桌面图形用户界面 (GUI),但现在越来越流行用于构建基于 Web 的…...
青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试
青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试 一、单元测试(Unit Testing)二、集成测试(Integration Testing)三、区别四、Go Web单元测试使用testing包使用testify框架使用GoConvey框架 五、应用示例步骤 1: 创建HTT…...
概率论 期末 笔记
第一章 随机事件及其概率 利用“四大公式”求事件概率 全概率公式与贝叶斯公式 伯努利概型求概率 习题 推导 一维随机变量及其分布 离散型随机变量(R.V)求分布律 利用常见离散型分布求概率 连续型R.V相关计算 利用常见连续型分布的计算 均匀分布 正态…...
Typesense:开源的高速搜索引擎
在当今数据驱动的世界中,高效、快速且智能的搜索能力是任何应用程序和网站成功的关键因素之一。无论是电商平台、内容管理系统还是社交媒体,用户都希望能够迅速找到所需信息。Typesense,作为一款优秀的开源搜索引擎,旨在通过其卓越…...
手把手复现DiffusionDet:基于PyTorch从论文到代码的完整实践指南(含COCO数据集)
从零实现DiffusionDet:基于PyTorch的扩散式目标检测实战指南 1. 环境配置与工具准备 在开始DiffusionDet项目之前,确保你的开发环境满足以下要求。我们将使用PyTorch作为主要框架,配合CUDA加速计算。 硬件建议: GPU࿱…...
OpenCode快速上手:3步配置本地AI编程环境,告别复杂安装
OpenCode快速上手:3步配置本地AI编程环境,告别复杂安装 1. 引言:为什么选择OpenCode? 在AI编程助手领域,OpenCode以其独特的终端优先设计和隐私安全特性脱颖而出。作为一个2024年开源的Go语言框架,它能够…...
3分钟快速优化Windows性能:Mem Reduct系统优化工具终极指南
3分钟快速优化Windows性能:Mem Reduct系统优化工具终极指南 【免费下载链接】memreduct Lightweight real-time memory management application to monitor and clean system memory on your computer. 项目地址: https://gitcode.com/gh_mirrors/me/memreduct …...
别再写错Verilog三态门了!一个assign语句搞定FPGA双向IO(附仿真避坑指南)
Verilog三态门实战指南:从代码误区到仿真验证 双向IO设计是FPGA开发中绕不开的经典问题,而三态门作为实现双向传输的核心元件,其代码写法看似简单却暗藏玄机。不少工程师在项目后期才发现三态门行为异常,仿真结果与预期不符&#…...
提升图像识别效率:C#整合YOLO26的深度学习应用实战
在工业质检、安防监控、智能视觉巡检等场景中,图像识别的效率与精度是决定落地价值的核心指标。YOLO26作为YOLO系列的新一代轻量化模型,凭借更优的骨干网络设计、Anchor-Free检测头和低精度推理支持,成为C#项目实现高性能图像识别的首选方案。不同于Python生态的便捷性,C#在…...
编写程序实现智能厨房刀具消毒,完成后自动提示,保障饮食安全。
📝 项目概述:Smart Knife Sterilizer Slogan: 代码守护舌尖安全,紫外精准消杀;让每一刀都切得安心,吃得放心。 一、 实际应用场景描述 (Context & Scenario) * 场景:现代家庭厨房。菜刀、水果刀在使用后…...
Django-unicorn 性能优化技巧:10个提升应用响应速度的终极指南
Django-unicorn 性能优化技巧:10个提升应用响应速度的终极指南 【免费下载链接】django-unicorn The magical reactive component framework for Django ✨ 项目地址: https://gitcode.com/gh_mirrors/dj/django-unicorn Django-unicorn 是一个神奇的响应式组…...
Applicative Functor应用指南:mostly-adequate-guide-chinese中的瓶中之船与协调激励
Applicative Functor应用指南:mostly-adequate-guide-chinese中的瓶中之船与协调激励 【免费下载链接】mostly-adequate-guide-chinese 函数式编程指南中文版 项目地址: https://gitcode.com/gh_mirrors/mo/mostly-adequate-guide-chinese 在函数式编程的世界…...
YOLO26镜像实战案例分享:基于自定义数据集的训练与评估
YOLO26镜像实战案例分享:基于自定义数据集的训练与评估 在计算机视觉领域,目标检测一直是核心且应用广泛的任务。从安防监控到自动驾驶,从工业质检到医疗影像,快速准确地识别图像中的物体是许多智能系统的基石。YOLO系列模型以其…...
高性能客服系统技术内幕:通过 SpinWait 自旋等待结构体提升高频消息分发性能舶
1. 智能软件工程的范式转移:从库集成到原生框架演进 在生成式人工智能(Generative AI)从单纯的文本生成向具备自主规划与执行能力的“代理化(Agentic)”系统跨越的过程中,.NET 生态系统正在经历一场自该平台…...
