苍穹外卖Day04-套餐管理

因为day-4属于作业部分,主要是完成套餐的CRUD,这里我就写下自己的思路以及代码

这里先实现新增功能,接口图如下:

 (视频里面的接口管理平台已经关闭了,这里是我自己搭建的一个Yapi平台,地址如下,大家可以免费使用YApi Pro-高效、易用、功能强大的可视化接口管理平台

首先在DishController添加一个根据分类id查询菜品的控制类:

 /**
     * 根据分类ID查询菜品
     * @param categoryId
     * @return
     */
   @GetMapping("/list")
   @ApiOperation("根据分类id查询菜品")
   public  Result<List<Dish>> list(Long categoryId){
       log.info("分类id查询菜品:{}",categoryId);
       List<Dish> list= dishService.getList(categoryId);
       return Result.success(list);
        
   }

在DishService写上方法

 /**
     * 根据分类id查询菜品
     * @param categoryId
     * @return
     */
    List<Dish> getList(Long categoryId);

在DishServiceImpl实现一下方法:
 

 /**
     * 根据分类ID查询菜品
     * @param categoryId
     * @return
     */
    @Override
    public List<Dish> getList(Long categoryId) {
        Dish dish= Dish.builder()
                .categoryId(categoryId)
                .status(StatusConstant.ENABLE)
                .build();
        return dishMapper.list(dish);
        return null;
    }

编写Dishmapper.xml,这里我们采用的是动态查询,所以我们使用xml编写,而不是注释,将查询出来的结果根据创建时间进行降序排序:

<select id="list" resultType="com.sky.entity.Dish">
        select * from dish
        <where>
            <if test="name != null">
                and name like concat('%',#{name},'%')
            </if>
            <if test="categoryId != null">
                and category_id = #{categoryId}
            </if>
            <if test="status != null">
                and status = #{status}
            </if>
        </where>
        order by create_time desc
    </select>

接下来我们做套餐管理的新增,这里大家可以测试一下查询功能

”------------------------------------------------分割线-----------------------------------------------------------------“

新建一个SetmealController控制类,新建SetmealService和SetmealServiceimpl类,这里我就省略创建步骤了,大家自行创建:

 


/**
 * 套餐管理
 */

@RestController
@RequestMapping("/admin/setmeal")
@Api(tags = "套餐管理相关接口")
@Slf4j
public class SetmealController {
  
    @Autowired
    private SetmealService setmealService;


}

编写新增控制方法:
 


    @PostMapping
    @ApiOperation("新增套餐")
    public Result save(@RequestBody SetmealDTO setmealDTO){
        //根据前面老师的思路采用DTO作为对象
        log.info("新增菜品信息:{}",setmealDTO);
        setmealService.saveWithDish(setmealDTO);
        return null;
    }

在setmealService类新增方法,然后实现方法,我这里直接省略了service的步骤,直接写实现类的具体代码:

/**
     * 新增套餐,同时需要保存套餐和菜品的关联光系
     * @param setmealDTO
     */
    @Override
    public void saveWithDish(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        //使用工具类将对象进行拷贝
        BeanUtils.copyProperties(setmealDTO,setmeal);
        
        //向套餐插入数据
        setmealMapper.insert(setmeal);
        //获取生成套餐的id
        Long setmealId = setmeal.getId();
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        setmealDishes.forEach(setmealDish -> 
                setmealDish.setSetmealId(setmealId)
        );
        //保存套餐和菜品的关联关系
        setmealDishMapper.insertBatch(setmealDishes);
        
    }

编写SetmealMapper.xml和SetmealDishMapper.xml

<mapper namespace="com.sky.mapper.SetmealMapper">
    <insert id="insert" parameterType="Setmeal" useGeneratedKeys="true" keyProperty="id">
        insert into setmeal
        (category_id, name, price, status, description, image, create_time, update_time, create_user, update_user)
        values (#{categoryId}, #{name}, #{price}, #{status}, #{description}, #{image}, #{createTime}, #{updateTime},
                #{createUser}, #{updateUser})
    </insert>
<mapper namespace="com.sky.mapper.SetmealMapper">
    <insert id="insert" parameterType="Setmeal" useGeneratedKeys="true" keyProperty="id">
        insert into setmeal
        (category_id, name, price, status, description, image, create_time, update_time, create_user, update_user)
        values (#{categoryId}, #{name}, #{price}, #{status}, #{description}, #{image}, #{createTime}, #{updateTime},
                #{createUser}, #{updateUser})
    </insert>

测试功能:

 

 ”----------------------------------------------------分割线-----------------------------------------------------------------“

 接下来我们进行分页查询代码编写,下面是接口设计图:

 在控制类编写方法:

 /**
     * 套餐的分页查询
     * @param setmealPageQueryDTO
     * @return
     */
    @GetMapping("/page")
    @ApiOperation("分页查询套餐")
    public Result<PageResult> page(SetmealPageQueryDTO setmealPageQueryDTO){
        log.info("套餐的分页查询:{}",setmealPageQueryDTO);
        PageResult pageResult= setmealService.pageQuery(setmealPageQueryDTO);
        return  Result.success(pageResult);
    }

编写SetmealServiceImpl实现类:

/**
     * 套餐的分页查询
     * @param setmealPageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {
        int pageNum = setmealPageQueryDTO.getPage();
        int pageSize = setmealPageQueryDTO.getPageSize();

        PageHelper.startPage(pageNum, pageSize);
        Page<SetmealVO> page = setmealMapper.pageQuery(setmealPageQueryDTO);
        return new PageResult(page.getTotal(), page.getResult());
        return null;
    }

编写SetmealMapper.xml文件

 <select id="pageQuery" resultType="com.sky.vo.SetmealVO">
        select
        s.*,c.name categoryName
        from
        setmeal s
        left join
        category c
        on
        s.category_id = c.id
        <where>
            <if test="name != null">
                and s.name like concat('%',#{name},'%')
            </if>
            <if test="status != null">
                and s.status = #{status}
            </if>
            <if test="categoryId != null">
                and s.category_id = #{categoryId}
            </if>
        </where>
        order by s.create_time desc
    </select>

测试功能我直接采用前后端联调了:

”--------------------------------------------------------分割线-----------------------------------------------------------“ 

接下来我们进行删除套餐和批量删除的功能代码编写,接口设计如下:

 在SetmealController控制类编写方法:

 
/**
     * 批量删除套餐
     * @param ids
     * @return
     */
    @DeleteMapping
    @ApiOperation("批量删除套餐")
    public  Result delete(@RequestParam List<Long> ids){
        log.info("批量删除套餐",ids);
        setmealService.deleteBatch(ids);
        return  Result.success();
        
    }

在SetmealService和SetmealServiceImpl编写实现方法:

 /**
     * 批量删除套餐
     * @param ids
     */
    @Override
    @Transactional
    public void deleteBatch(List<Long> ids) {
        ids.forEach(id -> {
            Setmeal setmeal = setmealMapper.getById(id);
            if(StatusConstant.ENABLE == setmeal.getStatus()){
                //起售中的套餐不能删除
                throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
            }
        });

        ids.forEach(setmealId -> {
            //删除套餐表中的数据
            setmealMapper.deleteById(setmealId);
            //删除套餐菜品关系表中的数据
            setmealDishMapper.deleteBySetmealId(setmealId);
        });

此处的删除SQL语句比较简单,我们就采用注解的方式写:

编写SetmealMapper类:

  /**
     * 根据id查询套餐
     * @param id
     * @return
     */
    @Select("select * from setmeal where id = #{id}")
    Setmeal getById(Long id);

    /**
     * 根据id删除套餐
     * @param setmealId
     */
    @Delete("delete from setmeal where id = #{id}")
    void deleteById(Long setmealId);

编写SetmealDishMapper类:

 /**
     * 根据id删除套餐和菜品的关联关系
     * @param setmealId
     */
    @Delete("delete from setmeal_dish where setmeal_id = #{setmealId}")
    void deleteBySetmealId(Long setmealId);

测试一下:

“------------------------------------------------分割线-----------------------------------------------------------------” 

接下里我们进行修改菜品的代码编写,接口设计图如下,我们修改的话,按照之前的经验,需要在修改的时候回显数据,所以我们需要先定义一个查询方法,查询出套餐信息:

 

 老样子,我们还是先编写控制类的方法,注意,因为我们需要回显数据,所以这里需要编写两个方法,一个用于查询回显数据,一个用于修改套餐信息:

/**
     * 根据id查询套餐
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @ApiOperation("根据id查询套餐")
    public  Result<SetmealVO> getById(@PathVariable Long id){
        log.info("根据ID查询的数据:{}",id);
        SetmealVO setmealVO= setmealService.getByIdWithDish(id);
        return  Result.success(setmealVO);
    }


    /**
     * 修改套餐
     * @param setmealDTO
     * @return
     */
    @PutMapping
    @ApiOperation("修改套餐")
    public  Result update(@RequestBody SetmealDTO setmealDTO){
        log.info("修改的菜品信息:{}",setmealDTO);
        setmealService.update(setmealDTO);
        return Result.success();
    }

编写SetmealServiceImpl类,这里修改信息,我们先修改套餐表,对于Setmeal_dish表我们采用先删除,然后再插入来修改:

 /**
     * 根据id查询套餐和菜品套餐信息
     * @param id
     * @return
     */
    @Override
    public SetmealVO getByIdWithDish(Long id) {
        Setmeal setmeal = setmealMapper.getById(id);
        List<SetmealDish> setmealDishes = setmealDishMapper.getBySetmealId(id);

        SetmealVO setmealVO = new SetmealVO();
        BeanUtils.copyProperties(setmeal, setmealVO);
        setmealVO.setSetmealDishes(setmealDishes);

        return setmealVO;
    }

    /**
     * 修改套餐
     * @param setmealDTO
     */
    @Transactional
    @Override
    public void update(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO, setmeal);

        //修改套餐表,执行update
        setmealMapper.update(setmeal);

        //获取套餐id
        Long setmealId = setmealDTO.getId();

        //2、删除套餐和菜品的关联关系,操作setmeal_dish表,执行delete
        setmealDishMapper.deleteBySetmealId(setmealId);

        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        setmealDishes.forEach(setmealDish -> {
            setmealDish.setSetmealId(setmealId);
        });
        //重新插入套餐和菜品的关联关系,操作setmeal_dish表,执行insert
        setmealDishMapper.insertBatch(setmealDishes);

    }

编写SetmealDishMapper类的查询方法,很简单的SQL语句我们一律采用注解写:

/**
     * 根据id查询套餐和菜品的关联信息
     * @param id
     * @return
     */
    @Select("select * from setmeal_dish where setmeal_id = #{setmealId}")
    List<SetmealDish> getBySetmealId(Long id);

功能测试:

 

 “----------------------------------------------分割线---------------------------------------------------------”

我们进行最后的起售or停售功能测试老规矩,先写控制类,接口设计如下:

编写 SetmealController控制类:
 

 @PostMapping("/status/{status}")
    @ApiOperation("套餐起售或者停售接口")
    public  Result startOrStop (@PathVariable Integer status,Long id){
        log.info("起售或停售套餐信息",status,id);
        setmealService.startOrStop(status,id);
        return  Result.success();
    }

编写SetmealServiceImpl实现类,原谅我的懒,service类我就没写了:

/**
     * 起售或者停售套餐
     * @param status
     * @param id
     */
    @Override
    public void startOrStop(Integer status, Long id) {
        //因为套餐和菜品又关联关系,所以再启用套餐之前我们先判定一下是否有包含菜品停售,如果有的话就没法启用套餐
        if(status == StatusConstant.ENABLE){
            //select a.* from dish a left join setmeal_dish b on a.id = b.dish_id where b.setmeal_id = ?
            List<Dish> dishList = dishMapper.getBySetmealId(id);
            if(dishList != null && dishList.size() > 0){
                dishList.forEach(dish -> {
                    if(StatusConstant.DISABLE == dish.getStatus()){
                        throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);
                    }
                });
            }
        }

        Setmeal setmeal = Setmeal.builder()
                .id(id)
                .status(status)
                .build();
        setmealMapper.update(setmeal);

    }

编写DishMapper类查询一下菜品信息看是否有停售:
 


    /**
     * 根据套餐id查询菜品
     * @param id
     * @return
     */
    @Select("select a.* from dish a left join setmeal_dish b on a.id = b.dish_id where b.setmeal_id = #{setmealId}")
    List<Dish> getBySetmealId(Long id);

测试:

 OK,我们整个套餐管理的模块就全部完成啦!!!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值