苍穹外卖学习 Day04

前言

本篇博客用于记录苍穹外卖Day04套餐管理的学习。由于本章节课程中直接跳过,所以我会全过程进行编码(service接口的代码就省略了)。有什么问题欢迎在评论区指出,可以一起探讨一下
注意:许多思路在代码块使用注释写出来了可以参考,建议自己先按自己的思路编码再来参考我的。

新增套餐

该接口有两个接口需要我们完成开发:1.根据分类id查询菜品 2.新增套餐

根据分类id查询菜品

在该接口,要求我们点击新增套餐->添加菜品后出现以下界面:

在这里插入图片描述

如图所示,左边展示出菜品分类(菜品分类只展示type=1同时status=1的菜品分类),中间展示出该分类下的菜品。

分析接口文档,我们可知传递的参数为categoryId,返回数据为一个菜品集合

在这里插入图片描述

编码如下:

DishController:

	//根据分类id查询菜品
    @GetMapping("/list")
    @ApiOperation("根据分类id查询菜品")
    public Result<List<Dish>> list(Long categoryId){//这里的参数记得要是categoryId
        log.info("根据分类id查询菜品:{}",categoryId);
        List<Dish> list=dishService.getByCategoryId(categoryId);
        return Result.success(list);
    }

DishServiceImpl:

	//根据分类id查询菜品
    @Override
    public List<Dish> getByCategoryId(Long categoryId) {
        //封装好一个Dish对象
        Dish dish=new Dish();
        dish.setCategoryId(categoryId);//根据categoryId查询菜品
        dish.setStatus(StatusConstant.ENABLE);//只查询status=1的菜品
        
        List<Dish> list=dishMapper.list(dish);
        return list;
    }

DishMapper:

List<Dish> list(Dish dish);

DishMapper.xml:

	<!--根据分类id查询菜品-->
    <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>

新增套餐

在该接口,我们不仅要保存套餐信息,还要保存套餐与菜品间的关联信息。

分析接口文档,我们可知传递的参数为SetmealDto,返回插入成功即可

SetmealController:

@RestController
@RequestMapping("/admin/setmeal")
@Slf4j
@Api(tags = "套餐相关接口")
public class SetmealController {

    @Autowired
    private SetmealService setmealService;

    //新增套餐
    @PostMapping
    @ApiOperation("新增套餐")
    private Result save(@RequestBody SetmealDTO setmealDTO){
        log.info("新增套餐:{}",setmealDTO);
        setmealService.save(setmealDTO);
        return Result.success();
    }
}

SetmealServiceImpl:

@Service
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private SetmealDishMapper setmealDishMapper;

    //新增套餐
    @Override
    @Transactional//保证两次插入操作要么同时成功,要么同时失败
    public void save(SetmealDTO setmealDTO) {
        //同时保存套餐与菜品的关联信息

        //1.新增套餐
        Setmeal setmeal=new Setmeal();
        BeanUtils.copyProperties(setmealDTO,setmeal);
        setmealMapper.save(setmeal);

        //获取插入套餐后生成的主键值(id)
        Long setmealId=setmeal.getId();

        //2.保存套餐与菜品的关联信息
        //获取套餐中的菜品
        List<SetmealDish> setmealDishes=setmealDTO.getSetmealDishes();
        for (SetmealDish setmealDish : setmealDishes) {
            //将套餐id设置进SetmelDish对象中
            setmealDish.setSetmealId(setmealId);
        }
        //将套餐id、菜品id等信息保存进setmeal_dish表
        setmealDishMapper.insertBatch(setmealDishes);
    }
}

新增套餐:

SetmealMapper:

	@AutoFill(OperationType.INSERT)
    void save(Setmeal setmeal);

SetmealMapper.xml:

<!--    记得插入之后要将主键值(id)返回-->
    <insert id="save" 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>

保存套餐与菜品的关联信息:

SetmealDishMapper:

void insertBatch(List<SetmealDish> setmealDishes);

SetmealMapper.xml:

	<!--    插入套餐与菜品关联信息-->
    <insert id="insertBatch" parameterType="list">
        insert into setmeal_dish
        (setmeal_id,dish_id,name,price,copies)
        values
        <foreach collection="setmealDishes" item="sd" separator=",">
            (#{sd.setmealId},#{sd.dishId},#{sd.name},#{sd.price},#{sd.copies})
        </foreach>
    </insert>

分页查询

该接口与前面菜品管理的接口差不多

SetmealController:

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

SetmealServiceImpl:

	@Override
    public PageResult page(SetmealPageQueryDTO setmealPageQueryDTO) {
        //开启分页查询
        PageHelper.startPage(setmealPageQueryDTO.getPage(),setmealPageQueryDTO.getPageSize());

        Page<SetmealVO> page=setmealMapper.page(setmealPageQueryDTO);
        return new PageResult(page.getTotal(),page.getResult());
    }

SetmealMapper:

Page<SetmealVO> page(SetmealPageQueryDTO setmealPageQueryDTO);

SetmealMapper.xml:

	<!--分页查询-->
    <select id="page" 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="categoryId!=null">
                and s.category_id=#{categoryId}
            </if>
            <if test="status!=null">
                and s.status=#{status}
            </if>
        </where>
        order by create_time desc
    </select>

删除套餐

删除套餐与上面删除类似,可以一个一个删,也可以批量删除。还有一个就是起售状态的套餐不能删除。

在这里插入图片描述

SetmealController:

	@DeleteMapping
    @ApiOperation("删除套餐")
    private Result delete(@RequestParam List<Long> ids){
        log.info("删除套餐:{}",ids);
        setmealService.delete(ids);
        return Result.success();
    }

SetmealServiceImpl:

	@Override
    @Transactional
    public void delete(List<Long> ids) {
        //判断套餐起售状态
        for (Long id : ids) {
            Setmeal setmeal=setmealMapper.getById(id);
            if(setmeal.getStatus()== StatusConstant.ENABLE){
                throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
            }
        }

        //删除套餐同时删除套餐与菜品的关联信息
        for (Long id : ids) {
            //删除套餐表中的数据
            setmealMapper.deleteById(id);
            //删除套餐菜品表中的关联数据
            setmealDishMapper.deleteBySetmealId(id);
        }
    }

SetmealMapper:

	@Select("select * from setmeal where id=#{id}")
    Setmeal getById(Long id);

    @Delete("delete from setmeal where id=#{id}")
    void deleteById(Long id);

SetmealDishMapper:

	@Delete("delete from setmeal_dish where setmeal_id=#{setmealId}")
    void deleteBySetmealId(Long id);

修改套餐

与之前的修改操作也差不多,简单介绍一下。在该接口,我们需要完成两步操作:1.根据id查询套餐,将原来的套餐信息展示出来先 2.修改套餐

SetmealController:

	@GetMapping("/{id}")
    @ApiOperation("根据id查询套餐")
    private Result<SetmealVO> getById(@PathVariable Long id){
        log.info("根据id查询套餐:{}",id);
        SetmealVO setmealVO=setmealService.getSetmealById(id);
        return Result.success(setmealVO);
    }
    @PutMapping
    @ApiOperation("更新套餐")
    private Result update(@RequestBody SetmealDTO setmealDTO){
        log.info("更新套餐:{}",setmealDTO);
        setmealService.update(setmealDTO);
        return Result.success();
    }

SetmealServiceImpl:

查询套餐时,我们不仅要查套餐信息,还要查套餐关联的菜品的信息。将查到的套餐信息和菜品信息封装成一个SetmealVO对象返回给前端。修改套餐信息时,我们先要修改套餐的信息,然后要将套餐原来关联的菜品信息删除,重新关联新的菜品信息,以此达到一个修改套餐关联菜品的操作

//根据id查询套餐及套餐菜品信息
@Override
public SetmealVO getSetmealById(Long id) {
    //查询套餐
    Setmeal setmeal=setmealMapper.getById(id);
    //获取套餐菜品关联信息
    List<SetmealDish> setmealDishes=setmealDishMapper.getBySetmealId(id);

    //封装SetMeal对象
    SetmealVO setmealVO=new SetmealVO();
    BeanUtils.copyProperties(setmeal,setmealVO);
    setmealVO.setSetmealDishes(setmealDishes);

    //将套餐信息以及套餐菜品信息返回
    return setmealVO;
}

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

    //1.修改套餐信息
    setmealMapper.update(setmeal);

    Long setmealId=setmealDTO.getId();
    //2.删除套餐与菜品间的联系
    setmealDishMapper.deleteBySetmealId(setmealId);

    //3.重新建立套餐与菜品间的联系
    List<SetmealDish> setmealDishes=setmealDTO.getSetmealDishes();
    for (SetmealDish setmealDish : setmealDishes) {
        setmealDish.setSetmealId(setmealId);
    }
    setmealDishMapper.insertBatch(setmealDishes);
}

SetmealDishMapper: 查询套餐关联菜品的信息

	@Select("select * from setmeal_dish where setmeal_id=#{id}")
    List<SetmealDish> getBySetmealId(Long id);

SetmealMapper:

	@AutoFill(OperationType.UPDATE)
    void update(Setmeal setmeal);

SetmealMapper.xml:

	<update id="update">
        update setmeal
        <set>
            <if test="categoryId!=null">
                category_id=#{categoryId},
            </if>
            <if test="name!=null">
                name=#{name},
            </if>
            <if test="price!=null">
                price=#{price},
            </if>
            <if test="status!=null">
                status=#{status},
            </if>
            <if test="description!=null">
                description=#{description},
            </if>
            <if test="image!=null">
                image=#{image},
            </if>
            <if test="createTime!=null">
                create_time=#{createTime},
            </if>
            <if test="updateTime!=null">
                update_time=#{updateTime},
            </if>
            <if test="createUser!=null">
                create_user=#{createUser},
            </if>
            <if test="updateTime!=null">
                update_time=#{updateTime}
            </if>
        </set>
        where id=#{id}
    </update>

起售停售

在此接口主要要注意一个问题:当套餐状态由停售改为起售时,如果套餐内包含停售菜品时,无法起售

SetmealController:

	@PostMapping("/status/{status}")
    @ApiOperation("套餐起售停售")
    private Result status(@PathVariable Integer status,Long id){
        log.info("套餐起售停售:{}{}",status,id);
        setmealService.status(status,id);
        return Result.success();
    }

SetmealServiceImpl:

	@Override
    public void status(Integer status, Long id) {
        //将停售套餐变为起售时,先判断套餐内是否包含停售菜品,如果包含,则无法起售
        if(status==StatusConstant.ENABLE){
            //根据套餐id查菜品表,返回一个集合
            List<Dish> dishes = dishMapper.getDish(id);
            if(dishes!=null&&dishes.size()>0){
                for (Dish dish : dishes) {
                    //菜品集合中包含停售菜品时
                    if(dish.getStatus()==StatusConstant.DISABLE){
                        throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);
                    }
                }
            }
        }
		//修改状态
        Setmeal setmeal=new Setmeal();
        setmeal.setStatus(status);
        setmeal.setId(id);
        setmealMapper.update(setmeal);
    }

DishMapper:

分析一下这个SQL语句,我们要根据套餐的id查询菜品数据,很显然这涉及到多表查询。因为我们传递进来的id是套餐的id,所以查询条件是sd.setmeal_id=#{id}",dish表和setmeal_dish表的连接条件是菜品表的id等于套餐菜品表的菜品id,所以在SQL语句中dish.id=setmeal_dish.dish_id

	@Select("select d.* from dish d left join setmeal_dish sd on d.id=sd.dish_id where sd.setmeal_id=#{id}")
    List<Dish> getDish(Long id);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值