19、新增套餐
19.1、需求分析
套餐就是菜品的集合。
后台系统中可以管理套餐信息,通过新增套餐功能来添加一个新的套餐,在添加套餐时需要选择当前套餐所属的套餐分类和包含的菜品,并且需要上传套餐对应的图片,在移动端会按照套餐分类来展示对应的套餐。
19.2、数据模型
新增套餐,其实就是将新增页面录入的套餐信息插入到setmeal
表,还需要向setmeal_dish
表插入套餐和菜品关联数据。
所以在新增套餐时,涉及到两个表:
setmeal
表:套餐表setmeal_dish
表:套餐菜品关系表
1、套餐表setmeal
:
2、套餐菜品关系表setmeal_dish
:
19.3、代码开发
19.3.1、准备工作
在开发业务之前,先将需要用到的类和接口基本结构创建好:
-
实体类:
SetmealDish
和Setmeal
【
SetmealDish.java
】/** * 套餐菜品关系 */ @Data public class SetmealDish implements Serializable { private static final long serialVersionUID = 1L; private Long id; //套餐id private Long setmealId; //菜品id private Long dishId; //菜品名称 (冗余字段) private String name; //菜品原价 private BigDecimal price; //份数 private Integer copies; //排序 private Integer sort; @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; @TableField(fill = FieldFill.INSERT) private Long createUser; @TableField(fill = FieldFill.INSERT_UPDATE) private Long updateUser; //是否删除 private Integer isDeleted; }
【
Setmeal.java
】/** * 套餐 */ @Data public class Setmeal implements Serializable { private static final long serialVersionUID = 1L; private Long id; //套餐分类id private Long categoryId; //套餐名称 private String name; //套餐价格 private BigDecimal price; //状态 0:停用 1:启用 private Integer status; //编码 private String code; //描述信息 private String description; //图片 private String image; @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; @TableField(fill = FieldFill.INSERT) private Long createUser; @TableField(fill = FieldFill.INSERT_UPDATE) private Long updateUser; //是否删除 private Integer isDeleted; }
-
DTO
:SetmealDto
@Data public class SetmealDto extends Setmeal { private List<SetmealDish> setmealDishes; private String categoryName; }
-
Mapper
接口:SetmealDishMapper
和SetmealMapper
【
SetmealDishMapper.java
】@Mapper public interface SetmealDishMapper extends BaseMapper<SetmealDish> { }
【
SetmealMapper.java
】@Mapper public interface SetmealMapper extends BaseMapper<Setmeal> { }
-
业务层接口:
SetmealDishService
和SetmealService
【
SetmealDishService.java
】public interface SetmealDishService extends IService<SetmealDish> { }
【
SetmealService.java
】public interface SetmealService extends IService<Setmeal> { }
-
业务层实现类:
SetmealDishServiceImpl
和SetmealServiceImpl
【
SetmealDishServiceImpl.java
】@Service @Slf4j public class SetmealDishServiceImpl extends ServiceImpl<SetmealDishMapper, SetmealDish> implements SetmealDishService { }
【
SetmealServiceImpl.java
】@Service @Slf4j public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService { }
-
控制层:
SetmealController
【
SetmealController.java
】/** * 套餐管理 */ @RestController @RequestMapping("/setmeal") @Slf4j public class SetmealController { @Autowired private SetmealService setmealService; @Autowired private SetmealDishService setmealDishService; }
19.3.2、梳理交互过程
在开发代码之前,需要梳理一下新增套餐时前端页面和服务端的交互过程:
1、页面(backend/page/combo/add.html
)发送ajax
请求,请求服务端获取套餐分类数据并展示到下拉框中
2、页面发送ajax
请求,请求服务端获取菜品分类数据并展示到添加菜品窗口中
3、页面发送ajax
请求,请求服务端,根据菜品分类查询对应的菜品数据并展示到添加菜品窗口中
4、页面发送请求进行图片上传,请求服务端将图片保存到服务器
5、页面发送请求进行图片下载,将上传的图片进行回显
6、点击保存按钮,发送ajax
请求,将套餐相关数据以json
形式提交到服务端
开发新增套餐功能,其实就是在服务端编写代码去处理前端页面发送的这6次请求即可。
19.4、功能测试
1、根据条件查询对应的菜品信息
【DishController.java
】
/**
* 根据条件查询对应的菜品信息
* @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、新增套餐
【SetmealServiceImpl.java
】
@Service
@Slf4j
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
@Autowired
private SetmealDishService setmealDishService;
/**
* 新增套餐,同时需要保存套餐和菜品的关联关系
* @param setmealDto
*/
@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);
}
}
【SetmealController.java
】
/**
* 新增套餐
* @param setmealDto
* @return
*/
@PostMapping
public R<String> save(@RequestBody SetmealDto setmealDto) {
log.info("套餐信息:{}", setmealDto);
setmealService.saveWithDish(setmealDto);
return R.success("新增套餐成功");
}