目录

一、套餐管理模块

1、新增套餐模块

(1)根据分类id查询菜品 - GET接口

(2)新增套餐 - POST接口

2、套餐分页查询 - GET接口

3、删除套餐 - DELETE接口

4、根据id查询套餐 - GET接口

5、修改套餐 - PUT接口

5、起售停售套餐 - POST接口


一、套餐管理模块

1、新增套餐模块

实现新增套餐功能,需要实现以下2个接口:

  • 根据分类id查询菜品:用于套餐中添加菜品功能
  • 新增套餐

(1)根据分类id查询菜品 - GET接口

【1】controller层

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

【2】service层

注意:只能返回【起售状态】的菜品

    /**
     * 动态条件查询菜品
     * @param categoryId
     * @return
     */
    public List<Dish> getByCategoryId(Long categoryId) {
        //只能返回【起售状态】的菜品,因此匹配条件为【分类id】和【status=1】
        Dish dish = Dish.builder()
                .status(StatusConstant.ENABLE)
                .categoryId(categoryId)
                .build();
        List<Dish> list = dishMapper.list(dish);
        return list;
    }

【3】mapper层

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

【4】mybatis文件

    <select id="list" resultType="com.sky.entity.Dish">
        select * from sky_take_out.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>

(2)新增套餐 - POST接口

【1】controller层

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

【2】service层

  • 和新增菜品功能类似,前端传来的DTO包含【套餐信息】+【套餐对应菜品列表】
  • 我们需要将其拆开,分别加入套餐表和套餐菜品关系表
  • 注意insert操作不会主动返回已插入的套餐id,而套餐菜品表需要获得套餐id,因此我们在insert的xml语句中加入相关属性,获取套餐id,并将套餐id遍历附给每一个对应菜品,最后将绑定套餐id的菜品表插入套餐菜品关系表中
    /**
     * 新增套餐
     * @param setmealDTO
     */
    public void saveWithDish(SetmealDTO setmealDTO) {
        //SetmealDTO中包含:套餐信息+套餐对应菜品列表
        //1.把套餐信息拆出来加入套餐表
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO,setmeal);
        setmealMapper.insert(setmeal);

        //2.因为insert操作不会自动返回套餐id,而套餐菜品表需要套餐id,因此我们要接收一下套餐id
        Long setmealId = setmeal.getId();

        //3.把套餐对应菜品列表拆出来
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();

        //4.给每个菜品附上套餐id
        if(setmealDishes != null && setmealDishes.size() > 0){
            setmealDishes.forEach(setmealDish -> {
                setmealDish.setSetmealId(setmealId);
            });
            //5.把菜品加入套餐菜品表
            setmealDishMapper.insertBatch(setmealDishes);
        }
    }

【3】mapper层

1)SetmealMapper

    /**
     * 新增套餐
     * @param setmeal
     */
    @AutoFill(value = OperationType.INSERT)
    void insert(Setmeal setmeal);

2)SetmealDishMapper

    /**
     * 批量插入菜品与套餐关系
     * @param setmealDishes
     */
    void insertBatch(List<SetmealDish> setmealDishes);

【4】mybatis文件

1)SetmealMapper

    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
        insert into sky_take_out.setmeal (category_id, name, price, description, image, create_time, update_time, create_user, update_user)
        values
            (#{categoryId},#{name},#{price},#{description},#{image},#{createTime},#{updateTime},#{createUser},#{updateUser})
    </insert>

2)SetmealDishMapper

    <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>

2、套餐分页查询 - GET接口

【1】controller层

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

【2】service层

    /**
     * 套餐分页查询
     * @param setmealPageQueryDTO
     * @return
     */
    public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {

        PageHelper.startPage(setmealPageQueryDTO.getPage(),setmealPageQueryDTO.getPageSize());

        Page<SetmealVO> page = setmealMapper.pageQuery(setmealPageQueryDTO);

        return new PageResult(page.getTotal(),page.getResult());
    }

【3】mapper层

    /**
     * 套餐分页查询
     * @param setmealPageQueryDTO
     * @return
     */
    Page<SetmealVO> pageQuery(SetmealPageQueryDTO setmealPageQueryDTO);

【4】mybatis文件

因为接口要求:返回的数据包括【套餐信息】+【分类名称】,而套餐表中仅有【分类id】

因此我们需要采用左外连接(返回左表全部记录和右表匹配记录,右表无匹配则显示NULL)进行多表联查(以分类id为外键关联套餐表和分类表)

这样我们就可以获得【套餐信息】+【分类名称】

    <select id="pageQuery" resultType="com.sky.vo.SetmealVO">
        select s.*,c.name categoryName
        from sky_take_out.setmeal s left outer join sky_take_out.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>

3、删除套餐 - DELETE接口

起售中的套餐不允许删除

【1】controller层

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

【2】service层

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

        //批量删除套餐
        setmealMapper.deleteBatch(ids);
        //批量删除套餐菜品关系
        setmealDishMapper.deleteByDishBatch(ids);
    }

【3】mapper层

1)SetmealMapper

    /**
     * 批量删除套餐
     * @param SetmealIds
     */
    void deleteBatch(List<Long> SetmealIds);

2)SetmealDishMapper

    /**
     * 批量删除套餐菜品关系
     * @param SetmealIds
     */
    void deleteByDishBatch(List<Long> SetmealIds);

【4】mybatis文件

1)SetmealMapper

    <delete id="deleteBatch">
        delete from sky_take_out.setmeal where id in
        <foreach collection="SetmealIds" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </delete>

2)SetmealDishMapper

    <delete id="deleteByDishBatch">
        delete from setmeal_dish where setmeal_id in 
        <foreach collection="SetmealIds" item="setmealId" open="(" close=")" separator=",">
            #{setmealId}
        </foreach>
    </delete>

4、根据id查询套餐 - GET接口

为了使修改页面,数据可以回显,我们需要通过套餐id查询套餐信息+对应套餐菜品信息

【1】controller层

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

【2】service层

要求返回【套餐信息】+【套餐包含的菜品列表】,因此分别查询最后再合并

    /**
     * 根据id查询套餐
     * @param id
     * @return
     */
    public SetmealVO getById(Long id) {
        //1.先查询套餐信息
        Setmeal setmeal = setmealMapper.getById(id);
        //2.再查询套餐对应菜品
        List<SetmealDish> setmealDishes = setmealDishMapper.getDishBysetmealId(id);
        //3.合并
        SetmealVO setmealVO = new SetmealVO();
        BeanUtils.copyProperties(setmeal,setmealVO);
        setmealVO.setSetmealDishes(setmealDishes);

        return setmealVO;
    }

【3】mapper层

1)SetmealDishMapper

    /**
     * 根据套餐id获取菜品列表
     * @param setmealId
     * @return
     */
    @Select("select * from sky_take_out.setmeal_dish where setmeal_id = #{setmealId}")
    List<SetmealDish> getDishBysetmealId(Long setmealId);

页面成功回显

5、修改套餐 - PUT接口

【1】controller层

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

【2】service层

  • setmealDTO中包含【套餐信息】和【对应菜品列表】,因此分开修改,先修改套餐信息
  • 因为套餐中菜品修改操作会涉及删除和修改,因此我们只需要先把套餐中所有菜品删除,再批量插入即可
    /**
     * 修改套餐
     * @param setmealDTO
     */
    public void update(SetmealDTO setmealDTO) {
        //1.先修改套餐信息
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO,setmeal);
        setmealMapper.update(setmeal);

        //2.先删除现在套餐内所有菜品
        setmealDishMapper.deleteBySetmealId(setmealDTO.getId());

        //3.再重新插入套餐对应菜品
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        //逐一绑定菜品对应套餐id
        if(setmealDishes != null && setmealDishes.size() > 0){
            setmealDishes.forEach(setmealDish -> {
                setmealDish.setSetmealId(setmealDTO.getId());
            });
        }
        setmealDishMapper.insertBatch(setmealDishes);
    }

【3】mapper层

1)SetmealMapper

    /**
     * 修改套餐信息
     * @param setmeal
     */
    @AutoFill(value = OperationType.UPDATE)
    void update(Setmeal setmeal);

2)SetmealDishMapper

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

【4】mybatis文件

1)SetmealMapper

    <update id="update">
        update sky_take_out.setmeal
        <set>
            <if test="name != null">name = #{name},</if>
            <if test="categoryId != null">category_id = #{categoryId},</if>
            <if test="price != null">price = #{price},</if>
            <if test="description != null">description = #{description},</if>
            <if test="image != null">image = #{image},</if>
            <if test="status != null">status = #{status},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
            <if test="updateUser != null">update_user = #{updateUser},</if>
        </set>
        where id = #{id}
    </update>

5、起售停售套餐 - POST接口

【1】controller层

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

【2】service层

    /**
     * 起售停售套餐
     * @param status
     * @param id
     */
    public void startOrStop(Integer status, Long id) {
        Setmeal setmeal = Setmeal.builder()
                .status(status)
                .id(id)
                .build();
        setmealMapper.update(setmeal);
    }

套餐模块开发结束~撒花!

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐