苍穹外卖04 (新增内表的外键id获取,多表分页查询,多表批量删除,修改先查在改内表外键id用主表的,起售时包含了“停售”状态的外关联表)

1. 新增套餐

1 需求分析和设计

业务规则:

  • 套餐名称唯一

  • 套餐必须属于某个分类

  • 套餐必须包含菜品

  • 名称、分类、价格、图片为必填项

  • 添加菜品窗口需要根据分类类型来展示菜品

  • 新增的套餐默认为停售状态

2 代码实现

1 根据分类id查询菜品

DishController@GetMapping("/list")
@ApiOperation("根据分类id查询菜品列表")
public Result queryDishesByCategoryId(Long categoryId){return dishService.queryDishesByCategoryId(categoryId);
}----------------
DishService/*** 根据分类id查询菜品列表* @param categoryId 分类id* @return categoryId对应的菜品列表*/
Result queryDishesByCategoryId(Long categoryId);----------------
DishServiceImpl@Override
public Result queryDishesByCategoryId(Long categoryId) {List<Dish> dishes = dishMapper.selectByCategoryId(categoryId);return Result.success(dishes);
}----------------
DishMapper@Select("select * from dish where category_id = #{categoryId}")
List<Dish> selectByCategoryId(Long categoryId);

2 新增套餐

SetmealControllerpackage com.sky.controller.admin;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.result.Result;
import com.sky.service.SetmealService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@Api(tags = "套餐管理相关接口")
@RequestMapping("/admin/setmeal")
public class SetmealController {@Autowiredprivate SetmealService setmealService;@PostMapping@ApiOperation("新增套餐")public Result addSetmeal(@RequestBody SetmealDTO dto){return setmealService.addSetmeal(dto);}
}-----------------
SetmealServicepackage com.sky.service;
import com.sky.dto.SetmealDTO;
import com.sky.result.Result;
import java.util.List;public interface SetmealService {Result addSetmeal(SetmealDTO dto);}-----------------
SetmealServiceImplpackage com.sky.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.SetmealMapper;
import com.sky.mapper.SetmeatlDishMapper;
import com.sky.result.PageResult;
import com.sky.result.Result;
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;
@Service
public class SetmealServiceImpl implements SetmealService {@Autowiredprivate SetmealMapper setmealMapper;@Autowiredprivate SetmeatlDishMapper setmealDishMapper;@Override@Transactionalpublic Result addSetmeal(SetmealDTO dto) {//1. 保存套餐Setmeal setmeal = new Setmeal();BeanUtils.copyProperties(dto, setmeal);setmealMapper.insert(setmeal);//2. 保存套餐里关联的菜品List<SetmealDish> setmealDishes = dto.getSetmealDishes();if (setmealDishes != null && setmealDishes.size() > 0) {setmealDishes.forEach(setmealDish -> setmealDish.setSetmealId(setmeal.getId()));setmealDishMapper.batchInsert(setmealDishes);}return Result.success();}
}-----------------
SetmealMapper/*** 新增套餐* @param setmeal*/
@AutoFill(OperationType.INSERT)
@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("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})")
void insert(Setmeal setmeal);-------------------
SetmeatlDishMappervoid batchInsert(List<SetmealDish> setmealDishes);----------------
SetmeatlDishMapper.xml<insert id="batchInsert">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. 套餐分页查询

1 需求分析和设计

业务规则:

  • 根据页码进行分页展示

  • 每页展示10条数据

  • 可以根据需要,按照套餐名称、分类、售卖状态进行查询

2 代码实现

SetmealController@GetMapping("/page")
@ApiOperation("分页查询套餐")
public Result querySetmealsByPage(SetmealPageQueryDTO dto){return setmealService.querySetmealsByPage(dto);
}----------------
SetmealService/*** 分页查询套餐* @param dto* @return*/
Result querySetmealsByPage(SetmealPageQueryDTO dto);----------------
SetmealServiceImpl@Override
public Result querySetmealsByPage(SetmealPageQueryDTO dto) {//1. 开启分页PageHelper.startPage(dto.getPage(), dto.getPageSize());//2. 查询列表Page<SetmealVO> page = setmealMapper.selectByPage(dto);//3. 封装结果PageResult pageResult = new PageResult(page.getTotal(), page.getResult());return Result.success(pageResult);
}--------------
SetmealMapper/*** 分页查询套餐列表* @param dto* @return*/
Page<SetmealVO> selectByPage(SetmealPageQueryDTO dto);--------------
SetmealMapper.xml<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sky.mapper.SetmealMapper"><select id="selectByPage" 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 name.length()>0">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 s.create_time desc</select>
</mapper>

3. 删除套餐

1 需求分析和设计

业务规则:

  • 可以一次删除一个套餐,也可以批量删除套餐

  • 起售中的套餐不能删除

2 代码实现

SetmealController@DeleteMapping
@ApiOperation("删除套餐")
public Result batchDeleteSetmealsByIds(@RequestParam List<Long> ids){return setmealService.batchDeleteSetmealsByIds(ids);
}----------
SetmealService/*** 批量删除套餐* @param ids
*/
Result batchDeleteSetmealsByIds(List<Long> ids);----------
SetmealServiceImpl@Override
@Transactional
public Result batchDeleteSetmealsByIds(List<Long> ids) {//1. 如果有某个套餐是“起售”状态,则不允许删除int count = setmealMapper.selectEnableSetmealsCount(ids);if (count > 0) {throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);}//2. 删除套餐setmealMapper.batchDeleteByIds(ids);//3. 删除套餐关联的菜品setmealDishMapper.batchDeleteBySetmealIds(ids);return Result.success();
}-----------
SetmealMapper/*** 查询 ids对应的套餐中,起售状态的套餐 数量* @param ids* @return*/
int selectEnableSetmealsCount(List<Long> ids);/*** 根据ids批量删除套餐* @param ids*/
void batchDeleteByIds(List<Long> ids);------------
SetmealMapper.xml<select id="selectEnableSetmealsCount" resultType="int">select count(*) from setmeal where status = 1 and<foreach collection="ids" item="id" separator="," open="id in(" close=")">#{id}</foreach>
</select><delete id="batchDeleteByIds">delete from setmeal where id in<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach>
</delete>---------------
SetmeatlDishMapper/*** 根据套餐ids,批量删除这些套餐包含的菜品关联关系* @param ids*/
void batchDeleteBySetmealIds(List<Long> ids);-----------
SetmeatlDishMapper.xml<delete id="batchDeleteBySetmealIds">delete from setmeal_dish where setmeal_id in<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach>
</delete>

4. 修改套餐

1 需求分析和设计

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

  • 根据id查询套餐

  • 根据类型查询分类(已完成)

  • 根据分类id查询菜品(已完成)

  • 图片上传(已完成)

  • 修改套餐

2 代码实现

1 根据id查询套餐

SetmealController@GetMapping("/{id}")
@ApiOperation("根据id查询套餐")
public Result querySetmealById(@PathVariable("id") Long id) {return setmealService.querySetmealById(id);
}----------
SetmealService/*** 根据id查询套餐* @param id* @return*/
Result querySetmealById(Long id);-----------
SetmealServiceImpl@Override
public Result querySetmealById(Long id) {//查询套餐信息Setmeal setmeal = setmealMapper.selectById(id);//查询套餐关联的菜品列表List<SetmealDish> setmealDishes = setmealDishMapper.selectBySetmealId(id);//封装成VO对象SetmealVO vo = new SetmealVO();BeanUtils.copyProperties(setmeal, vo);vo.setSetmealDishes(setmealDishes);return Result.success(vo);
}----------
SetmealMapper/*** 根据id查询套餐* @param id* @return*/
@Select("select * from setmeal where id = #{id}")
Setmeal selectById(Long id);----------
SetmeatlDishMapper/*** 根据套餐id,查询套餐内包含的菜品* @param setmealId* @return*/
@Select("select * from setmeal_dish where setmeal_id = #{setmealId}")
List<SetmealDish> selectBySetmealId(Long setmealId);

2 修改套餐

SetmealController@PutMapping
@ApiOperation("修改套餐")
public Result updateSetmeal(@RequestBody SetmealDTO dto){return setmealService.updateSetmeal(dto);
}----------
SetmealService/*** 修改套餐* @param dto* @return*/
Result updateSetmeal(SetmealDTO dto);----------
SetmealServiceImpl@Override
@Transactional
public Result updateSetmeal(SetmealDTO dto) {//1. 修改套餐Setmeal setmeal = new Setmeal();BeanUtils.copyProperties(dto, setmeal);setmealMapper.updateById(setmeal);//2. 修改套餐关联的菜品//2.1 删除套餐 之前关联的菜品setmealDishMapper.batchDeleteBySetmealIds(Collections.singletonList(dto.getId()));//2.2 重新添加 关联的菜品List<SetmealDish> setmealDishes = dto.getSetmealDishes();if (setmealDishes != null && setmealDishes.size() > 0) {setmealDishes.forEach(setmealDish -> setmealDish.setSetmealId(setmeal.getId()));setmealDishMapper.batchInsert(setmealDishes);}return Result.success();
}-----------
SetmealMapper/*** 根据id修改套餐* @param setmeal*/
@AutoFill(OperationType.UPDATE)
void updateById(Setmeal setmeal);-----------
SetmealMapper.xml<update id="updateById">UPDATE setmeal<set><if test="categoryId!=null">category_id = #{categoryId},</if><if test="name!=null and name.length()>0">name = #{name},</if><if test="price!=null">price = #{price},</if><if test="status!=null">status = #{status},</if><if test="description!=null and description.length()>0">description = #{description},</if><if test="image!=null and image.length()>0">image = #{image},</if><if test="updateTime!=null">update_time = #{updateTime},</if><if test="updateUser!=null">update_user = #{updateUser}</if></set>WHERE id = #{id}
</update>

5. 起售停售套餐

1 需求分析和设计

业务规则:

  • 可以对状态为起售的套餐进行停售操作,可以对状态为停售的套餐进行起售操作

  • 起售的套餐可以展示在用户端,停售的套餐不能展示在用户端

  • 起售套餐时,如果套餐内包含停售的菜品,则不能起售

2 代码实现

SetmealController@PostMapping("/status/{status}")
@ApiOperation("启用禁用套餐")
public Result updateStatus(@PathVariable("status") Integer status, Long id){return setmealService.updateStatus(id, status);
}--------------
SetmealService/*** 套餐起售、停售* @param status* @param id
*/
Result updateStatus(Long id, Integer status);-------------
SetmealServiceImpl@Autowired
private DishMapper dishMapper;@Override
public Result updateStatus(Long id, Integer status) {//起售套餐时,如果包含了“停售”状态的菜品,则不允许起售if (StatusConstant.ENABLE.equals(status)) {//查询套餐关联的所有菜品List<Dish> dishes = dishMapper.selectBySetmealId(id);//如果有任意一个菜品是“停售”状态,就抛出异常long count = dishes.stream().filter(dish -> dish.getStatus().equals(StatusConstant.DISABLE)).count();if (count > 0) {throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);}}//起售/停售套餐Setmeal setmeal = Setmeal.builder().id(id).status(status).build();setmealMapper.updateById(setmeal);return Result.success();
}-----------
DishMapper/*** 根据套餐id查询菜品* @param setmealId* @return
*/
@Select("select * from dish where id in(select dish_id from setmeal_dish where setmeal_id = #{setmealId})")
List<Dish> selectBySetmealId(Long setmealId);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/784138.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言环境】Sublime中运行C语言时MinGW环境的安装

要知道&#xff0c;GCC 官网提供的 GCC 编译器是无法直接安装到 Windows 平台上的&#xff0c;如果我们想在 Windows 平台使用 GCC 编译器&#xff0c;可以安装 GCC 的移植版本。 目前适用于 Windows 平台、受欢迎的 GCC 移植版主要有 2 种&#xff0c;分别为 MinGW 和 Cygwin…

数据分析之POWER BI Desktop可视化应用案列

在power bi中导入数据 导入前期建好的模型 简单介绍&#xff08;power bi desktop&#xff09; 将右边字段全部展开 各类数据 所作的模型 在excel中是单向的&#xff0c;power bi 中可以是双向的 右键单击----点击属性 选择两个---在两个方向上应用安全筛选器 变为双向的…

每日面经分享(pytest入门)

1. pytest具有什么功能 a. 自动发现和执行测试用例&#xff1a;pytest可以自动发现项目中的测试文件和测试函数&#xff0c;无需手动编写测试套件或测试运行器。 b. 丰富的断言函数&#xff1a;pytest提供了丰富的断言函数&#xff0c;方便地验证测试结果是否符合预期。断言函…

flask的使用学习笔记1

跟着b站学的1-06 用户编辑示例_哔哩哔哩_bilibili flask是一个轻量级&#xff0c;短小精悍&#xff0c;django大而全 创建&#xff1a; manage.py和一个和项目名称相同的目录&#xff08;static&#xff08;前端生成的dist&#xff09;、templates&#xff08;html文件&…

【吴恩达机器学习笔记】神经网络初探

前言 传统机器学习不足 【例】预测房价&#xff0c;不同的房子有上百个特征 如果要包含所有的二次项&#xff08;即使只是二次&#xff09;&#xff0c;最终也有很多项&#xff0c; 每个参数都有 n 个变量&#xff0c;那二次项数量将会是 n^2 /2 级别的量级&#xff0c;模型…

并查集

本文用于个人算法竞赛学习&#xff0c;仅供参考 目录 一.什么是并查集 二.并查集实现 三.路径优化 四.时间复杂度 五.并查集路径压缩 模板 五.题目 一.什么是并查集 并查集&#xff08;Disjoint Set&#xff09;是一种数据结构&#xff0c;用于处理一系列不相交的集合的合…

一文了解JAVA的常用API

目录 常用kpimathSystemRuntimeObjectObjectsBigIntegerBigDecima正则表达式包装类 常用kpi 学习目的&#xff1a; 了解类名和类的作用养成查阅api文档的习惯 math 工具类。因为是工具类&#xff0c;因此直接通过类名.方法名(形参)即可直接调用 abs&#xff1a;获取参数绝对…

Linux学习:进程(4)程序地址空间(笔记)

目录 1. Linux下各种资源的内存分布2. 物理地址与虚拟(线性)地址3. 程序地址空间的区域划分4. 地址映射与页表5. 缺页中断 1. Linux下各种资源的内存分布 2. 物理地址与虚拟(线性)地址 在有关进程创建的初步学习中&#xff0c;我们了解了fork函数创建子进程的方式。此种进程的创…

Spring Boot 一.基础和项目搭建(上)

之前也自学过SSM框架&#xff0c;Spring Boot框架&#xff0c;也动手写过几个项目&#xff0c;但是这是第一次完整的记录。从0开始&#xff0c;把一些细节整理了一下。 大概会分为十几小节&#xff0c;这是一个学习的过程&#xff0c;更是一个思考的过程&#xff0c;废话不多说…

金融汽车科技LLM

汇丰银行 众安保险 1. AIGC重塑保险价值链 小额高频 2.构建智能应用的技术方案演进 增加微服务 长记忆&#xff1a;向量库短记忆&#xff1a;对话历史&#xff0c;思考路径&#xff0c;执行历史 中台架构设计 蔚来汽车在大模型的应用实践 公司介绍 应用架构 应用实践 4.大…

Django框架之DRF(武沛齐全)

一、FBV和CBV FBV&#xff0c;function base views&#xff0c;其实就是编写函数来处理业务请求。 from django.contrib import admin from django.urls import path from app01 import views urlpatterns [path(users/, views.users), ] from django.http import JsonResp…

快速排序---算法

1、算法概念 快速排序&#xff1a;通过一趟排序将待排记录分隔成独立的两部分&#xff0c;其中一部分记录的数据均比另一部分的数据小&#xff0c;则可分别对这两部分记录继续进行排序&#xff0c;以达到震哥哥序列有序。 快速排序的最坏运行情况是O()&#xff0c;比如说顺序数…

网络基础二补充——json与http协议

五、市面上常用序列化和反序列化工具 ​ 常用的有&#xff1a;json、protobuf、xml三种方案&#xff1b; 5.1json的使用 1.安装jsoncpp库&#xff0c;是一个第三方的开发库文件&#xff1b; sudo yum install -y jsoncpp-devel2.使用json ​ 经常使用的头文件是json.h&…

【uC/OS-III篇】uC/OS-III 创建第一个任务(For STM32)

uC/OS-III 创建第一个任务&#xff08;For STM32&#xff09; 日期&#xff1a;2024-3-30 23:55&#xff0c;结尾总结了今天学习的一些小收获 本博客对应的项目源码工程 源码项目工程 1. 首先定义错误码变量 // 用于使用uC/OS函数时返回错误码 OS_ERR err; 2. 定义任务控制…

Golang | Leetcode Golang题解之第2题两数相加

题目&#xff1a; 题解&#xff1a; func addTwoNumbers(l1, l2 *ListNode) (head *ListNode) {var tail *ListNodecarry : 0for l1 ! nil || l2 ! nil {n1, n2 : 0, 0if l1 ! nil {n1 l1.Vall1 l1.Next}if l2 ! nil {n2 l2.Vall2 l2.Next}sum : n1 n2 carrysum, carry …

Vue ElementPlus Input输入框

Input 输入框 通过鼠标或键盘输入字符 input 为受控组件&#xff0c;它总会显示 Vue 绑定值。 通常情况下&#xff0c;应当处理 input 事件&#xff0c;并更新组件的绑定值&#xff08;或使用v-model&#xff09;。否则&#xff0c;输入框内显示的值将不会改变。不支持 v-mode…

【面试经典150 | 动态规划】最小路径和

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;动态规划方法二&#xff1a;空间优化 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题…

MCGS学习——水位控制

要求 插入一个水罐&#xff0c;液位最大值为37插入一个滑动输入器&#xff0c;用来调节水罐水位&#xff0c;滑动输入器最大调节为液位最大值&#xff0c;并能清楚的显示出液位情况用仪表显示水位变化情况&#xff0c;仪表最大显示设置直观清楚方便读数&#xff0c;主划线为小…

设计模式-结构型-享元模式Flyweight

享元模式的特点&#xff1a; 享元模式可以共享相同的对象&#xff0c;避免创建过多的对象实例&#xff0c;从而节省内存资源 使用场景&#xff1a; 常用于需要创建大量相似的对象的情况 享元接口类 public interface Flyweight { void operate(String extrinsicState); } 享…

如何使用极狐GitLab 自定义 Pages 根域名

本文作者&#xff1a;徐晓伟 GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 本文主要讲述了极狐GitLab Pages …