瑞吉外卖项目学习笔记(七)新增菜品、(批量)删除菜品

瑞吉外卖项目学习笔记(一)准备工作、员工登录功能实现
瑞吉外卖项目学习笔记(二)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)重启服务,再次测试删除菜品功能

本节完,更多内容查阅:瑞吉外卖项目实战

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

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

相关文章

TCP/IP 模型中,网络层对 IP 地址的分配与路由选择

TCP/IP 模型中&#xff0c;网络层对 IP 地址的分配与路由选择 一. IP 地址的分配1.1 IP 地址的结构与分类1.2 IP 地址的分配方式 二. 路由选择2.3 路由协议2.4 路由表的结构2.5 路由选择的算法2.6 默认路由与静态路由 三. 网络层的 IP 地址分配与路由选择总结 前言 这是我在这个…

WebRTC搭建与应用(五)-Coturn踩坑记

WebRTC搭建与应用(五)-Coturn踩坑记 近期由于项目需要在研究前端WebGL渲染转为云渲染&#xff0c;借此机会对WebRTC等有了初步了解&#xff0c;在此记录一下&#xff0c;以防遗忘。 第五章 WebRTC搭建与应用(五)-Coturn踩坑记 文章目录 WebRTC搭建与应用(五)-Coturn踩坑记前…

亚信安全举办“判大势 悟思想 强实践”主题党日活动

为深入学习和贯彻党的二十届三中全会精神&#xff0c;近日&#xff0c;亚信安全举办了 “学习贯彻党的二十届三中全会精神——‘判大势 悟思想 强实践’党日活动”&#xff0c;并取得圆满成功。 本次活动特邀南京市委宣讲团成员、南京市委党校市情研究中心主任王辉龙教授出席。…

EsChatPro 接入国内 DeepSeek 大模型

EsChatPro 接入国内 DeepSeek 大模型 前言 上一篇文章 我们讲了 EsChatPro 如何在本地安装运行&#xff0c;接下来给大家带来接入 deepseek 大模型的教程&#xff0c;实现 AI对话 功能 详见&#xff1a;EsChatPro本地开发运行指南 前置准备 首先我们打开 deepseek 的官网&…

Linux挖矿程序排查

一、背景 我们收到一个阿里云安全告警&#xff0c;内容是服务器可能存在挖矿程序。 二、杀死挖矿程序 2.1 找到可疑服务器进程 #1.输入top命令&#xff0c;输入shift P会按照cpu的使用率大小从大到小进行排序&#xff0c;cpu使用率高的就是可疑进程。 top #2.查看运行该进程…

flask基础

from flask import Flask, requestapp Flask(__name__)# app.route(/) # def hello_world(): # put applications code here # return Hello World!app.route(/) # 路由 当用户访问特定 URL 时&#xff0c;Flask 会调用对应的视图函数来处理请求 def index():return …

OpenCV学习——图像融合

import cv2 as cv import cv2 as cvbg cv.imread("test_images/background.jpg", cv.IMREAD_COLOR) fg cv.imread("test_images/forground.png", cv.IMREAD_COLOR)# 打印图片尺寸 print(bg.shape) print(fg.shape)resize_size (1200, 800)bg cv.resize…

Spring Boot 项目创建

创建一个新项目&#xff1a; 打开 Spring Initializr 网址&#xff1a;https://start.spring.io/ &#xff0c;然后创建一个新项目&#xff1a; springboot3.3.5_jdk17&#xff1a; Project&#xff08;Maven&#xff09;编程语言&#xff08;Java 17&#xff09;Spring Boo…

GTID下复制问题和解决

环境介绍 数据库1主2从&#xff0c;mysql版本是v5.19 表结构 一、主库新增记录&#xff0c;从库提示主键冲突 模拟故障 1&#xff0c; master上关闭 sql_log_bin,删除id 103 后打开 2&#xff0c; 确认此时从库有id103,主库没有 3&#xff0c; master insert id103 主从异常…

C语言初阶【13】——打印一个数的每一位(递归和非递归实现)

1. 题目 打印一个数的每一位 2.分析 首先先实现非递归方式&#xff0c; 以123为例。我们要获取它的每一位&#xff0c; 获取个位数&#xff1a;123 %10 3 获取十位数&#xff1a;123/10 12 之后在 12%10 2&#xff1b; 获取百位数&#xff1a;12/10 1 之后再1%10 1&#x…

webrtc学习----前端推流拉流,局域网socket版,一对多

提示&#xff1a;局域网socket版&#xff0c;一对多 文章目录 [TOC](文章目录) 前言一、教程二、webrtc工作流程三、推流端四、拉流五、socket服务六、效果七、备注总结 前言 WebRTC&#xff08;Web Real-Time Communication&#xff09;是一种实时通讯技术&#xff0c;允许网…

深入探讨 Go 中的高级表单验证与翻译:Gin 与 Validator 的实践之道20241223

深入探讨 Go 中的高级表单验证与翻译&#xff1a;Gin 与 Validator 的实践之道 在现代后端开发中&#xff0c;表单验证是保证数据完整性和服务稳定性的核心环节。如何优雅、高效地实现表单验证&#xff0c;同时提供人性化的错误提示&#xff0c;是每位开发者的必修课。在本文中…

单机游戏《野狗子》游戏运行时提示dbghelp.dll缺失是什么原因?dbghelp.dll缺失要怎么解决?

《野狗子》游戏运行时提示dbghelp.dll缺失&#xff1a;原因与解决方案 在畅游《野狗子》这款引人入胜的游戏世界时&#xff0c;突然遭遇“dbghelp.dll缺失”的错误提示&#xff0c;无疑会给玩家的探险之旅蒙上一层阴影。作为一名深耕软件开发领域的从业者&#xff0c;我深知此…

Unity复刻胡闹厨房复盘 模块一 新输入系统订阅链与重绑定

本文仅作学习交流&#xff0c;不做任何商业用途 郑重感谢siki老师的汉化教程与代码猴的免费教程以及搬运烤肉的小伙伴 版本&#xff1a;Unity6 模板&#xff1a;3D 核心 渲染管线&#xff1a;URP ------------------------------…

Flutter 异步编程简述

1、isolate 机制 1.1 基本使用 Dart 是基于单线程模型的语言。但是在开发当中我们经常会进行耗时操作比如网络请求&#xff0c;这种耗时操作会堵塞我们的代码。因此 Dart 也有并发机制 —— isolate。APP 的启动入口main函数就是一个类似 Android 主线程的一个主 isolate。与…

一键打断线(根据相交点打断)——CAD c# 二次开发

多条相交线根据交点一键打断&#xff0c;如下图&#xff1a; 部分代码如下: finally namespace IFoxDemo; public class Class1 {[CommandMethod("ddx")]public static void Demo(){//"ifox可以了".Print();Database db HostApplicationServices.Workin…

Confluent Cloud Kafka 可观测性最佳实践

Confluent Cloud 介绍 Confluent Cloud 是一个完全托管的 Apache Kafka 服务&#xff0c;提供高可用性和可扩展性&#xff0c;旨在简化数据流处理和实时数据集成。用户可以轻松创建和管理 Kafka 集群&#xff0c;而无需担心基础设施的维护和管理。Confluent Cloud 支持多种数据…

【C++】B2066救援题目分析和解决讲解

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af; 题目&#x1f4af; 题目分析每个屋顶计算的元素 &#x1f4af; 思路解析1. **读取输入**2. **计算屋顶时间**3. **结果精确取整** &#x1f4af; 完整解决代码&#x1f4a…

WPS工具栏灰色怎么办

WPS离线不登录&#xff0c;开启工具栏等相关功能 当你在使用WPS的过程中&#xff0c;若因网络问题或其他特殊原因&#xff0c;导致无法登录使用WPS时&#xff0c;可根据以下步骤开启离线兼容模式&#xff0c;开启此模式后&#xff0c;可在未登录的状态下&#xff0c;激活并使用…

反射探针.

一、在unity场景中如何添加反射探针&#xff1f; 可以先添加一个空对象&#xff0c;在空对象的上方添加反射探针组件&#xff08;Reflection Probe&#xff09; 反射探针的类型有&#xff1a;Baked、Custom、Realtime 其中“Baked”反射探针类型&#xff0c;可以将场景中的静态…