菜品管理模块day06

day06菜品管理

1、新增菜品

1.1、功能分析

  1. 点击新增菜品,进入添加菜品网页【标1】;
  2. 添加完成菜品名称和单价【标2】后,选择菜品所属的菜品分类【标4】【标5】(需要一个菜品分类选择列表功能);
  3. 为需要添加口味偏好的菜品添加特色口味【标6】和【标7】(需要一个口味选择列表功能,前端固定死了,后端省略),
  4. 点击【标8】为菜品添加图片(图片上产),图片上传后,自动执行图片下载(图片显示),这个功能前面已经完成;
  5. 菜品添加完成后,点击【标10】,向后端发送保存请求;

1.2、代码

Category_controller
 /**
     * 查找所有符合条件的数据列表
     * @param categoryListDto dto
     * @return Result<List<Category>>
     */
    @GetMapping("/list")
    @ApiOperation(value = "查找所有符合条件的数据列表" )
    public Result<List<Category>> getList(CategoryListDto categoryListDto) {
        log.info("CategoryListDto={}",categoryListDto);

        //执行查询
        List<Category> list= categoryService.list(categoryListDto);

        return Result.success(list);
    }
Service
    List<Category> list(CategoryListDto categoryListDto);
Impl
@Override
public List<Category> list(CategoryListDto categoryListDto) {
    //1.准备查询条件和排序规则
    LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(categoryListDto.getType() != null,Category::getType,categoryListDto.getType());
    queryWrapper.orderByAsc(Category::getSort).orderByDesc(Category::getUpdateTime);
    
    //2.查询数据
    List<Category> list = super.list(queryWrapper);
    
    //3.返回数据
    return list;
}

1.3、问题
因为Dish实体类不满足接收flavor参数,需要创建一个Dish的子类DishDto,用于封装口味数据

2、删除菜品

控制层

/**
     * 删除指定ID集合的数据
     * @param ids ids
     * @return Result<String>
     */
    @DeleteMapping
    @ApiOperation(value = "根据ID删除当前记录")
    public Result<String> deleteBatch(String[] ids) {
        //log.info("ids={}",ids);

        dishService.deleteBatch(ids);

        return Result.success("删除成功");
    }

接口层

void deleteBatch(String[] ids);

实现类


    @Transactional
    @Override
    public void deleteBatch(String[] ids) {
        //1.逐一遍历
        for (String id : ids) {
            //2.检查是否为售卖状态,售卖状态不允许删除
            Dish dish = super.getById(id);
            if (dish.getStatus().equals(StatusConstant.ENABLE)) {
                //当前菜品处于起售中,不能删除
                throw new DeletionNotAllowedException(dish.getName() + "," + MessageConstant.DISH_ON_SALE);
            }
            //3. 检查是否在套餐中关联了,关联了的菜品不允许删除
            LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SetmealDish::getDishId, id);
            List<SetmealDish> setmealDisheList = setmealDishService.list(queryWrapper);
            if (setmealDisheList != null && setmealDisheList.size() > 0) {
                //当前菜品被套餐关联了,不能删除
                throw new DeletionNotAllowedException(dish.getName() + "," + MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
            }

            //4.允许删除
            super.removeById( Long.valueOf(id));
        }        
    }

3、菜品的状态修改(起售、停售)

控制层


/**
     * 查询指定id的记录
     * @param id id
     * @return Result<Dish>
     */
@GetMapping("/{id}")
@ApiOperation(value = "查询指定id的记录" )
public Result<Dish> getByIdWithFlavor(@PathVariable long id) {
    DishDto dishDto = dishService.getByIdWithFlavor(id);
    log.info("查询到的数据为:{}", dishDto);
    return Result.success(dishDto);
}

接口层

public DishDto getByIdWithFlavor(Long id);

实现类

@Override
public DishDto getByIdWithFlavor(Long id) {
    //1.先根据id查询到对应的dish对象
    Dish dish = this.getById(id);
    
    //2.创建一个dishDao对象
    DishDto dishDto = new DishDto();
    //拷贝对象
    BeanUtils.copyProperties(dish, dishDto);
    
    //3.条件构造器,对DishFlavor表查询
    LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
    //根据dish_id来查询对应的菜品口味数据
    queryWrapper.eq(DishFlavor::getDishId, id);
    //获取查询的结果
    List<DishFlavor> flavors = dishFlavorService.list(queryWrapper);
    //并将其赋给dishDto
    dishDto.setFlavors(flavors);
    
    //4.作为结果返回给前端
    return dishDto;
}

4、流式处理中map和peek的区别

4.1、什么是流式处理?
1.在JavaWeb中,流式处理(Stream Processing)是指对数据流进行连续、实时的处理。它允许你以连续的方式处理输入数据流,并在实时处理过程中逐步生成输出数据流。
2.在JavaWeb开发中,流式处理通常用于处理大规模数据、实时数据或者需要实时响应的场景。流式处理可以提供更高的性能和更低的延迟,因为它可以同时处理数据流的不同部分,而不需要等待全部数据到达。
3.流式处理可以通过使用Java 8引入的Stream API来实现。Stream API是Java的一种函数式编程方式,它提供了一套丰富的操作方法,可以方便地对数据流进行转换、过滤、映射等操作。
4.通过使用流式处理,你可以将数据的处理过程以流水线的方式进行组合,每个处理步骤都可以独立执行,从而实现高效的数据处理和分析。同时,流式处理还提供了一些高级功能,如窗口计算、聚合操作和事件处理等,可以满足不同场景下的需求。
4.2、map和peek的使用方式

map:

  • 功能:map方法用于将流中的每个元素映射到另一个元素上,生成一个新的流。
  • 用法:map方法接收一个Function函数式接口作为参数,该函数接收一个输入元素,并返回一个经过处理后的输出元素。
Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> squaredNumbers = numbers.map(n -> n * n);

peek:

  • 功能:peek方法用于在流的处理过程中执行一个操作,类似于观察者模式的观察者。它不会改变流中的元素,而是提供一个机会在每个元素上执行一些副作用操作,例如打印元素或记录日志。
  • 用法:peek方法接收一个Consumer函数式接口作为参数,该函数接收一个输入元素,并对其执行副作用操作,但不返回任何结果。
Stream<String> names = Stream.of("Alice", "Bob", "Charlie");
names.peek(System.out::println).forEach(name -> {});

总结:

  • map方法用于对输入流中的每个元素进行转换并生成一个新的流。
  • peek方法用于在流的处理过程中执行副作用操作,不会改变流中的元素。
  • 两者的区别在于,map方法会返回一个新的流,而peek方法不会。