【从零开始分析项目实战】11-套餐管理业务开发
注:本文章基于黑马程序员相关视频及资料进行编写,代码简单,较容易理解,若有问题或者源码资料获取可以在评论区留言或者联系作者!
文章目录
- 开篇
- 一、新增套餐
- 二、套餐信息分页查询
- 三、删除套餐
开篇
一、新增套餐
(1)需求分析:
套餐就是菜品的集合,后台系统中可以管理套餐信息,通过新增套餐功能来添加一个新的套餐,在添加套餐的时候需要选择当前套餐所属的套餐分类和包含的菜品,并且需要上传套餐对应的图片,在移动端会按照套餐分类来展示对应的套餐;
新增套餐,其实就是将新增页面录入的套餐信息插入到setmeal表(套餐表),还需要向Setmeal_dish(套餐菜品关联表)表中插入套餐和菜品关联的数据,所以在新增套餐的时候,涉及到两个表;
(2)代码开发-准备工作:
- 实体类Setmeal和Setmeal_dish类
- DTO类 SetmealDto
@Datapublic class SetmealDto extends Setmeal { private List<SetmealDish> setmealDishes; private String categoryName;}
- Mapper接口SetmealDishMapper
- 业务层接口SetmealDishService
public interface SetmealDishService extends IService<SetmealDish> {}
- 业务层实现类SetmealDishServiceImpl
@Servicepublic class SetmealDishServiceImpl extends ServiceImpl<SetmealDishMapper, SetmealDish> implements SetmealDishService {}
- 控制层 SetmealController
@RestController@RequestMapping("/setmeal")@Slf4jpublic class SetmealController { @Autowired private SetmealService setmealService; @Autowired private SetmealDishService setmealDishService; }
(3)代码开发-交互过程
- 页面发送ajax请求,获取套餐分类数据并展示到下拉框中(前面已实现)
- 页面发送ajax请求,请求服务端获取菜品分类中数据并展示到添加菜品的窗口中(前面已实现);
- 页面发送ajax请求,请去服务端,根据菜品分类查询对应的菜品数据并展示到添加菜品的窗口中
- 页面进行图片的上传与下载请求(前面已实现)
- 点击保存按钮,页面发送ajax请求,套餐相关数据以json数据的格式提交到服务端;
首先根据菜品分类查询对应的菜品数据,将前端传来的CategoryId封装成一个Dish对象,然后进行数据库查询,根据查询条件返回一个Dish的列表数据,
/*根据条件来查询对应的菜品*/ @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); }
然后是服务端接受页面提交的数据,将套餐数据分别保存到Setmeal和SetmealDish表中,可以在SetmealServiseImpl类中编写具体实现方法:
/*新增套餐同时保存套餐和菜品的关联关系*/ @Override @Transactional public void savewithDish(SetmealDto setmealDto) { //保存套餐的基本信息 执行inset操作 this.save(setmealDto); //保存套餐和菜品的关联信息,操作setmeal_dish 执行insert操作 List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes(); setmealDishes.stream().map((item)->{ item.setSetmealId(setmealDto.getId()); return item; }).collect(Collectors.toList()); setmealDishService.saveBatch(setmealDishes); }
最后编写接口调用此方法,并返回响应结果:
/*新增套餐*/ @PostMapping public R<String> save(@RequestBody SetmealDto setmealDto){ log.info("套餐信息{}",setmealDto); setmealService.savewithDish(setmealDto); return R.success("新增套餐成功"); }
二、套餐信息分页查询
(1)需求分析:系统中的套餐数据很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看,所以一般系统中都会以分页的方式来展示列表数据;
(2) 代码开发-梳理交互过程
- 页面发送ajax请求,将分页查询参数(page,pageSize,name)提交到服务端,获取分页数据
- 页面发送请求,请求服务端进行图片下载,用于图片展示
具体代码实现和之前一样,首先需要构造两个page对象,Page 和Page ,然后将Page 对象中的除records数据赋值到Page 中,也就是page,pageSIze等数据;
然后将records中的数据进行提取,将records中的列表数据Setmeal拷贝到SetmealDto中,再查询categoryName值对SetmealDto进行封装。最后将所有的SetmealDto返回成一个列表赋值给Page 的records数据;
/*套餐分页查询*/ @GetMapping("/page") public R<Page> page(int page,int pageSize,String name){ //分页构造器 Page<Setmeal> pageInfo=new Page<>(page,pageSize); Page<SetmealDto> pageDto=new Page<>(); //对象拷贝 BeanUtils.copyProperties(pageInfo,pageDto,"records"); LambdaQueryWrapper<Setmeal> queryWrapper =new LambdaQueryWrapper<>(); queryWrapper.like(name!=null,Setmeal::getName,name); //根据更新时间降序排列 queryWrapper.orderByDesc(Setmeal::getUpdateTime); setmealService.page(pageInfo, queryWrapper); List<Setmeal> records = pageInfo.getRecords(); List<SetmealDto> list=records.stream().map((item)->{ SetmealDto setmealDto=new SetmealDto(); BeanUtils.copyProperties(item,setmealDto); //根据分类的id查询分类的对象 Category category = categoryService.getById(item.getCategoryId()); if (category!=null){ //分类名称 String categoryName = category.getName(); setmealDto.setCategoryName(categoryName); } return setmealDto; }).collect(Collectors.toList()); pageDto.setRecords(list); return R.success(pageDto); }
运行结果如下图所示:
三、删除套餐
(1)需求分析:
在套餐管理列表页面,点击删除按钮,可以删除对应的套餐信息,也可以通过复选框选择多个套餐,点击批量删除按钮一次删除多个套餐,注意,对弈状态为售卖中的套餐不能删除,需要首先停售,然后才能删除;
(2) 代码开发-梳理交互流程
- 删除单个套餐时,页面发送AJAX请求,根据套餐id删除对应套餐
- 删除多个套餐时,页面发送AJAX请求,根据提交的多个套餐id删除对应套餐
开发删除功能时,其实就是在服务端编写代码去处理前端页面发送的这2此请求即可,观察删除单个套餐和批量删除套餐的请求信息可以发现,两种请求的地址和请求的方式都是相同的,不同的是传递的id的个数,所有在服务端可以提供一个方法来统一处理。
(3)代码开发-具体编码
由于删除功能设计到Setmeal表和Setmealdish表,所以可以在SetmealService中新编写一个方法,用于实现删除功能
/*删除套餐,同时删除套餐和菜品的关联数据*/ @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 CustomException("套餐正在售卖中,不能删除"); } //如果可以删除,先删除套餐表中的数据,根据主键id批量删除 this.removeByIds(ids); //删除关系表中的数据,根据条件批量删除 LambdaQueryWrapper<SetmealDish> lambdaQueryWrapper =new LambdaQueryWrapper<>(); lambdaQueryWrapper.in(SetmealDish::getSetmealId,ids); setmealDishService.remove(lambdaQueryWrapper); }
运行项目,删除一个菜品,可以正常删除;
如果感觉内容写的还不错的话,一键三连不迷路!!!!
后面将会更新更多学习内容,一起学习吧!!!!!!