0


基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖(八)

套餐模块功能开发

1. 新增套餐

1.1 需求分析和设计

1.1.1产品原型:

在这里插入图片描述
在这里插入图片描述

业务规则:

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

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

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

1.1.2接口设计:

在这里插入图片描述
在这里插入图片描述

1.1.3数据库设计:

setmeal表为套餐表,用于存储套餐的信息。具体表结构如下:
字段名数据类型说明备注idbigint主键自增namevarchar(32)套餐名称唯一category_idbigint分类id逻辑外键pricedecimal(10,2)套餐价格imagevarchar(255)图片路径descriptionvarchar(255)套餐描述statusint售卖状态1起售 0停售create_timedatetime创建时间update_timedatetime最后修改时间create_userbigint创建人idupdate_userbigint最后修改人id
setmeal_dish表为套餐菜品关系表,用于存储套餐和菜品的关联关系。具体表结构如下:
字段名数据类型说明备注idbigint主键自增setmeal_idbigint套餐id逻辑外键dish_idbigint菜品id逻辑外键namevarchar(32)菜品名称冗余字段pricedecimal(10,2)菜品单价冗余字段copiesint菜品份数

1.2 代码开发

1.2.1 DishController层
/**
     * 根据分类id查询菜品
     * @param categoryId
     * @return
*/@GetMapping("/list")@ApiOperation("根据分类id查询菜品")publicResult<List<Dish>>list(Long categoryId){List<Dish> list = dishService.list(categoryId);returnResult.success(list);}
1.2.2 DishService接口类
/**
     * 根据分类id查询菜品
     * @param categoryId
     * @return
*/List<Dish>list(Long categoryId);
1.2.3 DishServiceImpl接口实现类
/**
     * 根据分类id查询菜品
     * @param categoryId
     * @return
*/publicList<Dish>list(Long categoryId){Dish dish =Dish.builder().categoryId(categoryId).status(StatusConstant.ENABLE).build();return dishMapper.list(dish);}
1.2.4 DishMapper层
/**
     * 动态条件查询菜品
     * @param dish
     * @return
*/List<Dish>list(Dish dish);
1.2.5 DishMapper.xml
<selectid="list"resultType="Dish"parameterType="Dish">
    select * from dish
    <where><iftest="name != null">
            and name like concat('%',#{name},'%')
        </if><iftest="categoryId != null">
            and category_id = #{categoryId}
        </if><iftest="status != null">
            and status = #{status}
        </if></where>
    order by create_time desc
</select>
1.2.6 SetmealController层
/**
 * 套餐管理
 */@RestController@RequestMapping("/admin/setmeal")@Api(tags ="套餐相关接口")@Slf4jpublicclassSetmealController{@AutowiredprivateSetmealService setmealService;/**
     * 新增套餐
     * @param setmealDTO
     * @return
     */@PostMapping@ApiOperation("新增套餐")publicResultsave(@RequestBodySetmealDTO setmealDTO){
        setmealService.saveWithDish(setmealDTO);returnResult.success();}}
1.2.7 SetmealService接口类
publicinterfaceSetmealService{/**
     * 新增套餐,同时需要保存套餐和菜品的关联关系
     * @param setmealDTO
     */voidsaveWithDish(SetmealDTO setmealDTO);}
1.2.8 SetmealServiceImpl接口实现类
/**
 * 套餐业务实现
 */@Service@Slf4jpublicclassSetmealServiceImplimplementsSetmealService{@AutowiredprivateSetmealMapper setmealMapper;@AutowiredprivateSetmealDishMapper setmealDishMapper;@AutowiredprivateDishMapper dishMapper;/**
     * 新增套餐,同时需要保存套餐和菜品的关联关系
     * @param setmealDTO
     */@TransactionalpublicvoidsaveWithDish(SetmealDTO setmealDTO){Setmeal setmeal =newSetmeal();BeanUtils.copyProperties(setmealDTO, setmeal);//向套餐表插入数据
        setmealMapper.insert(setmeal);//获取生成的套餐idLong setmealId = setmeal.getId();List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
        setmealDishes.forEach(setmealDish ->{
            setmealDish.setSetmealId(setmealId);});//保存套餐和菜品的关联关系
        setmealDishMapper.insertBatch(setmealDishes);}}
1.2.9 SetmealMapper层
/**
     * 新增套餐
     * @param setmeal
*/@AutoFill(OperationType.INSERT)voidinsert(Setmeal setmeal);
1.2.10 SetmealMapper.xml
<insertid="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.2.11 SetmealDishMapper层
/**
     * 批量保存套餐和菜品的关联关系
     * @param setmealDishes
*/voidinsertBatch(List<SetmealDish> setmealDishes);
1.2.12 SetmealDishMapper.xml
<insertid="insertBatch"parameterType="list">
    insert into setmeal_dish
    (setmeal_id,dish_id,name,price,copies)
    values
    <foreachcollection="setmealDishes"item="sd"separator=",">
        (#{sd.setmealId},#{sd.dishId},#{sd.name},#{sd.price},#{sd.copies})
    </foreach></insert>

2. 套餐分页查询

2.1 需求分析和设计

2.1.1产品原型:

在这里插入图片描述

业务规则:

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

2.1.2接口设计:

在这里插入图片描述

2.2 代码开发

2.2.1 SetmealController层
/**
     * 分页查询
     * @param setmealPageQueryDTO
     * @return
*/@GetMapping("/page")@ApiOperation("分页查询")publicResult<PageResult>page(SetmealPageQueryDTO setmealPageQueryDTO){PageResult pageResult = setmealService.pageQuery(setmealPageQueryDTO);returnResult.success(pageResult);}
2.2.2 SetmealService接口类
/**
     * 分页查询
     * @param setmealPageQueryDTO
     * @return
*/PageResultpageQuery(SetmealPageQueryDTO setmealPageQueryDTO);
2.2.3 SetmealServiceImpl接口实现类
/**
     * 分页查询
     * @param setmealPageQueryDTO
     * @return
*/publicPageResultpageQuery(SetmealPageQueryDTO setmealPageQueryDTO){int pageNum = setmealPageQueryDTO.getPage();int pageSize = setmealPageQueryDTO.getPageSize();PageHelper.startPage(pageNum, pageSize);Page<SetmealVO> page = setmealMapper.pageQuery(setmealPageQueryDTO);returnnewPageResult(page.getTotal(), page.getResult());}
2.2.4 SetmealMapper层
/**
     * 分页查询
     * @param setmealPageQueryDTO
     * @return
*/Page<SetmealVO>pageQuery(SetmealPageQueryDTO setmealPageQueryDTO);
2.2.5 SetmealMapper.xml
<selectid="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><iftest="name != null">
            and s.name like concat('%',#{name},'%')
        </if><iftest="status != null">
            and s.status = #{status}
        </if><iftest="categoryId != null">
            and s.category_id = #{categoryId}
        </if></where>
    order by s.create_time desc
</select>

3. 删除套餐

3.1 需求分析和设计

3.1.1产品原型:

在这里插入图片描述

业务规则:

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

3.1.2接口设计:

在这里插入图片描述

3.2 代码实现

3.2.1 SetmealController层
/**
     * 批量删除套餐
     * @param ids
     * @return
*/@DeleteMapping@ApiOperation("批量删除套餐")publicResultdelete(@RequestParamList<Long> ids){
    setmealService.deleteBatch(ids);returnResult.success();}
3.2.2 SetmealService接口类
/**
     * 批量删除套餐
     * @param ids
*/voiddeleteBatch(List<Long> ids);
3.2.3 SetmealServiceImpl接口实现类
/**
     * 批量删除套餐
     * @param ids
*/@TransactionalpublicvoiddeleteBatch(List<Long> ids){
    ids.forEach(id ->{Setmeal setmeal = setmealMapper.getById(id);if(StatusConstant.ENABLE== setmeal.getStatus()){//起售中的套餐不能删除thrownewDeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);}});

    ids.forEach(setmealId ->{//删除套餐表中的数据
        setmealMapper.deleteById(setmealId);//删除套餐菜品关系表中的数据
        setmealDishMapper.deleteBySetmealId(setmealId);});}
3.2.4 SetmealMapper层
/**
     * 根据id查询套餐
     * @param id
     * @return
*/@Select("select * from setmeal where id = #{id}")SetmealgetById(Long id);/**
     * 根据id删除套餐
     * @param setmealId
*/@Delete("delete from setmeal where id = #{id}")voiddeleteById(Long setmealId);
3.2.5 SetmealDishMapper
/**
     * 根据套餐id删除套餐和菜品的关联关系
     * @param setmealId
*/@Delete("delete from setmeal_dish where setmeal_id = #{setmealId}")voiddeleteBySetmealId(Long setmealId);

4. 修改套餐

4.1 需求分析和设计

4.1.1产品原型:

在这里插入图片描述

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

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.2 代码实现

4.2.1 SetmealController层
/**
     * 根据id查询套餐,用于修改页面回显数据
     *
     * @param id
     * @return
*/@GetMapping("/{id}")@ApiOperation("根据id查询套餐")publicResult<SetmealVO>getById(@PathVariableLong id){SetmealVO setmealVO = setmealService.getByIdWithDish(id);returnResult.success(setmealVO);}/**
     * 修改套餐
     *
     * @param setmealDTO
     * @return
*/@PutMapping@ApiOperation("修改套餐")publicResultupdate(@RequestBodySetmealDTO setmealDTO){
    setmealService.update(setmealDTO);returnResult.success();}
4.2.2 SetmealService接口类
/**
     * 根据id查询套餐和关联的菜品数据
     * @param id
     * @return
*/SetmealVOgetByIdWithDish(Long id);/**
     * 修改套餐
     * @param setmealDTO
*/voidupdate(SetmealDTO setmealDTO);
4.2.3 SetmealServiceImpl接口实现类
/**
     * 根据id查询套餐和套餐菜品关系
     *
     * @param id
     * @return
*/publicSetmealVOgetByIdWithDish(Long id){Setmeal setmeal = setmealMapper.getById(id);List<SetmealDish> setmealDishes = setmealDishMapper.getBySetmealId(id);SetmealVO setmealVO =newSetmealVO();BeanUtils.copyProperties(setmeal, setmealVO);
    setmealVO.setSetmealDishes(setmealDishes);return setmealVO;}/**
     * 修改套餐
     *
     * @param setmealDTO
*/@Transactionalpublicvoidupdate(SetmealDTO setmealDTO){Setmeal setmeal =newSetmeal();BeanUtils.copyProperties(setmealDTO, setmeal);//1、修改套餐表,执行update
    setmealMapper.update(setmeal);//套餐idLong 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);

5. 起售停售套餐

5.1 需求分析和设计

5.1.1产品原型:

在这里插入图片描述

业务规则:

  • 可以对状态为起售的套餐进行停售操作,可以对状态为停售的套餐进行起售操作
  • 起售的套餐可以展示在用户端,停售的套餐不能展示在用户端
  • 起售套餐时,如果套餐内包含停售的菜品,则不能起售

5.1.2接口设计:

在这里插入图片描述

5.2 代码实现

5.2.1 SetmealController层
/**
     * 套餐起售停售
     * @param status
     * @param id
     * @return
*/@PostMapping("/status/{status}")@ApiOperation("套餐起售停售")publicResultstartOrStop(@PathVariableInteger status,Long id){
    setmealService.startOrStop(status, id);returnResult.success();}
5.2.2 SetmealService接口类
/**
     * 套餐起售、停售
     * @param status
     * @param id
*/voidstartOrStop(Integer status,Long id);
5.2.3 SetmealServiceImpl接口实现类
/**
     * 套餐起售、停售
     * @param status
     * @param id
*/publicvoidstartOrStop(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()){thrownewSetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);}});}}Setmeal setmeal =Setmeal.builder().id(id).status(status).build();
    setmealMapper.update(setmeal);}
5.2.4 DishMapper层
/**
     * 根据套餐id查询菜品
     * @param setmealId
     * @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 setmealId);

后记
👉👉💕💕美好的一天,到此结束,下次继续努力!欲知后续,请看下回分解,写作不易,感谢大家的支持!! 🌹🌹🌹


本文转载自: https://blog.csdn.net/m0_59230408/article/details/132915072
版权归原作者 失重外太空. 所有, 如有侵权,请联系我们删除。

“基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖(八)”的评论:

还没有评论