2.3 代码开发
2.3.1 基本信息查询
上述我们已经分析列表分页查询功能的请求信息,接下来我们就在SetmealController中创建套餐分页查询方法。
该方法的逻辑如下:
1). 构建分页条件对象
2). 构建查询条件对象,如果传递了套餐名称,根据套餐名称模糊查询, 并对结果按修改时间降序排序
3). 执行分页查询
4). 组装数据并返回
代码实现 :
/*** 套餐分页查询* @param page* @param pageSize* @param name* @return*/"/page") (publicR<Page>page(intpage,intpageSize,Stringname){ //分页构造器对象Page<Setmeal>pageInfo=newPage<>(page,pageSize); LambdaQueryWrapper<Setmeal>queryWrapper=newLambdaQueryWrapper<>(); //添加查询条件,根据name进行like模糊查询queryWrapper.like(name!=null,Setmeal::getName,name); //添加排序条件,根据更新时间降序排列queryWrapper.orderByDesc(Setmeal::getUpdateTime); setmealService.page(pageInfo,queryWrapper); returnR.success(pageInfo); } ————————————————版权声明:本文为CSDN博主「陶然同学」的原创文章,遵循CC4.0BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/weixin_45481821/article/details/126309868
2.3.2 问题分析
基本分页查询代码编写完毕后,重启服务,测试列表查询,我们发现, 列表页面的数据可以展示出来, 但是套餐分类名称没有展示出来
这是因为在服务端仅返回分类ID(categoryId), 而页面展示需要的是categoryName属性。
2.3.3 功能完善
在查询套餐信息时, 只包含套餐的基本信息, 并不包含套餐的分类名称, 所以在这里查询到套餐的基本信息后, 还需要根据分类ID(categoryId), 查询套餐分类名称(categoryName),并最终将套餐的基本信息及分类名称信息封装到SetmealDto(在第一小节已经导入)中。
publicclassSetmealDtoextendsSetmeal { privateList<SetmealDish>setmealDishes; //套餐关联菜品列表privateStringcategoryName;//套餐分类名称}
完善后代码:
/*** 套餐分页查询* @param page* @param pageSize* @param name* @return*/"/page") (publicR<Page>page(intpage,intpageSize,Stringname){ //分页构造器对象Page<Setmeal>pageInfo=newPage<>(page,pageSize); Page<SetmealDto>dtoPage=newPage<>(); LambdaQueryWrapper<Setmeal>queryWrapper=newLambdaQueryWrapper<>(); //添加查询条件,根据name进行like模糊查询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) -> { SetmealDtosetmealDto=newSetmealDto(); //对象拷贝BeanUtils.copyProperties(item,setmealDto); //分类idLongcategoryId=item.getCategoryId(); //根据分类id查询分类对象Categorycategory=categoryService.getById(categoryId); if(category!=null){ //分类名称StringcategoryName=category.getName(); setmealDto.setCategoryName(categoryName); } returnsetmealDto; }).collect(Collectors.toList()); dtoPage.setRecords(list); returnR.success(dtoPage); }
2.4 功能测试
代码完善后,重启服务,测试列表查询,我们发现, 抓取浏览器的请求响应数据,我们可以获取到套餐分类名称categoryName,也可以在列表页面展示出来 。
3. 删除套餐
3.1 需求分析
在套餐管理列表页面,点击删除按钮,可以删除对应的套餐信息。也可以通过复选框选择多个套餐,点击批量删除按钮一次删除多个套餐。注意,对于状态为售卖中的套餐不能删除,需要先停售,然后才能删除。
3.2 前端页面分析
在开发代码之前,需要梳理一下删除套餐时前端页面和服务端的交互过程:
1). 点击删除, 删除单个套餐时,页面发送ajax请求,根据套餐id删除对应套餐
2). 删除多个套餐时,页面发送ajax请求,根据提交的多个套餐id删除对应套餐
开发删除套餐功能,其实就是在服务端编写代码去处理前端页面发送的这2次请求即可,一次请求为根据ID删除,一次请求为根据ID批量删除。
观察删除单个套餐和批量删除套餐的请求信息可以发现,两种请求的地址和请求方式都是相同的,不同的则是传递的id个数,所以在服务端可以提供一个方法来统一处理。
具体的请求信息如下:
请求 | 说明 |
请求方式 | DELETE |
请求路径 | /setmeal |
请求参数 | ?ids=1423640210125656065,1423338765002256385 |
3.3 代码开发
删除套餐的流程及请求信息,我们分析完毕之后,就来完成服务端的逻辑开发。在服务端的逻辑中, 删除套餐时, 我们不仅要删除套餐, 还要删除套餐与菜品的关联关系。
1). 在SetmealController中创建delete方法
我们可以先测试在delete方法中接收页面提交的参数,具体逻辑后续再完善:
/*** 删除套餐* @param ids* @return*/publicR<String>delete(List<Long>ids){ log.info("ids:{}",ids); returnR.success("套餐数据删除成功"); }
编写完代码,我们重启服务之后,访问套餐列表页面,勾选复选框,然后点击"批量删除",我们可以看到服务端可以接收到集合参数ids,并且在控制台也可以输出对应的数据 。
2). SetmealService接口定义方法removeWithDish
/*** 删除套餐,同时需要删除套餐和菜品的关联数据* @param ids*/publicvoidremoveWithDish(List<Long>ids);
3). SetmealServiceImpl中实现方法removeWithDish
该业务层方法具体的逻辑为:
A. 查询该批次套餐中是否存在售卖中的套餐, 如果存在, 不允许删除
B. 删除套餐数据
C. 删除套餐关联的菜品数据
代码实现为:
/*** 删除套餐,同时需要删除套餐和菜品的关联数据* @param ids*/publicvoidremoveWithDish(List<Long>ids) { //select count(*) from setmeal where id in (1,2,3) and status = 1//查询套餐状态,确定是否可用删除LambdaQueryWrapper<Setmeal>queryWrapper=newLambdaQueryWrapper(); queryWrapper.in(Setmeal::getId,ids); queryWrapper.eq(Setmeal::getStatus,1); intcount=this.count(queryWrapper); if(count>0){ //如果不能删除,抛出一个业务异常thrownewCustomException("套餐正在售卖中,不能删除"); } //如果可以删除,先删除套餐表中的数据---setmealthis.removeByIds(ids); //delete from setmeal_dish where setmeal_id in (1,2,3)LambdaQueryWrapper<SetmealDish>lambdaQueryWrapper=newLambdaQueryWrapper<>(); lambdaQueryWrapper.in(SetmealDish::getSetmealId,ids); //删除关系表中的数据----setmeal_dishsetmealDishService.remove(lambdaQueryWrapper); }
由于当前的业务方法中存在多次数据库操作,为了保证事务的完整性,需要在方法上加注解 @Transactional 来控制事务。
4). 完善SetmealController代码
/*** 删除套餐* @param ids* @return*/publicR<String>delete(List<Long>ids){ log.info("ids:{}",ids); setmealService.removeWithDish(ids); returnR.success("套餐数据删除成功"); }
3.4 功能测试
代码完善后,重启服务,测试套餐的删除功能,主要测试以下几种情况。
1). 删除正在启用的套餐
2). 执行批量操作, 删除两条记录, 一个启售的, 一个停售的
由于当前我们并未实现启售/停售功能,所以我们需要手动修改数据库表结构的status状态,将其中的一条记录status修改为0。