瑞吉外卖 —— 5、菜品管理

news/2024/12/2 16:44:47/

目录

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;


http://www.ppmy.cn/news/633785.html

相关文章

samba配置共享用户home目录

1. 先要安装samba sudo apt-get update sudo apt-get install samba openssh-server 2. 编辑Samba配置文件 sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak sudo vi /etc/samba/smb.conf找到[homes]项&#xff0c;此项默认是注释掉的&#xff0c;取消其注释&#xff…

想在美国开餐厅?想招人?顶级餐饮经营锦囊,300个餐饮人等你来撩!

硅谷Live / 实地探访 / 热点探秘 / 深度探讨 前段时间&#xff0c; Facebook上有位餐厅老板的Po文&#xff0c; 字字血泪真实的“跌跌撞撞”经历&#xff0c; 引来了100多个赞。 小分队在日常的工作中接触的餐厅越多&#xff0c; 越觉得开一家餐厅、开一家好餐厅的不易。 根据调…

智慧营养餐厅

目前&#xff0c;随着人工智能时代的到来&#xff0c;智慧餐厅模式也已进入了我们的生活之中&#xff0c;它所展现出来的应用场景&#xff0c;不仅有无人餐厅、智能化食堂、数字化后勤管理&#xff0c;等新型团餐形式&#xff0c;还包括智能化软硬件设备。 随着国家大力推动物联…

基辅餐厅大食记

社会主义就是好来就是好&#xff0c;我们编辑部又聚餐了……这次选在俄罗斯风情浓厚的基辅餐厅&#xff0c;去之前我已经参考过手中的《2005北京餐馆指南》&#xff0c;那上面是这样说的&#xff1a; 海淀区玉渊潭南路普惠南里13号 010-68283482 68277309 简介&#xff1a; …

餐厅预订系统有哪些?餐厅预订系统怎么选择?

餐厅实施餐厅预订系统&#xff0c;既可以能提升服务体会&#xff0c;也可以很大省下店员的工作量&#xff0c;提升服务效率。以及通过预订成功提醒、就餐提醒等功能&#xff0c;确保用户忘记就餐。那餐饮店如何快速、低成本的拥有一套属于自己的餐馆预订系统&#xff0c;今天小…

北京十大隐秘餐厅

1、翼栈 说翼栈是个酒吧或者餐厅都不确切&#xff0c;这里更像是一个据点&#xff0c;一个世外的江湖。这里长期聚集着各种有趣的人&#xff0c;比如没事满世界乱走的背包客、扛着着伞包四处飞伞的滑翔者&#xff0c;骑个单车走遍中国的骑行人什么的&#xff0c;还有就是喜欢音…

餐厅信息管理系统

简易餐厅信息管理系统 餐厅管理流程是一个小型的信息管理系统&#xff0c;本文采用c/c中的结构体、文件的输入、输出等操作&#xff0c;实现了一个餐厅中的预约、点菜、查询信息、收款基本功能。 1.模块分析 本文将一个餐厅信息管理系统划分为如下图所示的子模块。 主要功能如…

上海西式餐厅一览

卢湾区 "洛西亚"俄罗斯文化主题餐厅 上海市淮海中路438号B1021-63872111 ; 浦东新区 夏龙湾餐厅 上海市陆家嘴路15号陆家嘴中心绿地内021-58771231 ; 卢湾 伊斯坦布尔餐厅 淮海中路900号地下一层 021-64676666 ; 徐汇区 希腊餐厅 上海市吴兴路33号64665608 ; 徐汇…