文章目录
- 1. 需求分析与实体类准备
- 2. 依据菜品分类或者名字进行查询的请求(需求B)
- 3. 新增套餐
1. 需求分析与实体类准备
如上图为新增套餐的界面, 它包含了套餐的一些基本信息, 例如名称、价格等, 同时还有套餐分类(因此这里需要一个查询所有套餐分类的请求处理方法, 需求A). 以及弹出页面用于选择菜品, 包括依据菜品分类或者名字进行查询的请求(需求B), 其他的还包括图片的上传与展示©等等, 这一新增操作涉及到两个表: setmeal 和 setmeal_dish 两个表, setmeal 表包含套餐的基本信息以及id, 而 setmeal_dish 则是一张关联表, 每一条记录包含某一套餐下的一类菜品, 实体类如下:
@Data
public class Setmeal implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private Long categoryId; //分类id
private String name; //套餐名称
private BigDecimal price; //套餐价格
private Integer status; //状态 0:停用 1:启用
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;
}
@Data
public class SetmealDish implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private Long setmealId; //套餐id
private Long dishId; //菜品id
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;
}
同时为他们搭建 Mapper接口 和 Service层, 并建立 SetmealController:
// mapper
package com.rain.reggie.mapper;
@Mapper
public interface SetmealMapper extends BaseMapper<Setmeal> {
}
@Mapper
public interface SetMealDishMapper extends BaseMapper<SetmealDish> {
}
// service
package com.rain.reggie.service;
public interface SetmealDishService extends IService<SetmealDish> {
}
public interface SetmealService extends IService<Setmeal> {
}
// service impl
package com.rain.reggie.service.impl;
@Service
public class SetmealDishServiceImpl extends ServiceImpl<SetMealDishMapper, SetmealDish> implements SetmealDishService {
}
// controller
package com.rain.reggie.controller;
@RestController
@RequestMapping("setmeal")
@Slf4j
public class SetmealController {
@Autowired
private SetmealService mealService;
}
显然由于传入的json数据并非以上任何一个实体类, 因而需要创建 DTO 类:
@Data
public class SetmealDto extends Setmeal {
private List<SetmealDish> setmealDishes;
private String categoryName;
}
2. 依据菜品分类或者名字进行查询的请求(需求B)
请求路径(示例):
http://localhost:8080/dish/list?categoryId=123
http://localhost:8080/dish/list?name=123
请求方式:
GET
为了兼容这两种查询方式, 使用 Dish 实体类接收, 使用时判断 categoryId 字段是否为空再进行查询:
@GetMapping("list")
public R<List<Dish>> list(Dish dish){
log.info("查询信息: {}", dish);
Long categoryId = dish.getCategoryId();
LambdaQueryWrapper<Dish> dishWrapper = new LambdaQueryWrapper<>();
if (categoryId == null){
String queryName = dish.getName();
log.info("使用名称 {} 进行查询 ...", queryName);
dishWrapper.like(queryName!=null, Dish::getName, queryName);
}else {
log.info("使用分类 {} 进行查询 ...", categoryId);
dishWrapper.eq(Dish::getCategoryId, categoryId);
}
dishWrapper.orderByAsc(Dish::getSort).orderByDesc(Dish::getUpdateTime);
List<Dish> dishes = service.list(dishWrapper);
return R.success(dishes);
}
3. 新增套餐
请求路径:
http://localhost:8080/setmeal
请求方式:
POST
如下为从浏览器 copy 的请求数据示例:
{
"name": "儿童套餐经典版",
"categoryId": "1413386191767674881",
"price": 18000,
"code": "",
"image": "D:/cache/reggie/dfb496e6-d4a8-4c45-bf79-a02e7ca08ffa.jpg",
"description": "我连一亿都不敢想,她直接600亿[泪][泪][泪]",
"dishList": [],
"status": 1,
"idType": "1413386191767674881",
"setmealDishes": [
{
"copies": 1,
"dishId": "1397851668262465537",
"name": "口味蛇",
"price": 16800
},
{
"copies": 1,
"dishId": "1397854865672679425",
"name": "鱼香炒鸡蛋",
"price": 2000
},
{
"copies": 2,
"dishId": "1413384757047271425",
"name": "王老吉",
"price": 500
},
{
"copies": 1,
"dishId": "1413385247889891330",
"name": "米饭",
"price": 200
}
]
}
注意, 不要更改 Setmeal 实体类的名称以及其中字段的名称, 因为这是要与 mysql 中表以及表中字段一一对应的.
例如 Setmeal 实体对应 setmeal 表. 而如果这样写: SetMeal, 那么它对应 set_meal 表(实际上数据库只有 setmeal 表, 因此万不可错写)
SetmealController 中新增方法:
@PostMapping
public R<String> insert(@RequestBody SetmealDto setMealDto){
log.info("待添加的套餐: {}", setMealDto);
mealService.addWithDish(setMealDto);
return R.success("套餐添加成功");
}
SetmealServiceImpl 中重写方法:
@Transactional
@Override
public void addWithDish(SetmealDto setMealDto) {
// 1. 将数据插入到 set meal 表, 注意 code 字段未填充
this.save(setMealDto);
// 2. 将 set meal Dishes 数据依次插入到 SetMealDish 表, 注意字段填充
List<SetmealDish> setmealDishes = setMealDto.getSetmealDishes();
setmealDishes = setmealDishes.stream().map((item)->{
item.setSetmealId(setMealDto.getId());
return item;
}).collect(Collectors.toList());
setMealDishService.saveBatch(setmealDishes);
}