Part03 ☀️

YangeIT大约 14 分钟瑞吉外卖菜品模块文件上传DTO封装多表查询逻辑删除

Part03 ☀️

课程内容

  • 管理端
    • 文件上传下载 ✏️
    • 菜品新增 ✏️
    • 菜品分页查询 ✏️
    • 菜品修改 ✏️

1. 菜品模块介绍 🍐

菜品模块介绍

  • 文件上传下载 ✏️
  • 菜品新增 ✏️
  • 菜品分页查询 ✏️
  • 菜品修改 ✏️ image

开始前,需要下载群里的前端页面,替换项目中的backend代码

image
image

2. 菜品新增模块

2.1 图片上传 🍐

图片上传

  1. 新增菜品,需要上传图片,流程如下:
image
image

2. 实际开发中,图片会存到专门的图片服务器,本项目使用阿里云OSS对象存储,来存储图片,流程如下:

image
image

代码操作

image
image

阿里云oss:https://www.aliyun.com/product/ossopen in new window

  1. 打开阿里云oss,申请服务,获取如下信息:
    • 服务器地址:如武汉机房,北京机房
    • accessKeyId 访问keyId
    • accessKeySecret:秘钥
    • bucketName:桶信息

总结

课堂作业

  1. 根据上述提示完成图片的上传?🎤
  2. 大家思考一下,秘钥可以随便传播吗?

2.2 获取分类列表

获取分类列表

1. 点击新增菜品,会自动发起获取菜品分类的列表image


2. 按照F12观察请求,获取请求路径和请求方式以及参数类型image

代码操作

1. 在CategoryController类中书写请求

 /**
     * 根据条件查询分类数据
     * @param category
     * @return
     */
    @GetMapping("/list")
    public R<List<Category>> list(Category category){
        log.info("分类type:{}",category.getType());
        //条件构造器
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        //添加条件 分类类型不等于NUll 1为菜品分类 2为套餐分类
        queryWrapper.eq(category.getType() != null,Category::getType,category.getType());
        //添加排序条件 修改时间降序
        queryWrapper.orderByAsc(Category::getSort).orderByDesc(Category::getUpdateTime);
        //带条件查询
        List<Category> list = categoryService.list(queryWrapper);
        return R.success(list);
    }

2.3 菜品新增 ✏️

菜品新增

后台系统中可以管理菜品信息,通过 新增功能来添加一个新的菜品,在添加菜品时需要选择当前菜品所属的菜品分类,并且需要上传菜品图片,在移动端会按照菜品分类来展示对应的菜品信息 。

image-20210803234122966
image-20210803234122966

代码操作

步骤

  1. 导入资料到工程中(焱哥发到群里了)
  2. DishController 定义方法新增菜品
  3. DishService 中增加方法 saveWithFlavor
  4. DishServiceImpl 中实现方法 saveWithFlavor
  5. 在引导类上加注解 @EnableTransactionManagement

将老师发送在微信群里的压缩包,下载解压后,放到对应的包中!

image
image

总结

课堂作业

  1. 参考上述步骤,完成菜品的新增🎤

3. 菜品分页查询 🍐 ✏️

菜品分页查询

系统中的菜品数据很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看,所以一般的系统中都会以分页的方式来展示列表数据。

image-20210804223703893

菜品列表展示数据:

  1. 菜品的基本信息(名称、售价、售卖状态、更新时间)
  2. 菜品图片
  3. 菜品分类(需要展示分类名称,而不是分类 ID )
    • 需要根据菜品的分类 ID,去分类表中查询分类信息,然后在页面展示

代码操作

上述我们已经分析了分页查询的请求信息,那么接下来,我们就需要在 DishController 中开发方法,来完成菜品的条件分页查询,在分页查询时还需要给页面返回分类的名称,而分类的名称前端在接收的时候是通过 categoryName 属性获取的,那么对应的服务端也应该封装到 categoryName 属性中。

<el-table-column prop="categoryName" label="菜品分类"></el-table-column>

而在我们的实体类 Dish 中,仅仅包含 categoryId, 不包含 categoryName,那么我们应该如何封装查询的数据呢?

其实,这里我们可以返回 DishDto 对象,在该对象中我们可以拓展一个属性 categoryName,来封装菜品分类名称。

@Data
public class DishDto extends Dish {
    private List<DishFlavor> flavors = new ArrayList<>();
    private String categoryName; //菜品分类名称
    private Integer copies;
}




 



注意: 已经导入成功了,不需要重复导入

4. 菜品修改

4.1 根据 ID 查询菜品信息 ✏️

根据 ID 查询菜品信息

页面发送 ajax 请求,请求服务端,根据 id 查询当前菜品信息和对应的口味信息,用于修改页面中菜品信息回显。

  1. 在 DishService 接口中扩展 getByIdWithFlavor 方法

  2. 在 DishService 实现类中实现此方法 具体逻辑为:

    1. A. 根据 ID 查询菜品的基本信息
    2. B. 根据菜品的 ID 查询菜品口味列表数据
    3. C. 组装数据并返回
  3. 在 DishController 中创建 get 方法

代码操作

DishController

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

4.2 修改菜品信息 🍐 ✏️

修改菜品信息

image
image

点击保存按钮,页面发送 ajax 请求,将修改后的菜品相关数据以 json 形式提交到服务端。在修改菜品信息时需要注意,除了要更新 dish 菜品表,还需要更新 dish_flavor 菜品口味表

  1. 在 DishService 接口中扩展方法 updateWithFlavor

  2. 在 DishServiceImpl 中实现方法 updateWithFlavor

    1. 该方法中,我们既需要更新 dish 菜品基本信息表,还需要更新 dish_flavor 菜品口味表。
      1. 页面再操作时,关于菜品的口味,有修改,有新增,也有可能删除,我们应该如何更新菜品口味信息呢?
        1. 无论菜品口味信息如何变化,我们只需要保持一个原则:先删除,后添加。
  3. 在 DishController 中创建 update 方法

代码操作

DishController 代码

/**
* 修改菜品
* @param dishDto
* @return
*/
@PutMapping
public R<String> update(@RequestBody DishDto dishDto){
    log.info("修改菜品,菜品信息:{}",dishDto);
    dishService.updateWithFlavor(dishDto);
    return R.success("修改菜品成功");
}