目录

1、文件上传和下载

1.1、文件上传介绍

1.2、文件下载介绍

1.3、文件上传实现

1.3.1、分析

1.3.2、代码

1.4、文件下载实现

2、新增菜品

2.1、分析

2.1.1、需求分析

2.1.2、数据模型给

2.1.3、准备工作

2.1.4、页面与服务端的交互过程

2.1.5、前端代码分析

2.2、代码

2.2.1、获取菜品分类信息

2.2.2、DishDTO

2.2.3、保存页面发来的数据

3、菜品信息分页查询

3.1、分析

3.1.1、需求分析

3.1.2、页面与服务端的交互过程

3.2、代码

4、修改菜品

4.1、分析

4.1.1、需求分析

4.1.2、页面与服务端的交互过程

4.2、代码

4.2.1、菜品信息回显

4.2.2、修改商品实现

5、菜品停售与起售(批量)

5.1、分析

5.2、代码

6、(批量)删除

6.1、分析

6.2、代码

6.2.1、添加逻辑删除注解


1、文件上传和下载

1.1、文件上传介绍

1.2、文件下载介绍

1.3、文件上传实现

1.3.1、分析

将 upload.html 放在 backend/page/demo 目录下,上传图片的接口如下

1.3.2、代码

① 将文件上传和下载页面取消检查登录:在 LoginCheckFilter 中将对应路径加入免查数组

        // 定义不需要处理的请求路径String[] urls = new String[]{"/employee/login",  // 登录请求"/employee/logout",  // 登出请求"/backend/**",       // 前端资源"/front/**",       // 前端资源"/common/**"        // 文件上传和下载//"/employee/page"       // 前端资源};

② 在 application.yml 中设置文件存放位置

reggie:path: C:\Users\zhang\Desktop\2\

③ 创建 CommonController 处理文件上传请求

package com.itheima.reggie.controller;import com.itheima.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.IOException;
import java.util.UUID;/*** @Author zhang* @Date 2022/9/2 - 21:54* @Version 1.0*/
// 文件上传和下载
@RestController
@Slf4j
@RequestMapping("/common")
public class CommonController {@Value("${reggie.path}")private String basePath;/*** 文件上传* @param file 这个参数名字必须与前端保持一直* @return*/@PostMapping("/upload")public R<String> upload(MultipartFile file){//log.info(file.toString());// file是一个临时文件,需要转存到指定位置,否则本次请求完后临时文件会删除// 原始文件名String originalFilename = file.getOriginalFilename();// 获取原始文件的后缀名String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));// 使用UUID生成文件名String fileName = UUID.randomUUID().toString() + suffix;// 创建一个目录对象File dir = new File(basePath);if(!dir.exists()){// 目录不存在,需要创建dir.mkdirs();}try {// 将临时文件转存到指定位置file.transferTo(new File(basePath + fileName));} catch (IOException e) {e.printStackTrace();}return R.success(fileName);}}

1.4、文件下载实现

前端在文件上传成功后,通过 handleAvatarSuccess 方法使自定义的参数 imageUrl 存储服务器保存图片的路径,再通过 imageUrl 发送请求下载文件

    /*** 文件下载* @param name* @param response*/@GetMapping("/download")public void download(String name,HttpServletResponse response){try {// 通过输入流读取文件内容FileInputStream fileInputStream = new FileInputStream(new File(basePath + name));// 通过输出流将文件写回浏览器ServletOutputStream outputStream = response.getOutputStream();response.setContentType("image/jpeg");  // 设置文件格式byte[] bytes = new byte[1024];int len = 0;while((len = fileInputStream.read(bytes)) != -1){outputStream.write(bytes, 0, len);outputStream.flush();}// 关闭资源outputStream.close();fileInputStream.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}

2、新增菜品

2.1、分析

2.1.1、需求分析

2.1.2、数据模型给

dish 表

dish_flavor 表

2.1.3、准备工作

2.1.4、页面与服务端的交互过程

获取菜品分类数据:

图片上传与下载与上面使用的接口相同,所以已经实现

保存菜品信息:

2.1.5、前端代码分析

在 created 生命周期,先通过 getDishList 方法获取菜品分类信息并存储到自定义数据 dishList

2.2、代码

2.2.1、获取菜品分类信息

在 CategoryController 中添加方法

    /*** 根据条件查询分类数据* @param category* @return*/@GetMapping("list")public R<List<Category>> list(Category category){LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(category.getType() != null, Category::getType, category.getType());queryWrapper.orderByAsc(Category::getSort).orderByDesc(Category::getUpdateTime);List<Category> categoryList = categoryService.list(queryWrapper);return R.success(categoryList);}

2.2.2、DishDTO

DTO,全称为 Data Transfer Object,即数据传输对象,一般用于展示层与服务层之间的数据传输。

由于保存菜品信息时,页面发送了 flavors 信息,而在 Dish 中没有该属性,无法匹配,所以导入 DishDto(位置:资料/dto) ,用于封装页面提交的数据

@Data
public class DishDto extends Dish {private List<DishFlavor> flavors = new ArrayList<>();private String categoryName;private Integer copies;
}

2.2.3、保存页面发来的数据

页面发来的数据不仅有菜品信息,还有对应的口味信息

① 在 DishSerivce 中添加同时存储两种信息的方法

public interface DishSerivce extends IService<Dish> {// 新增菜品,同时插入菜品对应的口味数据,需要操作两张表:dish、dish_flavorpublic void saveWithFlavor(DishDto dishDto);}

② 在 DishServiceImpl 添加实现方法

@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishSerivce {@Autowiredprivate DishFlavorService dishFlavorService;/*** 新增菜品,同时插入菜品对应的口味数据,需要操作两张表:dish、dish_flavor* @param dishDto*/@Transactional@Overridepublic void saveWithFlavor(DishDto dishDto) {// 保存菜品的基本信息this.save(dishDto);Long dishId = dishDto.getId();  // 菜品idList<DishFlavor> flavors = dishDto.getFlavors();    // 菜品口味flavors.stream().map((item) -> {item.setDishId(dishId);return item;}).collect(Collectors.toList());// 保存菜品口味信息到dish_flavordishFlavorService.saveBatch(flavors);}}

③ 在启动类添加注解开启事务

@EnableTransactionManagement    // 开启事务

④ 在 DishController 中添加方法

@RestController
@Slf4j
@RequestMapping("/dish")
public class DishController {@Autowiredprivate DishSerivce dishSerivce;@Autowiredprivate DishFlavorService dishFlavorService;/*** 新增菜品* @param dishDto* @return*/@PostMappingpublic R<String> save(@RequestBody DishDto dishDto){//log.info(dishDto.toString());dishSerivce.saveWithFlavor(dishDto);return R.success("新增菜品成功");}}

3、菜品信息分页查询

3.1、分析

3.1.1、需求分析

3.1.2、页面与服务端的交互过程

分页获取菜品信息请求:

3.2、代码

    /*** 菜品信息分页查询* @param page* @param pageSize* @param name* @return*/@GetMapping("/page")public R<Page> page(int page,int pageSize,String name){// 分页构造器对象Page<Dish> pageInfo = new Page<>(page, pageSize);Page<DishDto> dishDtoPage = new Page<>();// 添加条件LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.like(name != null && !"".equals(name), Dish::getName, name);queryWrapper.orderByDesc(Dish::getUpdateTime);// 分页查询dishSerivce.page(pageInfo, queryWrapper);// 对象拷贝,不拷贝records属性BeanUtils.copyProperties(pageInfo, dishDtoPage, "records");// 将对应的分类名称填入List<Dish> records = pageInfo.getRecords();List<DishDto> list = records.stream().map((item) -> {DishDto dishDto = new DishDto();BeanUtils.copyProperties(item, dishDto);Long categoryId = item.getCategoryId(); // 分类idCategory category = categoryService.getById(categoryId);if(category != null) {String categoryName = category.getName();dishDto.setCategoryName(categoryName);}return dishDto;}).collect(Collectors.toList());dishDtoPage.setRecords(list);return R.success(dishDtoPage);}

4、修改菜品

4.1、分析

4.1.1、需求分析

4.1.2、页面与服务端的交互过程

根据 id 查询当前菜品信息的请求:

保存修改后的信息的请求:

4.2、代码

4.2.1、菜品信息回显

菜品信息的回显需要获取菜品的基本信息及其口味

① 在 DishSerivce 添加方法

    // 根据id查询菜品信息及其口味信息public DishDto getByIdWithFlavor(Long id);

② 在 DishServiceImpl 实现方法

    /*** 根据id查询菜品信息及其口味信息* @param id* @return*/@Overridepublic DishDto getByIdWithFlavor(Long id) {DishDto dishDto = new DishDto();// 查询菜品基本信息Dish dish = this.getById(id);// 查询菜品对应的口味信息LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(DishFlavor::getDishId, id);List<DishFlavor> flavors = dishFlavorService.list(queryWrapper);// 将查询到的数据封装BeanUtils.copyProperties(dish, dishDto);dishDto.setFlavors(flavors);return dishDto;}

③ 在 DishController 中使用方法

    /*** 根据id查询菜品信息及其口味信息* @param id* @return*/@GetMapping("/{id}")public R<DishDto> get(@PathVariable Long id){DishDto dishDto = dishSerivce.getByIdWithFlavor(id);return R.success(dishDto);}

4.2.2、修改商品实现

① 在 DishSerivce 添加方法

    // 更新菜品,同时更新对应的口味信息public void updateWithFlavor(DishDto dishDto);

② 在 DishServiceImpl 实现方法

    /*** 更新菜品,同时更新对应的口味信息* @param dishDto*/@Override@Transactionalpublic void updateWithFlavor(DishDto dishDto) {// 更新dish菜品表信息this.updateById(dishDto);// 清理当前菜品对应的口味LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(DishFlavor::getDishId, dishDto.getCategoryId());dishFlavorService.remove(queryWrapper);// 添加当前提交过来的口味信息List<DishFlavor> flavors = dishDto.getFlavors();flavors = flavors.stream().map((item) -> {item.setDishId(dishDto.getCategoryId());return item;}).collect(Collectors.toList());dishFlavorService.saveBatch(flavors);}

③ 在 DishController 中使用方法

    /*** 修改菜品* @return*/@PutMappingpublic R<String> update(@RequestBody DishDto dishDto){dishSerivce.updateWithFlavor(dishDto);return R.success("修改菜品成功");}

5、菜品停售与起售(批量)

5.1、分析

首先查看单个停售或起售的请求

再看一下批量的请求

可以将他们写为一个方法

5.2、代码

在 DishController 添加方法

    @PostMapping("/status/{status}")public R<String> updateStatus(@PathVariable("status") int status,@RequestParam List<Long> ids){List<Dish> dishes = new ArrayList<>();for (Long id : ids) {Dish dish = new Dish();dish.setStatus(status);dish.setId(id);dishes.add(dish);}dishSerivce.updateBatchById(dishes, dishes.size());return R.success("菜品状态修改成功");}

6、(批量)删除

6.1、分析

首先看一下单个删除的请求

再来看一下批量删除的请求

可以看到与修改售卖状态的请求大致相同。

流程:
1、获取请求中要删除的 id,并获取他们的基本信息
2、逐个判断他们的售卖状态,若在启售状态,则无法删除

6.2、代码

6.2.1、添加逻辑删除注解

由于 Dish 和 DishFlavor 中有逻辑删除的字段,所以这里使用逻辑删除。

在 Dish 和 DishFlavor 类的 isDeleted 字段加上 @TableLogic 注解

    //是否删除@TableLogic // 逻辑删除private Integer isDeleted;

瑞吉外卖 —— 5、菜品管理相关推荐

  1. 黑马瑞吉外卖之菜品的启售停售

    黑马瑞吉外卖值菜品的启售卖.和停售 这一部分功能是课程没有去完成的,但是其实是比较简单的,我们需要去完成菜品的启售和停售. 执行之前的项目,我们要完成的就是这里的这个售卖的状态的更改. 我们先去看一下 ...

  2. 黑马-瑞吉外卖 day5 套餐管理+手机验证码登录

    目录 1. 套餐管理 1.1 新增套餐 1.2 套餐信息分页查询 1.3 删除套餐(可批量) 1.4 修改套餐状态(可批量) 2.手机验证码登录 2.1 短信发送 2.2 手机验证码登录 1. 套餐管 ...

  3. 瑞吉外卖-新增菜品-异常处理

    错误信息描述 在新增菜品的时候遇到该错误 原因 没有找到create_time字段 没有获取到对应用户的id 添加了之后 错误信息 java.lang.IllegalArgumentException ...

  4. 猿创征文|瑞吉外卖——管理端_菜品管理_1

    个人名片: 博主:酒徒ᝰ. 专栏:瑞吉外卖 个人简介:沉醉在酒中,借着一股酒劲,去拼搏一个未来. 本篇励志:真正的程序员不看参考手册,新手和胆小鬼才会看. 本项目基于B站黑马程序员Java项目实战&l ...

  5. SB_5_瑞吉外卖_4_文件上传下载_菜品新增_菜品分页查询_菜品修改

    瑞吉外卖-Day04 课程内容 文件上传下载 菜品新增 菜品分页查询 菜品修改 1. 文件上传下载 1.1 上传介绍 1.1.1 概述 文件上传,也称为upload,是指将本地图片.视频.音频等文件上 ...

  6. 瑞吉外卖-移动端菜品展示功能,购物车添加菜品及修改等功能,用户下单功能及历史订单派送功能

    整理记录下学习整个瑞吉外卖项目,详细代码可在我的Gitee仓库瑞吉外卖实战克隆下载学习使用! 12.菜品展示 12.1 需求分析 12.2 更改前台页面使其正常显示 由于购物车功能还未进行开发,所以修 ...

  7. 猿创征文|瑞吉外卖——管理端_订单明细

    个人名片: 博主:酒徒ᝰ. 专栏:瑞吉外卖 个人简介:沉醉在酒中,借着一股酒劲,去拼搏一个未来. 本篇励志:一个人静静坐在电脑面前写代码的感觉,那是什么感觉?那是武林高手闭关修炼的感觉. 本项目基于B ...

  8. 瑞吉外卖之移动端菜品数据的展示

    瑞吉外卖之移动端菜品数据的展示 界面分析 界面分析 上篇我们主要完成了了瑞吉外卖移动端界面登录的功能.完成界面登录自然要进入主界面. 我们和前面的登录界面进行衔接上. 于是我们跳转到这个界面,也就是我 ...

  9. 【瑞吉外卖】学习笔记-day1:项目介绍及后台初识

    项目介绍 本项目(瑞吉外卖)是专门为餐饮企业(餐厅.饭店)定制的一款软件产品,包括 系统管理后台 和 移动端应用 两部分.其中系统管理后台主要提供给餐饮企业内部员工使用,可以对餐厅的分类.菜品.套餐. ...

  10. 瑞吉外卖01-项目整体介绍

    瑞吉外卖-项目整体介绍 前言 软件开发整体介绍(了解) 软件开发流程 第1阶段: 需求分析 第2阶段: 设计 第3阶段: 编码 第4阶段: 测试 第5阶段: 上线运维 角色分工 软件环境 开发环境(d ...

最新文章

  1. html li 右跟下有倒影,HTML5 canvas实现的下雨夜湖面星空倒影动画特效
  2. vue仿今日头条_vue2.0仿今日头条开源项目
  3. kibana6.2.2安装
  4. Leetcode--3Sum
  5. Vue 3.1.0 的 beta 版发布
  6. 程序员需要避免的 10 个坏习惯
  7. docker 容器内部获取自身id_crontab入门二:定时启动docker容器并启动容器内部脚本...
  8. kali安装步骤失败 选择并安装软件_PhotoShop CS5中文版软件下载+安装详细步骤
  9. Linux内核参数优化网络带宽,基于Linux内核的网络带宽管理
  10. LINUX给机器改名
  11. 研究生教育学科专业目录(2022年)与研究生教育学科专业目录管理办法
  12. 中国房地产泡沫规模巨大将载入历史 面临崩溃风险
  13. Java Heap - Percolate Up, Percolate Down, and Heapify
  14. 分享如何跟进转化客户,提高成单率
  15. python 图片处理模块_(python)图片处理Pillow模块的使用
  16. 铿锵玫瑰回来了 男足还是臭脚吗
  17. SSL数字证书认证的过程
  18. 实现海报合成工具,自定义背景图、位置、大小等 (html2canvas)
  19. UE4 VR手柄移动转盘
  20. Can't create database 'xxx' (errno: 28)

热门文章

  1. 科技赋能公益,看掌门1对1“灯塔计划”下的教育新火花
  2. php大文件下载502,php+nginx上传大文件502BadGateway
  3. 【Python学习】常用函数(更新中……)
  4. java 找不到或无法加载,java提示找不到或无法加载主类
  5. 单位换算:MB=?B,Mbps=?bps
  6. C#屏幕取色(支持Win7 64位 32位 WinXP)
  7. Unity3D光照贴图烘焙知识详解
  8. 微信 图文素材中批量替换URL
  9. 手机修改域名服务器,手机修改域名服务器ip地址
  10. js定时器,将当前系统的时间渲染到网页(每隔一秒钟,重新获取一次时间,拼接渲染到网页)