套餐管理业务
1.新增套餐
1.1需求分析
1.2 代码开发
首先是套餐菜品关系类SetmealDish
@Data
public class SetmealDish {
private Long id;
private Long setmealId;
private Long dishId;
private String name;
private BigDecimal price;
private Integer copies;
private Integer sort;
@TableField(fill= FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill=FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableField(fill= FieldFill.INSERT)
private Long createUser;
@TableField(fill=FieldFill.INSERT_UPDATE)
private Long updateUser;
private long isDeleted;
private static final long serialVersionUID = 1L;
}
然后是数据传输类SetmealDto
@Data
public class SetmealDto extends Setmeal {
private List<SetmealDish> setmealDishes;
private String categoryName;
}
然后是创建Mapper、Service、ServiceImpl、Controller,和之前的步骤类似,在此不做赘述
下面梳理一下新增套餐时的前端和服务端的交互过程:
我们进入套餐管理页面,按F12调试,点击新增套餐
我们发现,前端发送了两个请求:一个是type=2,即为查询套餐分类,另一个是type=1,即为查询菜品分类。查询出来的结果都会在前端页面展示出来:
套餐分类是下拉框:
还有在点击添加菜品时,菜品分类在左侧会显示。
在6个请求中,1,2,4,5请求均已经完成,第三个请求和第六个请求需要开发。我们看看第三个请求:
即在新增菜品时,显示对应分类的具体菜品信息
我们在dishController中编写代码
/**
* 根据条件查询对应菜品数据
* @param dish
* @return
*/
@GetMapping("/list")
public R<List<Dish>> queryList(Dish dish){
LambdaQueryWrapper<Dish> queryWrapper=new LambdaQueryWrapper<>();
//查询条件
queryWrapper.eq(dish.getCategoryId()!=null,Dish::getCategoryId,dish.getCategoryId());
//排序条件
queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
List<Dish> dishList = dishService.list(queryWrapper);
return R.success(dishList);
}
测试,运行,根据分类查询菜品信息成功。
接下来是我们如何把自定义的套餐存入数据库中,这里不仅要新增套餐,同时还需要保存套餐与菜品的关联关系
我们编写service接口方法:
/**
* 新增套餐,同时保存套餐与菜品的关联关系
* @param setmealDto
*/
public void saveWithDishes(SetmealDto setmealDto);
然后实现:(注意,这里由于setmealDishes传进来的时候,setmealId都是null,所以需要利用steam流进行赋值)
/**
* 新增套餐,同时保存套餐与菜品的关联关系
* @param setmealDto
*/
@Transactional
@Override
public void saveWithDishes(SetmealDto setmealDto) {
this.save(setmealDto);
List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
Long setmealId = setmealDto.getId();
setmealDishes=setmealDishes.stream().map((item)->{
item.setSetmealId(setmealId);
return item;
}).collect(Collectors.toList());
setmealDishService.saveBatch(setmealDishes);
}
最后是controller:
/**
* 添加套餐
* @return
*/
@PostMapping
public R<String> addSetmeal(@RequestBody SetmealDto setmealDto){
log.info(setmealDto.toString());
setmealService.saveWithDishes(setmealDto);
return R.success("套餐添加成功");
}
测试,发现数据库添加记录成功。
2.套餐信息分页查询
2.1需求分析
2.2 代码开发
编写套餐信息分页查询controller代码
/**
* 套餐信息分页查询
* @param page
* @param pageSize
* @param name
* @return
*/
@GetMapping("/page")
public R<Page> getPage(int page,int pageSize,String name){
//分页构造器
Page<Setmeal> pageinfo=new Page<>(page,pageSize);
//为了同时向前端提交套餐分类名称,创建SetmealDto的分页构造器
Page<SetmealDto> dtoInfo=new Page<>(page,pageSize);
//查询条件
LambdaQueryWrapper<Setmeal> queryWrapper=new LambdaQueryWrapper<>();
queryWrapper.like(name!=null,Setmeal::getName,name);
queryWrapper.orderByDesc(Setmeal::getUpdateTime);
//执行分页查询
setmealService.page(pageinfo, queryWrapper);
//属性拷贝,除了recodes之外的属性
BeanUtils.copyProperties(pageinfo,dtoInfo,"recodes");
//用stream流来修改recodes
List<Setmeal> records = pageinfo.getRecords();
List<SetmealDto> collect = records.stream().map((item) -> {
SetmealDto setmealDto = new SetmealDto();
BeanUtils.copyProperties(item, setmealDto);
//获取分类id,查询分类名称
Long categoryId = item.getCategoryId();
Category catbyId = categoryService.getById(categoryId);
if(catbyId!=null){
//分类名称
String catName = catbyId.getName();
setmealDto.setCategoryName(catName);
}
return setmealDto;
}).collect(Collectors.toList());
dtoInfo.setRecords(collect);
return R.success(dtoInfo);
}
注:由于Setmeal中只有套餐分类id,而前端需要展示套餐具体名称,所以这里我们需要借助SetmealDto,来获取到套餐分类名称传给前端。
测试,发现分页查询成功。
3.修改套餐(视频没有,自己写的,供参考)
3.1 需求分析&代码开发
首先需要在修改页面回显套餐原有数据,前端页面查看请求:
为restful风格请求,我们编写相应服务:
/**
* 修改套餐时查询套餐信息
* @param id
* @return
*/
@Override
public SetmealDto queryWhenUpdate(Long id) {
//套餐基本信息
SetmealDto setmealDto=new SetmealDto();
Setmeal setmealById = this.getById(id);
BeanUtils.copyProperties(setmealById,setmealDto);
//套餐菜品List<SetmealDish>
LambdaQueryWrapper<SetmealDish> queryWrapper=new LambdaQueryWrapper<>();
queryWrapper.eq(SetmealDish::getSetmealId,id);
List<SetmealDish> setmealDishList = setmealDishService.list(queryWrapper);
setmealDto.setSetmealDishes(setmealDishList);
//套餐分类名称 categoryName
Long categoryId = setmealById.getCategoryId();
String categoryname = categoryService.getById(categoryId).getName();
setmealDto.setCategoryName(categoryname);
return setmealDto;
}
controller:
/**
* 修改套餐时查询套餐信息
* @param id
* @return
*/
@GetMapping("/{id}")
public R<SetmealDto> querySetmealDto(@PathVariable Long id){
SetmealDto setmealDto = setmealService.queryWhenUpdate(id);
return R.success(setmealDto);
}
测试,回显功能正常:
然后是提交修改请求:
这里的修改涉及到两张表,分别是套餐表和套餐菜品关系表。
我们的处理逻辑和菜品修改那块类似:首先更新套餐表,然后删除套餐菜品关系表的相关记录,最后新增传进来的套餐菜品关系记录。
接下来编写service代码
/**
* 修改套餐提交
* @param setmealDto
*/
@Transactional
@Override
public void updateSetmealDto(SetmealDto setmealDto) {
//首先修改套餐
this.updateById(setmealDto);
//然后删除套餐菜品关系表的相关记录
Long setmealId = setmealDto.getId();
LambdaQueryWrapper<SetmealDish> queryWrapper=new LambdaQueryWrapper<>();
queryWrapper.eq(SetmealDish::getSetmealId,setmealId);
setmealDishService.remove(queryWrapper);
//最后是新增
List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
//设置缺失的setmealid
setmealDishes=setmealDishes.stream().map((item)->{
item.setSetmealId(setmealId);
return item;
}).collect(Collectors.toList());
setmealDishService.saveBatch(setmealDishes);
}
controller代码
/**
* 修改套餐提交
* @return
*/
@PutMapping
public R<String> updateSetmeal(@RequestBody SetmealDto setmealDto){
// log.info(setmealDto.toString());
setmealService.updateSetmealDto(setmealDto);
return R.success("修改成功");
}
测试,修改成功。
4.停售/起售套餐(视频没有,自己写的,供参考)
4.1需求分析&代码开发
选取两个套餐,页面点击批量停售,发出的请求如下:
编写controller:
/**
* (批量)停售/起售套餐
* @return
*/
@PostMapping("/status/{status}")
public R<String> changeStatus(@PathVariable Integer status,@RequestParam List<Long> ids){
for (Long setId : ids) {
Setmeal setbyId = setmealService.getById(setId);
setbyId.setStatus(status);
setmealService.updateById(setbyId);
}
return R.success("修改成功");
}
测试,停售/起售成功
5.删除套餐
5.1需求分析
5.2 代码开发
具体删除逻辑:
** 为了支持批量删除,接收参数用List
首先查询套餐状态,如果是处于起售状态的是不能被删除的,需要提示用户先停售再删除;
其次是,删除了对应套餐表记录后,还需要删除套餐菜品关系表中的记录。**
Service层代码:
/**
* 删除套餐
* @param ids
*/
@Override
public void delSetWithDish(List<Long> ids) {
//首先查询是否能删除
LambdaQueryWrapper<Setmeal> queryWrapper=new LambdaQueryWrapper<>();
queryWrapper.in(Setmeal::getId,ids);
queryWrapper.eq(Setmeal::getStatus,1);
int count = this.count(queryWrapper);
//如果不能被删除,要抛出全局异常
if(count>0){
throw new CustomException("请先停售再删除套餐");
}
//如果可以被删除,那么就先删除套餐表记录
this.removeByIds(ids);
//最后删除菜品关系表记录
LambdaQueryWrapper<SetmealDish> queryWrapper1=new LambdaQueryWrapper<>();
queryWrapper1.in(SetmealDish::getSetmealId,ids);
setmealDishService.remove(queryWrapper1);
}
controller层代码
/**
* 删除套餐
* @param ids
* @return
*/
@DeleteMapping
public R<String> delSetmeal(@RequestParam List<Long> ids){
log.info(ids.toString());
setmealService.delSetWithDish(ids);
return R.success("删除成功");
}