4.1 菜品修改模块需求分析
在菜品管理列表页面点击修改按钮,跳转到修改菜品页面,在修改页面回显菜品相关信息并进行修改,最后点击确定按钮完成修改操作。
4.2 菜品修改模块前端页面(add.html)和服务端的交互过程
1). 点击菜品列表的中的修改按钮,携带菜品id跳转至add.html
2). 进入add.html,页面发送ajax请求,请求服务端获取分类数据,用于菜品分类下拉框中数据展示(已实现)
3). add.html获取id, 发送ajax请求,请求服务端,根据id查询当前菜品信息,用于菜品信息回显
4). 页面发送请求,请求服务端进行图片下载,用于页图片回显(已实现)
5). 点击保存按钮,页面发送ajax请求,将修改后的菜品相关数据以json形式提交到服务端
4.3 新增功能
经过上述的分析,菜品分类下拉框的展示、图片的下载回显功能已经实现了。只需要在这里实现两个功能即可,分别是:
1). 根据ID查询菜品及菜品口味信息
请求 | 说明 |
---|---|
请求方式 | GET |
请求路径 | /dish/{id} |
2). 修改菜品及菜品口味信息
请求 | 说明 |
---|---|
请求方式 | PUT |
请求路径 | /dish |
请求参数 | json格式数据 |
通过浏览器抓取 具体的json格式数据:
{
"id":"1422783914845487106",
"name":"佛跳墙",
"categoryId":"1397844357980663809",
"price":88800,
"code":"",
"image":"da9e1c70-fc32-4781-9510-a1c4ccd2ff59.jpg",
"description":"佛跳墙",
"status":1,
"sort":0,
"createTime":"2021-08-04 12:58:14",
"createUser":"1412578435737350122",
"updateUser":"1412578435737350122",
"flavors":[
{
"id":"1422783914883235842",
"dishId":"1422783914845487106",
"name":"辣度",
"value":"[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]",
"createTime":"2021-08-04 12:58:14",
"updateTime":"2021-08-04 12:58:14",
"createUser":"1412578435737350122",
"updateUser":"1412578435737350122",
"isDeleted":0,
"showOption":false
},
{
"id":"1422783914895818754",
"dishId":"1422783914845487106",
"name":"忌口",
"value":"[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]",
"createTime":"2021-08-04 12:58:14",
"updateTime":"2021-08-04 12:58:14",
"createUser":"1412578435737350122",
"updateUser":"1412578435737350122",
"isDeleted":0,
"showOption":false
}
]
}
4.4 代码实现
4.4.1 根据ID查询菜品信息
页面发送ajax请求,请求服务端,根据id查询当前菜品信息和对应的口味信息,用于修改页面中菜品信息回显。
4.4.2 修改菜品信息
点击保存按钮,页面发送ajax请求,将修改后的菜品相关数据以json形式提交到服务端。在修改菜品信息时需要注意,除了要更新dish菜品表,还需要更新dish_flavor菜品口味表。
4.4.3 在DishService接口中扩展getByIdWithFlavor、updateWithFlavor方法
package com.itheima.reggie.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Dish;
public interface DishService extends IService<Dish> {
// 新增菜品,需要同时插入菜品对应的口味数据,需要操作两张表,dish、dish_flavor
public void saveWithFlavor(DishDto dishDto);
// 根据id查询菜品信息和对应的口味信息
public DishDto getByIdWithFlavor(Long id);
// 更新菜品信息,同时更新对应的口味信息
public void updateWithFlavor(DishDto dishDto);
}
4.4.4 在DishService实现类中实现getByIdWithFlavor与updateWithFlavor方法
①getByIdWithFlavor具体逻辑为:
A. 根据ID查询菜品的基本信息
B. 根据菜品的ID查询菜品口味列表数据
C. 组装数据并返回
②updateWithFlavor具体逻辑为:
A. 根据ID查询菜品的基本信息
B. 根据菜品的ID查询菜品口味列表数据
C. 组装数据并返回
package com.itheima.reggie.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
/**
* Description: new java files header..
*
* @author w
* @version 1.0
* @date 2022/8/16 10:15
*/
@Service
@Slf4j
public class DishServiceImpl extends ServiceImpl<DishMapper,Dish> implements DishService{
@Autowired
private DishFlavorService dishFlavorService;
@Override
@Transactional
public void saveWithFlavor(DishDto dishDto) {
/**@Description: 新增菜品 同时保存对应的口味数据
* @author LiBiGo
* @date 2022/8/18 11:58
*/
// 保存菜品的基本信息到菜品表dish
this.save(dishDto);
Long dishId = dishDto.getId(); // 菜品id
// 菜品口味
List<DishFlavor> flavors = dishDto.getFlavors();
flavors = flavors.stream().map((item)->{
item.setDishId(dishId);
return item;
}).collect(Collectors.toList());
// 保存菜品口味数据到菜品口味表dish_flavor
dishFlavorService.saveBatch(flavors);
}
@Override
// 根据id查询菜品信息和对应的口味信息
public DishDto getByIdWithFlavor(Long id) {
// 查询菜品的基本信息,从dish表查询
Dish dish = this.getById(id);
// 拷贝基本信息
DishDto dishDto = new DishDto();
BeanUtils.copyProperties(dish,dishDto);
// 查询当前菜品对应的口味信息,从dish_flavor表查询flavors
LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DishFlavor::getDishId,dish.getId());
List<DishFlavor> flavors = dishFlavorService.list(queryWrapper);
dishDto.setFlavors(flavors);
return dishDto;
}
@Override
@Transactional
public void updateWithFlavor(DishDto dishDto) {
// 更新dish表的基本信息
this.updateById(dishDto);
// 清理当前菜品对应的口味数据---dish_flavor表的delete操作
LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DishFlavor::getDishId,dishDto.getId());
dishFlavorService.remove(queryWrapper);
// 添加当前提交过来的口味数据---dish_flavor表的insert操作
List<DishFlavor> flavors = dishDto.getFlavors();
flavors = flavors.stream().map((item) -> {
item.setDishId(dishDto.getId());
return item;
}).collect(Collectors.toList());
dishFlavorService.saveBatch(flavors);
}
}
4.4.5 在DishController中创建get方法与update方法
package com.itheima.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.stream.Collectors;
/**
* Description: 菜品管理 菜品及菜品口味的相关操作,统一使用这一个controller即可。
* @version 1.0
* @date 2022/8/18 11:08
*/
@Slf4j
@RestController
@RequestMapping("/dish")
public class DishController {
@Autowired
private DishService dishService;
@Autowired
private DishFlavorService dishFlavorService;
@Autowired
private CategoryService categoryService;
@PostMapping
public R<String> save(@RequestBody DishDto dishDto){
/**@Description: 新增菜品
* @author LiBiGo
* @date 2022/8/18 11:44
*/
log.info(dishDto.toString());
dishService.saveWithFlavor(dishDto);
return R.success("新增菜品成功");
}
@GetMapping("/page")
public R<Page> page(int page,int pageSize,String name){
/**@Description: 菜品信息分页查询
* @author LiBiGo
*
* 数据库查询菜品信息时,获取到的分页查询结果 Page 的泛型为 Dish,而最终需要给前端页面返回的类型为DishDto,
* 所以这个时候就要进行转换,基本属性直接通过属性拷贝的形式对Page中的属性进行复制,
* 对于结果列表 records属性需要进行特殊处理的(需要封装菜品分类名称);
*
* @date 2022/8/19 10:41
*/
// 构造分页构造器对象
Page<Dish> pageInfo = new Page<>(page,pageSize);
Page<DishDto> dishDtoPage = new Page<>();
// 条件构造器
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
// 添加过滤条件
queryWrapper.like(name!=null,Dish::getName,name);
// 添加排序条件
queryWrapper.orderByDesc(Dish::getUpdateTime);
// 执行分页查询
dishService.page(pageInfo,queryWrapper);
// 对象的拷贝
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();//分类id
//根据id查询分类对象
Category 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);
}
@GetMapping("/{id}")
public R<DishDto> get(@PathVariable Long id){
/**@Description: 根据id查询菜品信息和对应的口味信息
* @author LiBiGo
* @date 2022/8/19 11:43
*/
DishDto dishDto = dishService.getByIdWithFlavor(id);
return R.success(dishDto);
}
@PutMapping
// @PathVariable : 该注解可以用来提取url路径中传递的请求参数。
public R<String> update(@RequestBody DishDto dishDto){
/**@Description: 修改菜品
* @author LiBiGo
* @date 2022/8/19 11:58
*/
log.info(dishDto.toString());
dishService.updateWithFlavor(dishDto);
return R.success("新增菜品成功");
}
}
4.4.6 功能测试
代码编写完成之后,重启服务,然后按照前面分析的操作流程进行测试,查看数据是否正常修改即可。