Day05——瑞吉外卖

文章目录

15 菜品分页查询模块+根据类别ID填充类别信息

1.1 菜品分页查询功能需求分析

系统中的菜品数据很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看,所以一般的系统中都会以分页的方式来展示列表数据。

在这里插入图片描述

在菜品列表展示时,除了菜品的基本信息(名称、售价、售卖状态、更新时间)外,还有两个字段略微特殊,

①图片字段 ,从数据库查询出来的仅仅是图片的名字,图片要想在表格中回显展示出来,就需要下载这个图片。

②菜品分类,这里展示的是分类名称,而不是分类ID,因此需要根据菜品的分类ID,去分类表中查询分类信息,然后在页面展示。

1.2 菜品分页查询功能前端页面和服务端的交互过程

1). 访问页面(backend/page/food/list.html)时,发送ajax请求,将分页查询参数(page、pageSize、name)提交到服务端,获取分页数据

2). 页面发送请求,请求服务端进行图片下载,用于页面图片展示

在这里插入图片描述

在这里插入图片描述

开发菜品信息分页查询功能,其实就是在服务端编写代码去处理前端页面发送的这2次请求即可,而前端发起的请求中,图片文件下载回显的代码(已实现),所以,只需要开发分页查询的功能即可,分页查询具体的请求信息如下:

请求说明
请求方式GET
请求路径/dish/page
请求参数?page=1&pageSize=10&name=xxx

1.3 菜品分页查询功能逻辑分析

在 DishController中开发方法,来完成菜品的条件分页查询,在分页查询时还需要给页面返回分类的名称,而分类的名称前端在接收的时候是通过 categoryName 属性获取的,那么对应的服务端也应该封装到 categoryName 属性中。

如何解决在实体类 Dish 中,仅仅包含 categoryId, 不包含 categoryName的问题?

以返回DishDto对象,在该对象中可以拓展一个属性 categoryName,来封装菜品分类名称

@Data
public class DishDto extends Dish {
    private List<DishFlavor> flavors = new ArrayList<>();
    private String categoryName; //菜品分类名称
    private Integer copies;
}

具体逻辑为:

1). 构造分页条件对象

2). 构建查询及排序条件

3). 执行分页条件查询

4). 遍历分页查询列表数据,根据分类ID查询分类信息,从而获取该菜品的分类名称

5). 封装数据并返回、

1.4 菜品分页查询功能代码实现

package com.fc.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fc.reggie.common.R;
import com.fc.reggie.dto.DishDto;
import com.fc.reggie.entity.Category;
import com.fc.reggie.entity.Dish;
import com.fc.reggie.entity.DishFlavor;
import com.fc.reggie.service.CategoryService;
import com.fc.reggie.service.DishFlavorService;
import com.fc.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜品管理
 */
@RestController
@RequestMapping("/dish")
@Slf4j
public class DishController {
    @Autowired
    private DishService dishService;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private  CategoryService categoryService;

    /**
     * 新增菜品
     * @param dishDto
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDto){
        log.info(dishDto.toString());
        dishService.saveWithFlavor(dishDto);
        return R.success("新增菜品成功");
    }

    /**
     * 菜品信息的分页
     * @param pageSize
     * @param page
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(int pageSize,int page,String name){
        //构造分页构造器
        Page<Dish> pageInfo = new Page<>(page, pageSize);
        Page<DishDto> dishDtoPage = new Page<>();
        //条件构造器
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        //添加过滤条件
        queryWrapper.like(name!=null,Dish::getName,name);
        //添加排序条件
        queryWrapper.orderByDesc(Dish::getUpdateTime);
        //执行分页查询
        dishService.page(pageInfo,queryWrapper);

        //对象拷贝
        BeanUtils.copyProperties(pageInfo,dishDtoPage,"records");

        List<Dish> records = pageInfo.getRecords();
        List<DishDto> list= records.stream().map((item)->{
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item,dishDto);
            Long categoryId = item.getCategoryId();//分类id
            //根据id查询分类对象
            Category category = categoryService.getById(categoryId);
            if(category!=null){
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }
            return  dishDto;
        }).collect(Collectors.toList());
        dishDtoPage.setRecords(list);
        return R.success(dishDtoPage);
    }

    /**
     * 根据id查询菜品信息和对应的口味信息
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<DishDto> get(@PathVariable Long id){
        DishDto dishDto = dishService.getByIdWithFlavor(id);
        return R.success(dishDto);
    }

    /**
     * 修改菜品
     * @param dishDto
     * @return
     */
    @PutMapping
    public R<String> updateWithFlavor(@RequestBody DishDto dishDto){
        log.info(dishDto.toString());
        dishService.updateWithFlavor(dishDto);
        return R.success("修改菜品成功");
    }

    /**
     * 根据条件查询对应的菜品数据
     * @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);
    }
}

1.5 功能测试

代码编写完毕之后,我们重新启动服务,访问项目,可以通过debug端点的形式跟踪,整个分页查询过程中,数据的转换和封装。

在这里插入图片描述

16 菜品修改模块+菜品信息回显+ID查询口味列表+组装数据并返回

1.1 菜品修改模块需求分析

在菜品管理列表页面点击修改按钮,跳转到修改菜品页面,在修改页面回显菜品相关信息并进行修改,最后点击确定按钮完成修改操作。

在这里插入图片描述

1.2 菜品修改模块前端页面(add.html)和服务端的交互过程

1). 点击菜品列表的中的修改按钮,携带菜品id跳转至add.html

在这里插入图片描述

2). 进入add.html,页面发送ajax请求,请求服务端获取分类数据,用于菜品分类下拉框中数据展示(已实现)
3). add.html获取id, 发送ajax请求,请求服务端,根据id查询当前菜品信息,用于菜品信息回显

在这里插入图片描述

4). 页面发送请求,请求服务端进行图片下载,用于页图片回显(已实现)
<img v-if="imageUrl" :src="imageUrl" class="avater"></img>
5). 点击保存按钮,页面发送ajax请求,将修改后的菜品相关数据以json形式提交到服务端

在这里插入图片描述

1.3 新增功能

经过上述的分析,菜品分类下拉框的展示、图片的下载回显功能已经实现了。只需要在这里实现两个功能即可,分别是:

1). 根据ID查询菜品及菜品口味信息
请求说明
请求方式GET
请求路径/dish/{id}
2). 修改菜品及菜品口味信息
请求说明
请求方式PUT
请求路径/dish
请求参数json格式数据

通过浏览器抓取 具体的json格式数据:

{
    "id":"1422783914845487106",
    "name":"佛跳墙",
    "categoryId":"1397844357980663809",
    "price":88800,
    "code":"",
    "image":"da9e1c70-fc32-4781-9510-a1c4ccd2ff59.jpg",
    "description":"佛跳墙",
    "status":1,
    "sort":0,
    "createTime":"2021-08-04 12:58:14",
    "createUser":"1412578435737350122",
    "updateUser":"1412578435737350122",
    "flavors":[
        {
            "id":"1422783914883235842",
            "dishId":"1422783914845487106",
            "name":"辣度",
            "value":"[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]",
            "createTime":"2021-08-04 12:58:14",
            "updateTime":"2021-08-04 12:58:14",
            "createUser":"1412578435737350122",
            "updateUser":"1412578435737350122",
            "isDeleted":0,
            "showOption":false
        },
        {
            "id":"1422783914895818754",
            "dishId":"1422783914845487106",
            "name":"忌口",
            "value":"[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]",
            "createTime":"2021-08-04 12:58:14",
            "updateTime":"2021-08-04 12:58:14",
            "createUser":"1412578435737350122",
            "updateUser":"1412578435737350122",
            "isDeleted":0,
            "showOption":false
        }
    ]
}

1.4 代码实现

1.4.1 根据ID查询菜品信息

页面发送ajax请求,请求服务端,根据id查询当前菜品信息和对应的口味信息,用于修改页面中菜品信息回显。

1.4.2 修改菜品信息

点击保存按钮,页面发送ajax请求,将修改后的菜品相关数据以json形式提交到服务端。在修改菜品信息时需要注意,除了要更新dish菜品表,还需要更新dish_flavor菜品口味表。

1.4.3 在DishService接口中扩展getByIdWithFlavor、updateWithFlavor方法

package com.fc.reggie.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.fc.reggie.dto.DishDto;
import com.fc.reggie.entity.Dish;

public interface DishService extends IService<Dish> {

    //新增菜品,同时插入菜品对应的口味数据,需要操作两张表:dish、dish_flavor
    public void saveWithFlavor(DishDto dishDto);

    //根据id查询菜品信息和对应的口味信息
    public DishDto getByIdWithFlavor(Long id);

    //更新菜品信息,同时更新对应的口味信息
    public void updateWithFlavor(DishDto dishDto);

}

1.4.4 在DishService实现类中实现getByIdWithFlavor与updateWithFlavor方法

①getByIdWithFlavor具体逻辑为:

A. 根据ID查询菜品的基本信息

B. 根据菜品的ID查询菜品口味列表数据

C. 组装数据并返回

updateWithFlavor具体逻辑为:


A. 根据ID查询菜品的基本信息

B. 根据菜品的ID查询菜品口味列表数据

C. 组装数据并返回

package com.fc.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fc.reggie.dto.DishDto;
import com.fc.reggie.entity.Dish;
import com.fc.reggie.entity.DishFlavor;
import com.fc.reggie.mapper.DishMapper;
import com.fc.reggie.service.DishFlavorService;
import com.fc.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;

@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);
    }

    /**
     * 更新菜品信息,同时更新对应的口味信息
     * @param dishDto
     */
    @Override
    @Transactional
    public void updateWithFlavor(DishDto dishDto) {
        //更新dish表基本信息
        this.updateById(dishDto);
        //清理当前菜品对应的口味数据--dish_flavor表中的delete操作
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId,dishDto.getId());
        dishFlavorService.remove(queryWrapper);
        //添加当前提交的口味数据--dish_flavor表中的insert操作
        List<DishFlavor> flavors = dishDto.getFlavors();
        flavors = flavors.stream().map((item) -> {
            item.setDishId(dishDto.getId());
            return item;
        }).collect(Collectors.toList());
        dishFlavorService.saveBatch(flavors);
    }

    /**
     * 根据id查菜品和菜品口味信息
     * @param id
     * @return
     */
    @Override
    public DishDto getByIdWithFlavor(Long id) {
        //查询菜品基本信息,从dish表中查
        Dish dish = this.getById(id);
        DishDto dishDto = new DishDto();
        BeanUtils.copyProperties(dish,dishDto);
        //查询当前菜品对应的口味信息,从dish_flavor表中查
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId,dish.getId());
        List<DishFlavor> flavors = dishFlavorService.list(queryWrapper);
        dishDto.setFlavors(flavors);
        return dishDto;
    }
}

1.4.5 在DishController中创建get方法与update方法

package com.fc.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fc.reggie.common.R;
import com.fc.reggie.dto.DishDto;
import com.fc.reggie.entity.Category;
import com.fc.reggie.entity.Dish;
import com.fc.reggie.entity.DishFlavor;
import com.fc.reggie.service.CategoryService;
import com.fc.reggie.service.DishFlavorService;
import com.fc.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜品管理
 */
@RestController
@RequestMapping("/dish")
@Slf4j
public class DishController {
    @Autowired
    private DishService dishService;

    @Autowired
    private DishFlavorService dishFlavorService;

    @Autowired
    private  CategoryService categoryService;

    /**
     * 新增菜品
     * @param dishDto
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDto){
        log.info(dishDto.toString());
        dishService.saveWithFlavor(dishDto);
        return R.success("新增菜品成功");
    }

    /**
     * 菜品信息的分页
     * @param pageSize
     * @param page
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(int pageSize,int page,String name){
        //构造分页构造器
        Page<Dish> pageInfo = new Page<>(page, pageSize);
        Page<DishDto> dishDtoPage = new Page<>();
        //条件构造器
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        //添加过滤条件
        queryWrapper.like(name!=null,Dish::getName,name);
        //添加排序条件
        queryWrapper.orderByDesc(Dish::getUpdateTime);
        //执行分页查询
        dishService.page(pageInfo,queryWrapper);

        //对象拷贝
        BeanUtils.copyProperties(pageInfo,dishDtoPage,"records");

        List<Dish> records = pageInfo.getRecords();
        List<DishDto> list= records.stream().map((item)->{
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item,dishDto);
            Long categoryId = item.getCategoryId();//分类id
            //根据id查询分类对象
            Category category = categoryService.getById(categoryId);
            if(category!=null){
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }
            return  dishDto;
        }).collect(Collectors.toList());
        dishDtoPage.setRecords(list);
        return R.success(dishDtoPage);
    }

    /**
     * 根据id查询菜品信息和对应的口味信息
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<DishDto> get(@PathVariable Long id){
        DishDto dishDto = dishService.getByIdWithFlavor(id);
        return R.success(dishDto);
    }

    /**
     * 修改菜品
     * @param dishDto
     * @return
     */
    @PutMapping
    public R<String> updateWithFlavor(@RequestBody DishDto dishDto){
        log.info(dishDto.toString());
        dishService.updateWithFlavor(dishDto);
        return R.success("修改菜品成功");
    }

    /**
     * 根据条件查询对应的菜品数据
     * @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);
    }
}

1.4.6 功能测试

代码编写完成之后,重启服务,然后按照前面分析的操作流程进行测试,查看数据是否正常修改即可。

17 新增套餐模块+餐品信息回显+多数据表存储

1.1 新增套餐需求分析

后台系统中可以管理套餐信息,通过新增套餐功能来添加一个新的套餐,在添加套餐时需要选择当前套餐所属的套餐分类和包含的菜品,并且需要上传套餐对应的图片,在移动端会按照套餐分类来展示对应的套餐。

在这里插入图片描述

1.2 新增套餐数据模型

新增套餐,其实就是将新增页面录入的套餐信息插入到setmeal表,还需要向setmeal_dish表插入套餐和菜品关联数据。所以在新增套餐时,涉及到两个表:

说明备注
setmeal套餐表存储套餐的基本信息
setmeal_dish套餐菜品关系表存储套餐关联的菜品的信息(一个套餐可以关联多个菜品)
1). 套餐表setmeal

在这里插入图片描述

在该表中,套餐名称name字段是不允许重复的,在建表时,已经创建了唯一索引。

在这里插入图片描述

2). 套餐菜品关系表setmeal_dish

在这里插入图片描述

在该表中,菜品的名称name,菜品的原价price 实际上都是冗余字段,因为在这张表中存储了菜品的ID(dish_id),根据该ID就可以查询出name与price的数据信息,而这里又存储了name,price。在后续的查询展示操作中,就不需要再去查询数据库获取菜品名称和原价了,这样可以简化操作。

1.3 新增套餐准备工作

在开发业务功能前,先将需要用到的类和接口基本结构创建好,无需准备Setmeal的相关实体类、Mapper接口、Service接口及实现,因为之前在做分类管理的时候,已经引入了Setmeal的相关基础代码。 接下来,我们就来完成以下的几步准备工作:

1). 实体类 SetmealDish
package com.fc.reggie.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 套餐菜品关系
 */
@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;
}

2). DTO SetmealDto

该数据传输对象DTO,主要用于封装页面在新增套餐时传递过来的json格式的数据,其中包含套餐的基本信息,还包含套餐关联的菜品集合。

package com.fc.reggie.dto;

import com.fc.reggie.entity.Setmeal;
import com.fc.reggie.entity.SetmealDish;
import lombok.Data;
import java.util.List;

@Data
public class SetmealDto extends Setmeal {

    private List<SetmealDish> setmealDishes;

    private String categoryName;
}

3). Mapper接口 SetmealDishMapper
package com.fc.reggie.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fc.reggie.entity.Setmeal;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface SetmealMapper extends BaseMapper<Setmeal> {
}

4). 业务层接口 SetmealDishService
package com.fc.reggie.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.fc.reggie.entity.SetmealDish;

public interface SetmealDishService extends IService<SetmealDish> {
}

5). 业务层实现类 SetmealDishServiceImpl
package com.fc.reggie.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fc.reggie.entity.SetmealDish;
import com.fc.reggie.mapper.SetmealDishMapper;
import com.fc.reggie.service.SetmealDishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class SetmealDishServiceImpl extends ServiceImpl<SetmealDishMapper,SetmealDish> implements SetmealDishService {
}

6). 控制层 SetmealController

套餐管理的相关业务,我们都统一在 SetmealController 中进行统一处理操作。

package com.fc.reggie.controller;

import com.fc.reggie.common.R;
import com.fc.reggie.dto.SetmealDto;
import com.fc.reggie.service.SetmealDishService;
import com.fc.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;

@RestController
@RequestMapping("/setmeal")
@Slf4j
public class SetmealController {
    @Autowired
    private SetmealService setmealService;
    @Autowired
    private SetmealDishService setmealDishService;

    /**
     * 新增套餐
     * @param setmealDto
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody  SetmealDto setmealDto){
        log.info("套餐信息:{}",setmealDto);
        setmealService.saveWithDish(setmealDto);
        return R.success("新增套餐信息成功");
    }

}

1.4 新增套餐时前端页面和服务端的交互过程

1). 点击新建套餐按钮,访问页面(backend/page/combo/add.html),页面加载发送ajax请求,请求服务端获取套餐分类数据并展示到下拉框中(已实现)

在这里插入图片描述

获取套餐分类列表的功能我们不用开发,之前已经开发完成了,之前查询时type传递的是1,查询菜品分类; 本次查询时,传递的type为2,查询套餐分类列表。

2). 访问页面(backend/page/combo/add.html),页面加载时发送ajax请求,请求服务端获取菜品分类数据并展示到添加菜品窗口中(已实现)

在这里插入图片描述

本次查询分类列表,传递的type为1,表示需要查询的是菜品的分类。查询菜品分类的目的,是添加套餐关联的菜品时,我们需要根据菜品分类,来过滤查询菜品信息。查询菜品分类列表的代码已经实现, 具体展示效果如下:

在这里插入图片描述

3). 当点击添加菜品窗口左侧菜单的某一个分类, 页面发送ajax请求,请求服务端,根据菜品分类查询对应的菜品数据并展示到添加菜品窗口中

在这里插入图片描述

4). 页面发送请求进行****图片上传,请求服务端将图片保存到服务器(已实现)

5). 页面发送请求进行****图片下载,将上传的图片进行回显(已实现)

在这里插入图片描述

6). 点击保存按钮,发送ajax请求,将套餐相关数据以json形式提交到服务端

在这里插入图片描述

经过上述的页面解析及流程分析,发送这里需要发送的请求有5个,分别是 :

A. 根据传递的参数,查询套餐分类列表(已实现)

B. 根据传递的参数,查询菜品分类列表(已实现)

C. 图片上传(已实现)

D. 图片下载展示(已实现)

E. 根据菜品分类ID,查询菜品列表

1.5 新增套餐需要开发的功能

1). 根据分类ID查询菜品列表
请求说明
请求方式GET
请求路径/dish/list
请求参数?categoryId=1397844263642378242
2). 保存套餐信息
请求说明
请求方式POST
请求路径/setmeal
请求参数json格式数据

传递的json格式数据如下:

{
    "name":"营养超值工作餐",
    "categoryId":"1399923597874081794",
    "price":3800,
    "code":"",
    "image":"9cd7a80a-da54-4f46-bf33-af3576514cec.jpg",
    "description":"营养超值工作餐",
    "dishList":[],
    "status":1,
    "idType":"1399923597874081794",
    "setmealDishes":[
    	{"copies":2,"dishId":"1423329009705463809","name":"米饭","price":200},
    	{"copies":1,"dishId":"1423328152549109762","name":"可乐","price":500},
    	{"copies":1,"dishId":"1397853890262118402","name":"鱼香肉丝","price":3800}
    ]
}

1.6 根据分类查询菜品–代码开发

1.6.1 根据分类查询菜品

在当前的需求中,只需要根据页面传递的菜品分类的ID(categoryId)来查询菜品列表即可,因此直接定义一个DishController的方法,声明一个Long类型的categoryId,这样做是没问题的。

但是考虑到该方法的拓展性,我们在这里定义方法时,通过Dish这个实体来接收参数。

在DishController中定义方法list,接收Dish类型的参数:

在查询时,需要根据菜品分类categoryId进行查询,并且还要限定菜品的状态为起售状态(status为1),然后对查询的结果进行排序。


1.6.2 根据分类查询菜品功能测试

代码编写完毕,我们重新启动服务器,进行测试,可以通过debug断点跟踪的形式查看页面传递的参数封装情况,及响应给页面的数据信息。

在这里插入图片描述

1.7 保存套餐功能–代码开发

1.7.1 逻辑分析

在进行套餐信息保存时,前端提交的数据,不仅包含套餐的基本信息,还包含套餐关联的菜品列表数据 setmealDishes。

解决方案:需要在Setmeal的基本属性的基础上,再扩充一个属性 setmealDishes来接收页面传递的套餐关联的菜品列表,

1). SetmealController中定义方法save,新增套餐
package com.fc.reggie.controller;

import com.fc.reggie.common.R;
import com.fc.reggie.dto.SetmealDto;
import com.fc.reggie.service.SetmealDishService;
import com.fc.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;

@RestController
@RequestMapping("/setmeal")
@Slf4j
public class SetmealController {
    @Autowired
    private SetmealService setmealService;
    @Autowired
    private SetmealDishService setmealDishService;

    /**
     * 新增套餐
     * @param setmealDto
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody  SetmealDto setmealDto){
        log.info("套餐信息:{}",setmealDto);
        setmealService.saveWithDish(setmealDto);
        return R.success("新增套餐信息成功");
    }

}

2). SetmealService中定义方法saveWithDish
package com.fc.reggie.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.fc.reggie.dto.SetmealDto;
import com.fc.reggie.entity.Setmeal;

public interface SetmealService extends IService<Setmeal> {
    /**
     * 新增套餐,同时需要保存套餐和菜品的关联关系
     * @param setmealDto
     */
    public void  saveWithDish(SetmealDto setmealDto);
}

3). SetmealServiceImpl实现方法saveWithDish
package com.fc.reggie.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fc.reggie.dto.SetmealDto;
import com.fc.reggie.entity.Setmeal;
import com.fc.reggie.entity.SetmealDish;
import com.fc.reggie.mapper.SetmealMapper;
import com.fc.reggie.service.SetmealDishService;
import com.fc.reggie.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
    @Autowired
    private SetmealDishService setmealDishService;
    /**
     * 新增套餐,同时需要保存套餐和菜品的关联关系
     * @param setmealDto
     */
    @Override
    @Transactional
    public void saveWithDish(SetmealDto setmealDto) {
        //保存套餐的基本信息,操作setmeal表,执行insert操作
        this.save(setmealDto);

        List<SetmealDish> setmealDishes = setmealDto.getSetmealDishes();
        setmealDishes.stream().map((item)->{
            item.setSetmealId(setmealDto.getId());
            return item;
        }).collect(Collectors.toList());

        //保存套餐和菜品的关联信息,操作setmeal_dish表,执行insert操作
        setmealDishService.saveBatch(setmealDishes);

    }
}

1.7.2 功能测试

代码编写完毕,重新启动服务器,进行测试,可以通过debug断点跟踪的形式查看页面传递的参数封装情况及套餐相关数据的保存情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值