苍穹外卖Day04套餐管理

1.新增套餐

1.1 需求分析和设计

业务规则: 

  • 套餐名称唯一
  • 套餐必须属于某个分类
  • 套餐必须包含菜品
  • 名称、分类、价格、图片为必填项
  • 添加菜品窗口需要根据分类类型来展示菜品
  • 新增的套餐默认为停售状态

接口设计

  • 根据类型查询分类(已完成)
  • 根据分类id查询菜品
  • 图片上传(已完成)
  • 新增套餐

数据库设计:

setmeal表

setmeal_dish表

1.2 代码实现

1.2.1 SetmealController

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


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






1.2.2 SetmealService

package com.sky.service;

import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.result.PageResult;
import com.sky.vo.SetmealVO;

import java.util.List;

/**
 * @Author wyg
 * @project sky-take-out
 */
public interface SetmealService {
    /**
     *新增套餐和相应的菜品
     * @param setmealDTO
     */
    void saveWithDish(SetmealDTO setmealDTO);

   

}

1.2.3 SetmealServiceImpl

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.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.exception.SetmealEnableFailedException;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.SetmealService;
import com.sky.vo.SetmealVO;
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.List;

/**
 * @Author wyg
 * @project sky-take-out
 */
@Service
public class SetmealServiceImpl implements SetmealService {
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private SetmealDishMapper setmealDishMapper;
    @Autowired
    private DishMapper dishMapper;

    /**
     *新增套餐和相应的菜品
     * @param setmealDTO
     */
    @Transactional
    @Override
    public void saveWithDish(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO,setmeal);
        //向套餐插入数据
        setmealMapper.insert(setmeal);
        //获取生成的套餐id
        Long setmealId = setmeal.getId();
        //向菜品插入n条数据
        List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        if(setmealDishes != null && setmealDishes.size() > 0){
            setmealDishes.forEach(setmealDish -> {
                setmealDish.setSetmealId(setmealId);
            });
            setmealDishMapper.insertBatch(setmealDishes);
        }

    }

   

}

1.2.4 SetmealMapper

package com.sky.mapper;

import com.github.pagehelper.Page;
import com.sky.annotation.AutoFill;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Setmeal;
import com.sky.enumeration.OperationType;
import com.sky.vo.SetmealVO;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface SetmealMapper {

    /**
     * 根据分类id查询套餐的数量
     * @param id
     * @return
     */
    @Select("select count(id) from setmeal where category_id = #{categoryId}")
    Integer countByCategoryId(Long id);
 
    
}

 1.2.5 SetmealDishMapper

package com.sky.mapper;

import com.sky.entity.SetmealDish;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * @Author wyg
 * @project sky-take-out
 */
@Mapper
public interface SetmealDishMapper {
  
    /**
     * 插入菜品套餐关系数据
     * @param setmealDishes
     */
    void insertBatch(List<SetmealDish> setmealDishes);

    
}

1.2.6 SetmealDishMapper.xml

   <insert id="insertBatch">
        insert into setmeal_dish (setmeal_id,dish_id,name,copies,price)
        values
        <foreach collection="setmealDishes" item="setmealDish" separator=",">
            (
             #{setmealDish.setmealId},#{setmealDish.dishId},#{setmealDish.name},#{setmealDish.copies},
           #{setmealDish.price}
            )
        </foreach>
    </insert>

1.2.7 SetmealMapper.xml

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

1.3 功能测试

2. 套餐分页查询

2.1 需求分析和设计

业务规则:

  • 根据页码进行分页展示
  • 每页展示10条数据
  • 可以根据需要,按照套餐名称、分类、售卖状态进行查询

2.2 代码实现

2.2.1 SetmealController

/**
     * 套餐分页查询
     * @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.2.2 SetmealService

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

2.2.3 SetmealServiceImpl

/**
     * 套餐分页查询
     * @param setmealPageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {
        PageHelper.startPage(setmealPageQueryDTO.getPage(),setmealPageQueryDTO.getPageSize());
        Page<SetmealVO> page = setmealMapper.pageQuery(setmealPageQueryDTO);
        PageResult pageResult = new PageResult(page.getTotal(), page.getResult());
        return pageResult;
    }

2.2.4 SetmealMapper

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

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

2.3 功能测试

3. 删除套餐

3.1 需求分析和设计

业务规则:

  • 可以一次删除一个套餐,也可以批量删除套餐
  • 起售中的套餐不能删除

3.2 代码实现

3.2.1 SetmealController

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

3.2.2 SetmealService

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

3.2.3 SetmealServiceImpl

 /**
     * 批量删除套餐
     * @param ids
     */
    @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);
        });
    }

3.2.4 SetmealMapper

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

3.2.5 SetmealDishMapper

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

3.3 功能测试

4. 修改套餐

4.1 需求分析和设计

接口设计(共涉及到5个接口):

  • 根据id查询套餐
  • 根据类型查询分类(已完成)
  • 根据分类id查询菜品(已完成)
  • 图片上传(已完成)
  • 修改套餐

4.2 代码实现

4.2.1 SetmealController

/**
     * 根据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.updateWithDish(setmealDTO);
        return Result.success();
    }

4.2.2 SetmealService

 /**
     * 根据id查询套餐
     * @param id
     * @return
     */
    SetmealVO getByIdWithDish(Long id);

    /**
     * 修改套餐
     * @param setmealDTO
     */
    void updateWithDish(SetmealDTO setmealDTO);

4.2.3 SetmealServiceImpl

/**
     * 根据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
     */
    @Override
    @Transactional
    public void updateWithDish(SetmealDTO setmealDTO) {
        Setmeal setmeal = new Setmeal();
        BeanUtils.copyProperties(setmealDTO,setmeal);
        //1、修改套餐表,执行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);
        });

        //3、重新插入套餐和菜品的关联关系,操作setmeal_dish表,执行insert
        setmealDishMapper.insertBatch(setmealDishes);

4.2.4 SetmealDishMapper

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

4.2.5 SetmealMapper

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

 4.2.6 SetmealMapper.xml

 <update id="update" parameterType="Setmeal">
        update 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="status != null">status = #{status},</if>
            <if test="description != null">description = #{description},</if>
            <if test="image != null">image = #{image},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
            <if test="updateUser != null">update_user = #{updateUser}</if>
        </set>
        where id = #{id}
    </update>

4.3 功能测试

5. 起售停售套餐

5.1 需求分析和设计

产品原型:

5.2 代码实现

5.2.1 SetmealController

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

5.2.2 SetmealService

 /**
     * 修改套餐状态
     * @param status
     * @param id
     */
    void startOrStop(Integer status, Long id);

5.2.3 SetmealServiceImpl

/**
     * 套餐起售、停售
     * @param status
     * @param id
     */
    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);
    }

5.2.4 DishMapper

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

5.3 功能测试

  • 24
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值