当前位置: 首页 > news >正文

【项目实战 Day4】springboot + vue 苍穹外卖系统(套餐模块 完结)

目录

一、套餐管理模块

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层

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

    /*** 根据分类id查询菜品* @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.getByCategoryId(dish);return list;}

【3】mapper层

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

【4】mybatis文件

    <select id="getByCategoryId" 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,因此我们要接收一下套餐idLong setmealId = setmeal.getId();//3.把套餐对应菜品列表拆出来List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();//4.给每个菜品附上套餐idif(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 categoryNamefrom sky_take_out.setmeal s left outer join sky_take_out.category con 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();//逐一绑定菜品对应套餐idif(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);}

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

http://www.dtcms.com/a/392851.html

相关文章:

  • 素材库网站分享
  • 第8节-PostgreSQL数据类型-Text
  • React-router和Vue-router底层实现原理
  • 宝藏音乐下载站,免费好用
  • pygame AI snake 大乱斗
  • TCP FIN,TCP RST
  • 睡眠PSG统一数据集的设计思路
  • 告别Vibe Coding!敏捷AI驱动开发:用AI高效构建可维护的复杂项目
  • EA-LSS:边缘感知 Lift-splat-shot 框架用于三维鸟瞰视角目标检测
  • 和为 K 的子数组
  • 从流量红利到运营核心:“开源AI智能名片+链动2+1模式+S2B2C商城小程序”驱动电商行业价值重构
  • 【ICLR 2024】MogaNet:多阶门控聚合网络
  • 小语言模型(SLM):构建可扩展智能体AI的关键
  • ​​[硬件电路-293]:不同频率对应不同周期时间对应表
  • 自定义你的tqdm
  • Tiny10 os是啥?原来是精简的Windows10
  • ThingsBoard部署APP过程错误-flutterr Resolving dependencies
  • webpack入门基础
  • 机器视觉VUE3手势识别+手势检测控制相机缩放
  • AI大模型:(三)1.3 Dify文本生成快速搭建旅游助手
  • Linux文件下载卡在0%进度问题处理
  • 【车载开发系列】区分Flash,RAM与E2PROM的概念
  • 未来展望:小模型撬动大未来
  • TenstoRT加速YOLOv11——python端加速
  • 探索LiveTalking:开启实时数字人交互新时代
  • 【开题答辩全过程】以 Javaweb的火花流浪动物救助系统设计与实现为例,包含答辩的问题和答案
  • 链家二手房数据爬虫与预测项目 Python 线性回归 Scrapy+Django+Echarts 机器学习 大数据✅
  • Heptagon: 一项Scade工具的学术版原型
  • 师徒对决!阿森纳战曼城伤病情况 预计两队共11人缺席
  • 第37篇:AI伦理:偏见、公平性与负责任的人工智能