文章目录
瑞吉外卖 — day5
- 套餐管理业务开发
1. 新增套餐
1.1 需求分析
- 套餐就是菜品的集合。
- 后台系统中可以管理套餐信息,通过新增套餐功能来添加一个新的套餐,在添加套餐时需要选择当前套餐所属的套餐分类和包含的菜品,并且需要上传套餐对应的图片,在移动端会按照套餐分类来展示对应的套餐。
1.2 数据模型
-
setmeal 套餐表
setmeal_dish 套餐菜品关系表
1.3 代码开发
-
创建基本类和接口
实体类SetmealDish(直接从课程资料中导入即可,Setmeal实体前面课程中已经导入过了)
DTo SetmealDto (直接从课程资料中导入即可)
Mapper接口SetmealDishMapper
业务层接口SetmealDishService
业务层实现类SetmealDishServicelmpl
控制层SetmealController
-
前端页面与后端交互过程:
1、页面(backend/page/combo/add.html)发送ajax请求,请求服务端获取套餐分类数据并展示到下拉框中
2、页面发送ajax请求,请求服务端获取菜品分类数据并展示到添加菜品窗口中
3、页面发送ajax请求,请求服务端,根据菜品分类查询对应的菜品数据并展示到添加菜品窗口中
4、页面发送请求进行图片上传,请求服务端将图片保存到服务器
5、页面发送请求进行图片下载,将上传的图片进行回显
6、点击保存按钮,发送ajax请求,将套餐相关数据以json形式提交到服务端
-
请求服务端获取菜品分类数据并展示到添加菜品窗口中:
/** *根据条件查询对应菜品数据 * @param dish * @return */ @GetMapping("list") public R<List<Dish>> list(Dish dish){ //构造查询条件 LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(dish.getCategoryId()!=null, Dish::getCategoryId, dish.getCategoryId()); //添加条件,查询状态为1的菜品 queryWrapper.eq(Dish::getStatus,1); //添加排序条件 queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime); List<Dish> list = dishService.list(queryWrapper); return R.success(list); }
-
将套餐相关数据以json形式提交到服务端:
@RestController @RequestMapping("setmeal") @Slf4j public class SetmealController { @Autowired private SetmealService setmealService; @Autowired private SetmealDishService setmealDishService; /** * 新增套餐 * @param setmealDto * @return */ @PostMapping public R<String> save(@RequestBody SetmealDto setmealDto){ log.info("套餐信息:{}",setmealDto); setmealService.saveWithDish(setmealDto); return R.success("新增套餐成功!"); } }
@Service public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService { @Autowired private SetmealDishService setmealDishService; /** * 新增套餐,同时需要保存套餐与菜品的关联关系 * @param setmealDto */ @Override @Transactional public void saveWithDish(SetmealDto setmealDto) { //保存套餐基本信息 —— setmeal —— insert this.save(setmealDto); List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes(); setmealDishes.stream().map((item) ->{ item.setSetmealId(setmealDto.getId()); return item; }).collect(Collectors.toList()); //保存套餐和菜品的关联信息 —— setmeal_dish —— insert setmealDishService.saveBatch(setmealDishes); } }
2. 套餐信息分页查询
2.1 需求分析
- 系统中的套餐数据很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看,所以一般的系统中都会以分页的方式来展示列表数据。
2.2 代码开发
-
前端页面与服务端交互过程:
1、页面(backend/page/combo/list.html)发送ajax请求,将分页查询参数(page、pageSize,name)提交到服务端,获取分页数据
2、页面发送请求,请求服务端进行图片下载,用于页面图片展示
-
分页查询:
/** * 套餐分页查询 * @param page * @param pageSize * @param name * @return */ @GetMapping("page") public R<Page> page(int page, int pageSize, String name){ //分页构造器对象 Page<Setmeal> pageInfo = new Page<>(page, pageSize); Page<SetmealDto> dtoPage = new Page<>(); LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>(); //添加查询条件,根据name模糊查询 queryWrapper.like(name!=null,Setmeal::getName,name); //添加排序条件,根据更新时间降序排列 queryWrapper.orderByDesc(Setmeal::getUpdateTime); setmealService.page(pageInfo,queryWrapper); //对象拷贝 BeanUtils.copyProperties(pageInfo,dtoPage,"records"); List<Setmeal> records = pageInfo.getRecords(); List<SetmealDto> list = records.stream().map((item)->{ SetmealDto setmealDto = new SetmealDto(); //对象拷贝 BeanUtils.copyProperties(item,setmealDto); //分类id Long categoryId = item.getCategoryId(); //根据分类id查询分类对象 Category category = categoryService.getById(categoryId); if(category != null){ //分类名称 String categoryName = category.getName(); setmealDto.setCategoryName(categoryName); } return setmealDto; }).collect(Collectors.toList()); dtoPage.setRecords(list); return R.success(dtoPage); }
3. 删除套餐
3.1 需求分析
- 在套餐管理列表页面点击删除按钮,可以删除对应的套餐信息。也可以通过复选框选择多个套餐,点击批量删除按钮一次删除多个套餐。注意,对于状态为售卖中的套餐不能删除,需要先停售,然后才能删除。
3.2 代码开发
-
前端页面与服务端交互过程:
1、删除单个套餐时,页面发送ajax请求,根据套餐id删除对应套餐
2、删除多个套餐时,页面发送ajax请求,根据多个套餐id删除对应套餐
删除单个套餐和批量删除套餐的请求信息,两种请求的地址和请求方式都是相同的,不同的则是传递的id个数,所以在服务端可以提供一个方法来统一处理。
-
controller层:
/** * 删除套餐 * @param ids * @return */ @DeleteMapping public R<String> delete(@RequestParam List<Long> ids){ log.info("删除套餐:{}",ids); setmealService.removeWithDish(ids); return R.success("套餐删除成功!"); }
-
setmealSeriveImpl中的removeWithDish方法:
/** * 删除套餐,同时需要删除套餐与菜品的关联关系 * @param ids */ @Override @Transactional public void removeWithDish(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 CustomerException("套餐正在售卖中,不能删除"); } //可以删除,先删除套餐表中的数据 —— setmeal表 this.removeByIds(ids); //再删除关系表中的数据 —— setmeal_dish表 LambdaQueryWrapper<SetmealDish> queryWrapper1 = new LambdaQueryWrapper<>(); queryWrapper1.in(SetmealDish::getSetmealId,ids); setmealDishService.remove(queryWrapper1); }
4. 套餐售卖状态修改
4.1 需求分析
- 可根据需要,对套餐的 启售/停售 状态进行修改
4.2 代码开发
/**
* 套餐售卖状态修改
* @param status
* @param ids
* @return
*/
@PostMapping("status/{status}")
public R<String> updateStatus(@PathVariable int status, @RequestParam List<Long> ids){
log.info("售卖状态修改的套餐:{}",ids);
for(Long id: ids){
LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Setmeal::getId,id);
Setmeal setmeal = setmealService.getById(id);
setmeal.setStatus(status);
setmealService.updateById(setmeal);
}
return R.success("套餐售卖状态修改成功!");
}
5. 修改套餐
5.1 需求分析
- 对某一指定的套餐,可对套餐中的数据信息(价格,套餐名称等)进行修改
5.2 代码开发
-
前段页面与服务端交互过程
- 点击修改操作后,跳转到修改套餐页面(也就是新增套餐页面),先对套餐信息进行回显
- 对套餐数据进行修改
-
套餐信息回显操作
-
controller层
/** * 根据id查询套餐详细信息,在修改页面进行回显 * @param id * @return */ @GetMapping("/{id}") public R<Setmeal> get(@PathVariable Long id){ log.info("查询套餐详细信息的id:{}",id); SetmealDto setmealDto = setmealService.getByIdWithDish(id); return R.success(setmealDto); }
-
setmealSeriveImpl中的getByIdWithDish方法
/** * 根据id查询套餐详细信息,在修改页面进行回显 * @param id * @return */ @Override public SetmealDto getByIdWithDish(Long id) { //查询套餐基本信息 Setmeal setmeal = this.getById(id); SetmealDto setmealDto = new SetmealDto(); BeanUtils.copyProperties(setmeal,setmealDto); //查询当前套餐对应的菜品信息 LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SetmealDish::getSetmealId,id); List<SetmealDish> list = setmealDishService.list(queryWrapper); setmealDto.setSetmealDishes(list); return setmealDto; }
-
-
套餐数据修改操作
-
controller层
/** * 修改套餐数据信息 * @param setmealDto * @return */ @PutMapping public R<String> update(@RequestBody SetmealDto setmealDto){ log.info("修改套餐:{}",setmealDto); setmealService.updateWithDish(setmealDto); return R.success("修改套餐数据成功!"); }
-
setmealSeriveImpl中的updateWithDish方法
/** * 修改套餐数据信息 * @param setmealDto */ @Override public void updateWithDish(SetmealDto setmealDto) { //更新setmeal表信息 this.updateById(setmealDto); //清理当前套餐下对应的菜品 LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SetmealDish::getSetmealId,setmealDto.getId()); setmealDishService.remove(queryWrapper); //添加当前提交的菜品数据 List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes(); setmealDishes = setmealDishes.stream().map((item)->{ item.setSetmealId(setmealDto.getId()); return item; }).collect(Collectors.toList()); setmealDishService.saveBatch(setmealDishes); }
-