16、新增菜品
16.1、需求分析
后台系统中可以管理菜品信息,通过新增功能来添加一个新的菜品,在添加菜品时需要选择当前菜品所属的菜品分类,并且需要上传菜品图片,在移动端会按照菜品分类来展示对应的菜品信息。
16.2、数据模型
1、新增菜品,其实就是将新增页面录入的菜品信息插入到dish
表,如果添加了口味做法,还需要向dish_flavor
表插入数据。
所以在新增菜品时,涉及到两个表:
dish
:菜品表dish_flavor
:菜品口味表
2、菜品表dish
3、菜品口味表dish_flavor
16.3、代码开发
16.3.1、准备工作
在开发业务功能前,先将需要用到的类和接口基本结构创建好:
-
实体类:
Dish
和DishFlavor
【
Dish.java
】/** 菜品 */ @Data public class Dish implements Serializable { private static final long serialVersionUID = 1L; private Long id; //菜品名称 private String name; //菜品分类id private Long categoryId; //菜品价格 private BigDecimal price; //商品码 private String code; //图片 private String image; //描述信息 private String description; //0 停售 1 起售 private Integer status; //顺序 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; }
【
DishFlavor.java
】/** 菜品口味 */ @Data public class DishFlavor implements Serializable { private static final long serialVersionUID = 1L; private Long id; //菜品id private Long dishId; //口味名称 private String name; //口味数据list private String value; @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
接口:DishMapper
和DishFlavorMapper
【
DishMapper.java
】@Mapper public interface DishMapper extends BaseMapper<Dish> { }
【
DishFlavorMapper.java
】@Mapper public interface DishFlavorMapper extends BaseMapper<DishFlavor> { }
-
业务层接口:
DishService
和DishFlavorService
【
DishService.java
】public interface DishService extends IService<Dish> { }
【
DishFlavorService.java
】public interface DishFlavorService extends IService<DishFlavor> { }
-
业务层实现类:
DishServiceImpl
和DishFlavorServiceImpl
【
DishServiceImpl.java
】@Service @Slf4j public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService { }
【
DishFlavorServiceImpl.java
】@Service @Slf4j public class DishFlavorServiceImpl extends ServiceImpl<DishFlavorMapper, DishFlavor> implements DishFlavorService { }
-
控制层:
DishController
【
DishController.java
】@RestController @RequestMapping("/dish") @Slf4j public class DishController { @Autowired private DishService dishService; @Autowired private DishFlavorService dishFlavorService; }
16.3.2、交互过程
在开发代码之前,需要梳理一下新增菜品时前端页面与服务端的交互过程:
1、页面(backend/page/food/add.html
)发送ajax
请求,请求服务端获取菜品分类数据并展示到下拉框中
2、页面发送请求进行图片上传,请求服务端将图片保存到服务器
3、页面发送请求进行图片下载,将上传的图片进行回显
4、点击保存按钮,发送ajax
请求,将菜品相关数据以json
形式提交到服务端
开发新增菜品功能,其实就是在服务端编写代码去处理前端页面发送的者4此请求即可。
16.4、功能测试
16.4.1、获取菜品分类
16.4.1.1、前端实现
1、页面逻辑
16.4.1.2、后端实现
/**
* 根据条件查询分类数据
* @param category
* @return
*/
@GetMapping("/list")
public R<List<Category>> list(Category category) {
//构造条件构造器
LambdaQueryWrapper<Category> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//添加条件
lambdaQueryWrapper.eq(category.getType() != null, Category::getType, category.getType());
//添加排序条件:根据排序升序排列,排序一样,根据更新时间降序排列
lambdaQueryWrapper.orderByAsc(Category::getSort).orderByDesc(Category::getUpdateTime);
//查询
List<Category> list = categoryService.list(lambdaQueryWrapper);
return R.success(list);
}
16.4.2、新增菜品
16.4.2.1、前端实现
1、页面逻辑
2、前端请求
16.4.2.2、后端实现
1、创建类DishDTO
,用于封装页面提交的数据
@Data
public class DishDto extends Dish {
private List<DishFlavor> flavors = new ArrayList<>();
private String categoryName;
private Integer copies;
}
DTO
:Data Transfer Object,即数据传输对象,一般用于展示层与服务层之间的数据传输。
2、新增菜品,同时插入菜品对应的口味数据
【DishService.java
】
public interface DishService extends IService<Dish> {
//新增菜品,同时插入菜品对应的口味数据,需要操作两张表:dish、dish_flavor
public void saveWithFlavor(DishDto dishDto);
}
【DishServiceImpl.java
】
@Service
@Slf4j
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
@Autowired
private DishFlavorService dishFlavorService;
/**
* 新增菜品,同时保存对应的口味数据
* @param dishDto
*/
@Transactional
public void saveWithFlavor(DishDto dishDto) {
//保存菜品的基本信息到菜品表dish
this.save(dishDto);
Long dishId = dishDto.getId();//菜品id
List<DishFlavor> flavors = dishDto.getFlavors();
flavors = flavors.stream().map((item) -> {
item.setDishId(dishId);
return item;
}).collect(Collectors.toList());
// 保存菜品口味数据到菜品口味表dish_flavor
dishFlavorService.saveBatch(flavors);
}
}
3、在启动类上添加@EnableTransactionManagement
@Slf4j
@SpringBootApplication
@ServletComponentScan
@EnableTransactionManagement
public class ReggieApplication {
public static void main(String[] args) {
SpringApplication.run(ReggieApplication.class, args);
log.info("项目启动成功...");
}
}
4、controller
实现新增菜品
/**
* 新增菜品
* @param dishDto
* @return
*/
@PostMapping()
public R<String> save(@RequestBody DishDto dishDto) {
log.info("dishDto:{}", dishDto);
dishService.saveWithFlavor(dishDto);
return R.success("新增菜品成功");
}