content: package com.sky.service.impl;
  
  import com.github.pagehelper.Page;
  import com.github.pagehelper.PageHelper;
  import com.sky.constant.MessageConstant;
  import com.sky.constant.StatusConstant;
  import com.sky.dto.DishDTO;
  import com.sky.dto.DishPageQueryDTO;
  import com.sky.entity.Dish;
  import com.sky.entity.DishFlavor;
  import com.sky.entity.Setmeal;
  import com.sky.exception.DeletionNotAllowedException;
  import com.sky.mapper.*;
  import com.sky.result.PageResult;
  import com.sky.service.DishService;
  import com.sky.vo.DishVO;
  import lombok.extern.slf4j.Slf4j;
  import org.springframework.beans.BeanUtils;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.stereotype.Service;
  import org.springframework.transaction.annotation.Transactional;
  
  import java.util.ArrayList;
  import java.util.List;
  
  /**
   * @version 1.0
   * @Author Imak
   * @Date 2024/8/7 15:44
   * @菜品业务实现类
   */
  @Service
  @Slf4j
  public class DishServiceImpl implements DishService {
      @Autowired
      private DishMapper dishMapper;
  
      @Autowired
      private DishFlavorMapper dishFlavorMapper;
  
      @Autowired
      private SetmealDishMapper setmealDishMapper;
  
      @Autowired
      private SetmealMapper setmealMapper;
      /**
       * 新增菜品和口味
       * @param dishDTO
       */
      @Transactional
      public void saveWithFlavor(DishDTO dishDTO) {
          Dish dish=new Dish();
          BeanUtils.copyProperties(dishDTO,dish);
          //向菜品表插入数据
          dishMapper.insert(dish);
          Long dishId = dish.getId();//获取insert语句生成的主键值
  
          //向口味表插入n条数据
          List<DishFlavor> flavors = dishDTO.getFlavors();
          if(flavors!=null&&flavors.size()>0){
              flavors.forEach(dishFlavor -> {
                  dishFlavor.setDishId(dishId);
              });
              dishFlavorMapper.insertBatch(flavors);
          }
  
      }
  
      /**
       * 菜品分页查询
       * @param dishPageQueryDTO
       */
      public PageResult pageQuery(DishPageQueryDTO dishPageQueryDTO) {
          PageHelper.startPage(dishPageQueryDTO.getPage(),dishPageQueryDTO.getPageSize());
          Page<DishVO> page=dishMapper.pageQuery(dishPageQueryDTO);
          return new PageResult(page.getTotal(),page.getResult());
  
      }
  
      /**
       * 菜品批量删除,(多个表操作，使用事务注解保证一致性@Transactional)
       * @param ids
       */
      @Transactional
      public void deleteBatch(List<Long> ids) {
  
          //判断是否能删除
          //1.菜品是否在售
          for (Long id : ids) {
              Dish dish=dishMapper.getById(id);
              if(dish.getStatus()== StatusConstant.ENABLE){
                  //在售
                  throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
              }
          }
  
          //2.菜品是否关联套餐、
          List<Long> setmealIds=setmealDishMapper.getSetmealIdsByDishIds(ids);
          if(setmealIds!=null&&setmealIds.size()>0){
              throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
          }
  
          //批量删除菜品
          dishMapper.deleteByIds(ids);
  
          for(Long dishId:ids){
              dishFlavorMapper.deleteByDishId(dishId);
          }
  
      }
  
      /**
       * 根据id查询菜品和口味
       * @param id
       * @return
       */
      public DishVO getByIdWithFlavor(Long id) {
          //根据id查询菜品数据
          Dish dish = dishMapper.getById(id);
  
          //根据菜品id查询口味数据
          List<DishFlavor> dishFlavors = dishFlavorMapper.getByDishId(id);//后绪步骤实现
  
          //将查询到的数据封装到VO
          DishVO dishVO = new DishVO();
          BeanUtils.copyProperties(dish, dishVO);
          dishVO.setFlavors(dishFlavors);
  
          return dishVO;
      }
  
      /**
       * 根据id修改菜品基本信息和对应的口味信息
       * @param dishDTO
       */
      public void updateWithFlavor(DishDTO dishDTO) {
          Dish dish = new Dish();
          BeanUtils.copyProperties(dishDTO, dish);
  
          //修改菜品表基本信息
          dishMapper.update(dish);
  
          //删除原有的口味数据
          dishFlavorMapper.deleteByDishId(dishDTO.getId());
  
          //重新插入口味数据
          List<DishFlavor> flavors = dishDTO.getFlavors();
          if (flavors != null && flavors.size() > 0) {
              flavors.forEach(dishFlavor -> {
                  dishFlavor.setDishId(dishDTO.getId());
              });
              //向口味表插入n条数据
              dishFlavorMapper.insertBatch(flavors);
          }
      }
  
      /**
       * 起售停售菜品
       * @param status
       * @param id
       */
      @Transactional
      public void startOrStop(Integer status, Long id) {
          Dish dish=Dish.builder().status(status).id(id).build();
          dishMapper.update(dish);
          if (status == StatusConstant.DISABLE) {
              // 如果是停售操作，还需要将包含当前菜品的套餐也停售
              List<Long> dishIds = new ArrayList<>();
              dishIds.add(id);
              // select setmeal_id from setmeal_dish where dish_id in (?,?,?)
              List<Long> setmealIds = setmealDishMapper.getSetmealIdsByDishIds(dishIds);//利用旧的方法，要求传入一个List数组
              if (setmealIds != null && setmealIds.size() > 0) {
                  for (Long setmealId : setmealIds) {
                      Setmeal setmeal = Setmeal.builder()
                              .id(setmealId)
                              .status(StatusConstant.DISABLE)
                              .build();
                      setmealMapper.update(setmeal);
                  }
              }
          }
      }
  
      /**
       * 根据分类id查询菜品
       * @param categoryId
       * @return
       */
      public List<Dish> list(Long categoryId) {
          Dish dish = Dish.builder()
                  .categoryId(categoryId)
                  .status(StatusConstant.ENABLE)
                  .build();
          return dishMapper.list(dish);
      }
  
      /**
       * 条件查询菜品和口味
       * @param dish
       * @return
       */
      public List<DishVO> listWithFlavor(Dish dish) {
          List<Dish> dishList = dishMapper.list(dish);
  
          List<DishVO> dishVOList = new ArrayList<>();
  
          for (Dish d : dishList) {
              DishVO dishVO = new DishVO();
              BeanUtils.copyProperties(d,dishVO);
  
              //根据菜品id查询对应的口味
              List<DishFlavor> flavors = dishFlavorMapper.getByDishId(d.getId());
  
              dishVO.setFlavors(flavors);
              dishVOList.add(dishVO);
          }
  
          return dishVOList;
      }
  }
  