当前位置:网站首页>6.套餐管理业务开发
6.套餐管理业务开发
2022-06-24 09:43:00 【xjhqre】
套餐管理业务开发
1、准备工作
准备需要用到的类和接口
- 实体类
SetmealDish - DTO
SetmealDto - Mapper接口
SetmealDishMapper - 业务层接口
SetmealDishService - 业务层实现类
SetmealDishServiceImpl - 控制层
SetmealController
2、新增套餐
执行流程:
- 页面(backend/page/comboladd.html)发送ajax请求,请求服务端获取套餐分类数据并展示到下拉框中
- 页面发送ajax请求,请求服务端获取菜品分类数据并展示到添加菜品窗口中
- 页面发送ajax请求,请求服务端,根据菜品分类查询对应的菜品数据并展示到添加菜品窗口中
- 页面发送请求进行图片上传,请求服务端将图片保存到服务器
- 页面发送请求进行图片下载,将上传的图片进行回显
- 点击保存按钮,发送ajax请求,将套餐相关数据以json形式提交到服务端
2.1、查询菜品分类列表
在DishController创建list方法
/** * 根据条件查询对应的菜品数据 * @param dish * @return */
@GetMapping("/list")
public R<List<Dish>> list(Dish dish) {
// 狗仔查询条件
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(dish.getCategoryId() != null, Dish::getCategoryId, dish.getCategoryId());
// 查询状态为1的菜品
queryWrapper.eq(Dish::getStatus, 1);
// 添加排序条件
queryWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
List<Dish> list = dishService.list(queryWrapper);
return R.success(list);
}
2.2、阿里云OSS图片回显(可选)
修改backend/page/combo/add.html页面以下内容,改成自己的阿里云地址加上图片名称

2.3、保存新增信息
2.3.1、SetmealController
package com.itheima.reggie.controller;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.SetmealDto;
import com.itheima.reggie.entity.SetmealDish;
import com.itheima.reggie.service.SetmealDishService;
import com.itheima.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/** * @Author: xjhqre * @DateTime: 2022/6/19 15:36 */
@RequestMapping("/setmeal")
@RestController
@Slf4j
public class SetmealController {
@Autowired
SetmealService setmealService;
@Autowired
SetmealDishService setmealDishService;
/** * 新增套餐 * @param setmealDto * @return */
@PostMapping
public R<String> save(@RequestBody SetmealDto setmealDto) {
log.info("新增套餐信息:{}", setmealDto);
setmealService.saveWithDish(setmealDto);
return R.success("添加套餐成功");
}
}
2.3.2、SetmealService
// 新增套餐,同时需要保存套餐和菜品的关联关系
void saveWithDish(SetmealDto setmealDto);
2.3.3、SetmealServiceImpl
/** * 新增套餐,同时需要保存套餐和菜品的关联关系 * @param setmealDto */
@Override
@Transactional
public void saveWithDish(SetmealDto setmealDto) {
// 保存套餐的基本信息,操作setmeal,执行insert操作
this.save(setmealDto);
List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
setmealDishes = setmealDishes.stream().map(item -> {
item.setSetmealId(setmealDto.getId());
return item;
}).collect(Collectors.toList());
// 保存套餐和菜品的关联信息,操作setmeal_dish执行insert操作
setmealDishService.saveBatch(setmealDishes);
}
2.4、测试新增套餐
3、套餐信息分页查询
执行流程:
- 页面(backend/page/combo/list.html)发送ajax请求,将分页查询参数(page、pageSize.name)提交到服务端,获取分页数据
- 页面发送请求,请求服务端进行图片下载,用于页面图片展示
3.1、方法一:老师的方法
在SetmealController创建page方法
/** * 套餐信息分页查询 * @param page * @param pageSize * @param name * @return */
@GetMapping("/page")
public R<Page> page(int page, int pageSize, String name) {
// 分页构造器对象
Page<Setmeal> pageInfo = new Page<>(page, pageSize);
Page<SetmealDto> dtoPage = new Page<>();
LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
// 添加查询条件,根据name进行like模糊查询
queryWrapper.like(name != null, Setmeal::getName, name);
// 添加排序条件,根据更新时间降序排序
queryWrapper.orderByDesc(Setmeal::getUpdateTime);
setmealService.page(pageInfo, queryWrapper);
// 对象拷贝
BeanUtils.copyProperties(pageInfo, dtoPage, "records");
List<Setmeal> records = pageInfo.getRecords();
List<SetmealDto> list = records.stream().map(item -> {
SetmealDto setmealDto = new SetmealDto();
// 对象拷贝
BeanUtils.copyProperties(item, setmealDto);
// 分类id
Long categoryId = item.getCategoryId();
// 根据分类id查询分类对象
Category category = categoryService.getById(categoryId);
if (category != null) {
// 分类名称
String categoryName = category.getName();
setmealDto.setCategoryName(categoryName);
}
return setmealDto;
}).collect(Collectors.toList());
dtoPage.setRecords(list);
return R.success(pageInfo);
}
3.2、方法二:联表查询方法
3.2.1、SetmealController
/** * 套餐信息分页查询 * @param page * @param pageSize * @param name * @return */
@GetMapping("/page")
public R<Page<SetmealDto>> page(int page, int pageSize, String name) {
// 分页构造器
Page<SetmealDto> pageInfo = new Page<>(page, pageSize);
setmealService.querySetmealPageWithCategoryName(pageInfo, name);
return R.success(pageInfo);
}
3.2.2、SetmealService
// 查询带分类名的套餐分页信息
void querySetmealPageWithCategoryName(Page<SetmealDto> pageInfo, String name);
3.2.3、SetmealServiceImpl
/** * 查询带分类名的套餐分页信息 * @param pageInfo * @param name */
@Override
public void querySetmealPageWithCategoryName(Page<SetmealDto> pageInfo, String name) {
List<SetmealDto> records = setmealMapper.querySetmealPageWithCategoryName(pageInfo, name == null ? "" : name);
pageInfo.setRecords(records);
}
3.2.4、SetmealMapper
@Select("SELECT a.*, b.`name` AS category_name FROM setmeal a JOIN category b ON a.`category_id` = b.`id` WHERE a.`name` LIKE CONCAT('%',#{name},'%') AND a.`is_deleted` = 0 ORDER BY sort")
List<SetmealDto> querySetmealPageWithCategoryName(Page<SetmealDto> pageInfo, String name);
3.3、套餐管理页面阿里云OSS图片显示
修改backend/page/combo/list.html文件以下两处地方


3.4、测试分页查询

4、删除套餐信息
- 前端发送删除请求,参数形式为
ids=id1,id2,... - 后端接收请求,根据
id先删除表setmeal_dish表的内容,在删除setmeal表的内容
删除方法为逻辑删除
4.1 修改Setmeal和SetmealDish实体类
修改两个实体类的isDeleted属性,加上@TableLogic(value = "0", delval = "1")注解。用于逻辑删除。标注了此注解后,调用mybatis-plus框架里给的删除方法,会转变成对is_deleted字段的更新方法
//是否删除
@TableLogic(value = "0", delval = "1")
private Integer isDeleted;
4.2、SetmealController
创建delete方法
/** * 删除套餐 * @param ids * @return */
@DeleteMapping
public R<String> delete(@RequestParam Long[] ids) {
log.info("要删除套餐的ids:{}", Arrays.toString(ids));
setmealService.removeSetmealWithDish(ids);
return R.success("套餐数据删除成功");
}
4.3、SetmealService
// 删除套餐,同时需要删除套餐和菜品的关联数据
void removeSetmealWithDish(Long[] ids);
4.4、SetmealServiceImpl
/** * 删除套餐,同时需要删除套餐和菜品的关联数据 * @param ids */
@Override
@Transactional
public void removeSetmealWithDish(Long[] ids) {
// 查询套餐状态,确定是否可用删除
LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(Setmeal::getId, ids);
queryWrapper.eq(Setmeal::getStatus, 1);
int count = this.count(queryWrapper);
if (count > 0) {
// 当前套餐正在出售,不能删除
throw new CustomException("套餐正在售卖中,不能删除");
}
// 如果可用删除,先删除表setmeal_dish中关联的菜品信息
// delete from setmeal_dish where setmeal_id in ()
LambdaQueryWrapper<SetmealDish> setmealDishLambdaQueryWrapper = new LambdaQueryWrapper<>();
setmealDishLambdaQueryWrapper.in(SetmealDish::getSetmealId, ids);
setmealDishService.remove(setmealDishLambdaQueryWrapper);
// 然后删除套餐信息
this.removeByIds(Arrays.asList(ids));
}
4.5、测试删除套餐
5、修改套餐信息(可选)
5.1、套餐数据回显
点击修改后,前端页面会发送一个查询请求,带有id参数

我们需要返回一个SetmealDto类型的对象
5.1.1、SetmealController
/** * 根据id查询套餐信息和对应的菜品信息 * @param id * @return */
@GetMapping("/{id}")
public R<SetmealDto> get(@PathVariable Long id) {
SetmealDto setmealDto = setmealService.getByIdWithDish(id);
return R.success(setmealDto);
}
5.1.2、SetmealService
// 根据id查询套餐信息和对应的菜品信息
SetmealDto getByIdWithDish(Long id);
5.1.3、SetmealServiceImpl
/** * 根据id查询套餐信息和对应的菜品信息 * @param id * @return */
@Override
@Transactional
public SetmealDto getByIdWithDish(Long id) {
// 查询套餐基本信息
Setmeal setmeal = this.getById(id);
SetmealDto setmealDto = new SetmealDto();
BeanUtils.copyProperties(setmeal, setmealDto);
// 查询当前套餐对应的菜品信息
// select * from setmeal_dish where setmeal_id = id;
LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SetmealDish::getSetmealId, id);
List<SetmealDish> setmealDishes = setmealDishService.list(queryWrapper);
setmealDto.setSetmealDishes(setmealDishes);
return setmealDto;
}
5.1.4、阿里云OSS图片回显(可选)
修改backend/page/combo/add.html文件以下内容

5.1.5、测试数据回显
5.2、保存修改信息
先删除setmeal对应的所有dish,在进行添加
5.2.1、SetmealController
/** * 修改套餐 * @param setmealDto * @return */
@PutMapping
public R<String> update(@RequestBody SetmealDto setmealDto) {
log.info("保存修改套餐信息:{}", setmealDto);
setmealService.updateSetmealWithDish(setmealDto);
return R.success("修改套餐成功");
}
5.2.2、SetmealService
// 更新套餐信息
void updateSetmealWithDish(SetmealDto setmealDto);
5.2.3、SetmealServiceImpl
/** * 更新套餐信息 * @param setmealDto */
@Override
public void updateSetmealWithDish(SetmealDto setmealDto) {
// 更新setmeal表基本信息
this.updateById(setmealDto);
// 删除原来对应的菜品信息
LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SetmealDish::getSetmealId, setmealDto.getId());
setmealDishService.remove(queryWrapper);
// 添加新的菜品信息
List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
setmealDishes = setmealDishes.stream().peek(item -> item.setSetmealId(setmealDto.getId())).collect(Collectors.toList());
setmealDishService.saveBatch(setmealDishes);
}
5.2.4、测试修改套餐
6、批量起售/停售套餐(可选)
前端页面请求:

6.1、SetmealController
/** * 批量起售/停售套餐 * @param status * @param ids * @return */
@PostMapping("/status/{status}")
public R<String> status(@PathVariable("status") int status, @RequestParam Long[] ids) {
log.info("批量起售停售:{}", status, Arrays.toString(ids));
setmealService.updateStatusByIds(status, ids);
return R.success("批量起售停售成功");
}
6.2、SetmealService
// 批量起售停售套餐
void updateStatusByIds(int status, Long[] ids);
6.3、SetmealServiceImpl
不知道为什么mybat-plus没有提供批量修改的方法。
这里我为了方便就直接在循环里更新了。
还有一种方法是在mapper文件里进行批量更新。
不知道哪种方法更优雅一点。如果有大佬知道希望能在评论区解答一下。
/** * 批量起售停售套餐 * @param status * @param ids */
@Override
public void updateStatusByIds(int status, Long[] ids) {
// 查询出所有对应id的setmeal
List<Setmeal> setmeals = setmealMapper.selectBatchIds(Arrays.asList(ids));
// 循环遍历更新
setmeals.forEach(item -> {
item.setStatus(status);
setmealMapper.updateById(item);
});
}
6.4、测试批量起售停售
边栏推荐
- Operator details
- Floating point notation (summarized from cs61c and CMU CSAPP)
- 植物生长h5动画js特效
- NVIDIA's CVPR 2022 oral is on fire! 2D images become realistic 3D objects in seconds! Here comes the virtual jazz band!
- tf.errors
- 读取csv(tsv)文件出错
- linux下oracle服务器打开允许远程连接
- Distributed | how to make "secret calls" with dble
- 分布式 | 如何与 DBLE 进行“秘密通话”
- Internet of things? Come and see Arduino on the cloud
猜你喜欢

numpy.linspace()

Using pandas to read SQL server data table

Analysis of 43 cases of MATLAB neural network: Chapter 32 time series prediction of wavelet neural network - short-term traffic flow prediction

Mise en œuvre du rendu de liste et du rendu conditionnel pour l'apprentissage des applets Wechat.

微信小程序學習之 實現列錶渲染和條件渲染.

机器学习——感知机及K近邻

canvas管道动画js特效

有关二叉树 的基本操作

简单的价格表样式代码

Development of anti fleeing marketing software for health products
随机推荐
Phpstrom code formatting settings
ByteDance Interviewer: talk about the principle of audio and video synchronization. Can audio and video be absolutely synchronized?
操作符详解
The great charm of cookies
简单的价格表样式代码
js单例模式
学习使用KindEditor富文本编辑器,点击上传图片遮罩太大或白屏解决方案
Desktop software development framework reward
416-二叉树(前中后序遍历—迭代法)
dedecms模板文件讲解以及首页标签替换
YOLOv6:又快又准的目标检测框架开源啦
顶刊TPAMI 2022!基于不同数据模态的行为识别:最新综述
记录一下MySql update会锁定哪些范围的数据
oracle池式连接请求超时问题排查步骤
p5.js实现的炫酷交互式动画js特效
SQL sever基本数据类型详解
观察者模式
新手怎么选择投资理财产品的等级?
学习使用php实现无限极评论和无限极转二级评论解决方案
415 binary tree (144. preorder traversal of binary tree, 145. postorder traversal of binary tree, 94. inorder traversal of binary tree)