###今天的任务主要是自主完成套餐管理的模块###

1.新增套餐

在前端页面接口中我们可以看到在新增套餐的时候需要选择添加到菜单中的菜品

因此我们需要设计一个接口可以通过根据分类id(category_id)来查询该分类下的菜品

1.1根据分类id查询分类下的菜品

1.DishController

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

2.dishService

    /*** 根据套餐id查询菜品* @param categoryId* @return*/List<Dish> list(Long categoryId);

3.DishServiceImpl

这里需要注意一下,在前端页面中,添加套餐中的菜品可以通过多种的方式搜索:可以直接在展示框中点击(这个就是直接根据id搜索然后回显就好了)、可以通过名字搜索来进行添加(这个就要添加姓名的条件了)。为了方便去进行比较,这里使用对象生成器生成了一个对象,并且对对象进行初始化赋值,这样子就可以更方便的比对。

    /*** 根据分类id查询菜品* @param categoryId* @return*/public List<Dish> list(Long categoryId) {Dish dish = Dish.builder().categoryId(categoryId).status(StatusConstant.ENABLE).build();return dishMapper.list(dish);}

4.DishMapper

这里有多种对比方式,所以肯定选择的是动态的SQL

    <select id="list" resultType="Dish" parameterType="Dish">select * from 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>

1.2新增菜品

我们已经完成了菜品的回显,现在就可以新增菜品了。

1.2.1SetMealController

这里需要注意一下,前端传回来的数据格式,选择合适的dto进行数据的接收。

/*** 套餐管理*/
@RestController
@RequestMapping("/admin/setmeal")
@Api(tags = "套餐相关接口")
@Slf4j
public class SetmealController {@Autowiredprivate SetmealService setmealService;/*** 新增套餐* @param setmealDTO* @return*/@PostMapping@ApiOperation("新增套餐")public Result save(@RequestBody SetmealDTO setmealDTO) {setmealService.saveWithDish(setmealDTO);return Result.success();}
}

1.2.2SetMealServiceImpl

再新增套餐这个业务中,我们需要对两张表个进行操作:套餐表、套餐-菜品表(因为是多对多的关系,所以通过建立第三个表格来关联)

@Service
@Slf4j
public class SetmealServiceImpl implements SetmealService {@Autowiredprivate SetmealMapper setmealMapper;@Autowiredprivate SetmealDishMapper setmealDishMapper;@Autowiredprivate DishMapper dishMapper;/*** 新增套餐,同时需要保存套餐和菜品的关联关系* @param setmealDTO*/@Transactionalpublic void saveWithDish(SetmealDTO setmealDTO) {Setmeal setmeal = new Setmeal();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);}
}

首先使用了BeanUtils工具对对象属性进行复制提取出了setmeal的信息方便对seatmeal表格进行操作

然后获取setmeal中的套餐id(这里的套餐id用来作为连接表的逻辑链接)

使用DTO中的get方法获得所添加的Dishes然后对其中的每一个对象的mealId进行赋值

最后将Dishes插入到表格中

最终完成了套餐的新增。

2.套餐分页查询

套餐分页查询

产品原型:

2.1Controller方法

对于分页查询,我们使用的是pagehelper这个工具类。该工具类可以帮助我们在动态的SQL语句中插入页面数据。(就比如我们正常编写分页查询的SQL语句的时候会有limit这个来限定每页展示的数量,使用了工具类之后他可以帮我们自动添加上去,不需要在编写这个限定)

@GetMapping("/page")
@ApiOperation("分页查询")
public Result<PageResult> page(SetmealPageQueryDTO setmealPageQueryDTO) {PageResult pageResult = setmealService.pageQuery(setmealPageQueryDTO);return Result.success(pageResult);
}

注意:这里使用了pageresult作为返回的变量,因此在方法类型使用了泛型!!!

2.2ServiceImpl方法

前端传过来的页面数量和每页展示记录数通过get方法获取后需要传入到pagehelper的startpage中(可以理解成这样子就可以自动帮我们将页面数量和每页展示记录数据自动映射)

完成之后我们还需要编写基础的SQL语句来对所展示的记录进行返回

public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO) {int pageNum = setmealPageQueryDTO.getPage();int pageSize = setmealPageQueryDTO.getPageSize();PageHelper.startPage(pageNum, pageSize);Page<SetmealVO> page = setmealMapper.pageQuery(setmealPageQueryDTO);return new PageResult(page.getTotal(), page.getResult());
}

2.3Mapper方法

Page<SetmealVO> pageQuery(SetmealPageQueryDTO setmealPageQueryDTO);

2.4Xml

为什么要进行两表联查呢?

首先通过category表中的id字段来链接setmeal表中的vategory_id字段

在分页查找中我们可以通过多种方式来进行查找

分页查找选项

因此需要有三个条件判断 

<select id="pageQuery" resultType="com.sky.vo.SetmealVO">selects.*,c.name categoryNamefromsetmeal sleft joincategory cons.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.删除套餐

1.controller

前端给我们传递了一个id集合,里面包含了要删除的套餐的id(可能没有,可能有一个,可能有多个)

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

 2.serviceimpl

在service层面当我们处理这个id列表的时候,需要注意:

1.起售中的套餐不能删除(判断每一个id对应的setmeal对象中的status属性)

2.删除的时候需要删除菜单表的数据,也需要删除关联表中的数据(添加事务)3.

@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.Mapper

编写的SQL语句比较简单就不过多展示。

4. 修改套餐

对于修改操作,我们都需要对数据进行回显

4.1根据id查询套餐

@GetMapping("/{id}")
@ApiOperation("根据id查询套餐")
public Result<SetmealVO> getById(@PathVariable Long id) {SetmealVO setmealVO = setmealService.getByIdWithDish(id);return Result.success(setmealVO);//service
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;
}//mapper@Select("select * from setmeal_dish where setmeal_id = #{setmealId}")List<SetmealDish> getBySetmealId(Long setmealId);

注意:这里使用了两个get方法来获取数据!!! 

因为这里需要对数据进行一个回显,所以选择了VO格式的对象对数据进行封装。

4.2更新数据

//Controller
@PutMapping
@ApiOperation("修改套餐")
public Result update(@RequestBody SetmealDTO setmealDTO) {setmealService.update(setmealDTO);return Result.success();
}@Transactional
public void update(SetmealDTO setmealDTO) {Setmeal setmeal = new Setmeal();BeanUtils.copyProperties(setmealDTO, setmeal);//1、修改套餐表,执行updatesetmealMapper.update(setmeal);//套餐idLong setmealId = setmealDTO.getId();//2、删除套餐和菜品的关联关系,操作setmeal_dish表,执行deletesetmealDishMapper.deleteBySetmealId(setmealId);List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();setmealDishes.forEach(setmealDish -> {setmealDish.setSetmealId(setmealId);});//3、重新插入套餐和菜品的关联关系,操作setmeal_dish表,执行insertsetmealDishMapper.insertBatch(setmealDishes);
}

其实这里的操作和插入数据有类似的:

对setmeal套餐表中的数据进行更新

获取更新过后套餐的id

删除套餐和菜品之间的关系(根据套餐的id)

重新插入套餐和菜品之间的关系 

5.起售停售套餐

这个功能比较简单,主要是注意起售菜品的时候需要判断套餐中是否有停售菜品

//Controller
@PostMapping("/status/{status}")
@ApiOperation("套餐起售停售")
public Result startOrStop(@PathVariable Integer status, Long id) {setmealService.startOrStop(status, id);return Result.success();
}//Service
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);
}//Mapper
@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);

 

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

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

相关文章

数据赋能(208)——质量管理——及时性原则

概述 在数据处理、分析和应用过程中&#xff0c;数据及时性原则确保了数据在需要时能够迅速、准确地被获取、更新和传递&#xff0c;为决策和业务需求提供了时效性保障。能够反映当前的真实状况&#xff0c;为决策提供最新、最准确的信息支持。这种及时性不仅有助于企业快速响…

华为OD机试真题——告警抑制(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C、GO六种语言的最佳实现方式&#xff1b; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析&#xff1b; 本文收录于专栏&#xff1a;《2025华为OD真题目录…

ASP.NET MVC​ 入门指南四

21. 高级路由配置 21.1 自定义路由约束 除了使用默认的路由约束&#xff0c;你还可以创建自定义路由约束。自定义路由约束允许你根据特定的业务逻辑来决定一个路由是否匹配。例如&#xff0c;创建一个只允许特定年份的路由约束&#xff1a; csharp public class YearRouteCo…

测试基础笔记第十八天

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、web自动化1.xpath定位1.属性定位2.属性与逻辑结合3.属性和层级结合 2.常见元素定位方法&#xff08;面试题&#xff09;3.常见元素定位失败原因4.cookie1.验证码…

(笔记)List

一、List的介绍和使用 1.List的介绍 1.1 list是可以在任意常数范围内插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 1.2 list底层是双向链表结构&#xff0c;双向链表中每个元素都储存在互不相关的独立节点中&#xff0c;在节点中通过指针指向前其前一个…

重载和覆写有什么区别?

重载&#xff08;Overload&#xff09;和覆写&#xff08;Override&#xff0c;也叫重写 &#xff09;是面向对象编程中的重要概念&#xff0c;它们有以下区别&#xff1a; 定义 - 重载&#xff1a;在同一类中&#xff0c;允许存在多个方法名相同&#xff0c;但参数列表&#x…

flask 获取各种请求数据:GET form-data x-www-form-urlencoded JSON headers 上传文件

在 Flask 里&#xff0c;能使用多种方法获取不同类型的请求数据&#xff0c;下面详细介绍常见请求数据的获取方式。 获取查询字符串参数&#xff08;GET 请求&#xff09; 查询字符串参数一般在 URL 里&#xff0c;以 ?key1value1&key2value2 这种形式存在。可通过 requ…

人工智能助力工业制造:迈向智能制造的未来

在当今数字化转型的浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;技术正逐渐成为推动工业制造领域变革的核心力量。智能制造作为工业 4.0 的重要组成部分&#xff0c;通过将 AI 技术与传统制造工艺深度融合&#xff0c;正在重塑整个生产流程&#xff0c;提高生产效率、…

【java八股文】深入浅出synchronized优化原理

&#x1f50d; 开发者资源导航 &#x1f50d;&#x1f3f7;️ 博客主页&#xff1a; 个人主页&#x1f4da; 专栏订阅&#xff1a; JavaEE全栈专栏 synchronized优化原理 synchronized即使悲观锁也是乐观锁&#xff0c;拥有自适应性。 jvm内部会统计每个锁的竞争激烈程度&…

生成式 AI 的重要性

在科技飞速发展的今天,我们正站在一个前所未有的变革节点上。生成式 AI,宛如一颗突然划破夜空的耀眼流星,以其强大的创造力和无限的可能性,迅速成为全球瞩目的焦点。它究竟有何等魔力,能在如此短的时间内引发如此巨大的轰动?这背后又隐藏着怎样的时代密码,等待着我们去解…

生成式 AI 的阐释

在科技浪潮的汹涌推动下,一个全新的时代正以前所未有的速度向我们奔来,生成式 AI 无疑是这股浪潮中最耀眼的浪尖。它究竟是什么?又将如何重塑我们的世界?这不仅是科技爱好者们热衷探讨的话题,更是关乎每一个人未来发展的重要命题。 生成式 AI,从本质上来说,是一种能够自…

C++ 中 virtual 的作用

文章目录 1. 用于虚继承2. 用于抽象基类3. 用于多态 C 的 virtual 关键字&#xff0c;常见有 3 种用途&#xff1a;虚继承、抽象基类和多态。 1. 用于虚继承 virtual 用于虚继承时&#xff0c;主要是为了解决菱形继承中的重复继承同名成员问题。使用形式如下 class Derived:…

软件测试52讲学习分享:深入理解单元测试

课程背景 最近我在学习极客时间的《软件测试52讲》课程&#xff0c;这是由腾讯TEG基础架构部T4级专家茹炳晟老师主讲的认证课程。作为数字化转型与人工智能(DTAI)产业人才基地建设中心的认证课程&#xff0c;内容非常专业实用。今天想和大家分享第3讲"什么是单元测试&…

Java SE(7)——类和对象(二)

1.包(package) 1.1 包的定义 在Java中&#xff0c;包是一种用于组织和管理类&#xff0c;接口和其他包的机制。主要作用是防止命名冲突&#xff0c;并提供一种访问控制机制 1.2 package关键字 package关键字的主要作用是声明当前类在哪个包里面。 当然&#xff0c;用户也可以…

Manus联合创始人:公司产品基于Claude和阿里千问大模型开发

3月11日消息&#xff0c;日前&#xff0c;Manus官方在社交平台转发了公司联合创始人、首席科学家季逸超对Manus的技术解读&#xff0c;季逸超在评论区回复网友关于“Manus使用了哪一个基础大模型”这一问题时回复称&#xff0c;“我们用过Claude&#xff0c;也用过不同版本的Qw…

欺骗单页应用(SPA)渲染隐藏路由 -- trouble at the spa b01lersCTF

题目信息&#xff1a;I had this million-dollar app idea the other day, but I can’t get my routing to work! I’m only using state-of-the-art tools and frameworks, so that can’t be the problem… right? Can you navigate me to the endpoint of my dreams? 题目…

大数据引领行业革命:深度解析与未来趋势

📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 在信息化、数字化、智能化日益发展的今天,大数据技术已经成为推动产业变革的重要引擎。它不仅仅是一个技术工具,更是各行各业创新和优化的核心动力。无论是大企业还是初创公司,大数据的应用已经成为提升效…

[machine learning] Transformer - Attention (二)

本文介绍带训练参数的self-attention&#xff0c;即在transformer中使用的self-attention。 首先引入三个可训练的参数矩阵Wq, Wk, Wv&#xff0c;这三个矩阵用来将词向量投射(project)到query, key, value三个向量上。下面我们再定义几个变量&#xff1a; import torch inpu…

施磊老师rpc(三)

文章目录 mprpc框架项目动态库编译框架生成动态库框架初始化函数-文件读取1. 为什么要传入 argc, argv2. 读取参数逻辑3. 配置文件设计 init部分实现 mprpc配置文件加载(一)配置文件加载类成员变量主要方法**src/include/mprpcconfig.h** 配置文件**bin/test.conf** 实现配置文…

文献分享:通过简单的生物偶联策略将肽双特异性抗体(pBsAbs)应用于免疫治疗

背景 双特异性抗体是将单克隆抗体的两个不同抗原结合位点融合成一个单一实体的人工分子。它们已经成为一种很有前景的下一代抗癌治疗方法。尽管双特异性抗体的应用令人着迷&#xff0c;但双特异性抗体的设计和生产仍然繁琐而富有挑战性&#xff0c;导致研发过程漫长&#xff0…