• 瑞吉外卖项目:新增菜品与菜品分页查询


    目录

    一. 新增菜品

    1.1 需求分析

    1.2 数据模型

    1.3?代码实现

    二. 菜品分页查询

    2.1 需求分析

    2.2 代码编写


    一. 新增菜品

    1.1 需求分析

    后台系统可以管理菜品信息,通过新增功能来添加新的菜品,在添加菜品时需要选择当前菜品所属的菜品分类。

    此外还需要上传菜品图片,在移动端会按照菜品分类来展示对应的菜品信息。

    1.2 数据模型

    设计两张表菜品表与菜品口味表,添加某个菜品的口味做法时,需要加入菜品口味表中。

    菜品表(dish)

    菜品口味表(dish_flavor)

    在开发代码之前,需要梳理一下新增菜品时前端页面和服务端的交互过程:

    1. 页面(backend/page/food/add.html)发送aiax请求,请求服务端获取菜品分类数据并展示到下拉框中
    2. 页面发送请求进行图片上传,请求服务端将图片保存到服务器
    3. 页面发送请求进行图片下载,将上传的图片进行回显
    4. 点击保存按钮,发送ajax请求,将菜品相关数据以ison形式提交到服务端

    dishFlavor.java

    package com.itheima.reggie.entity;
    
    import com.baomidou.mybatisplus.annotation.FieldFill;
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableId;
    import lombok.Data;
    
    import java.io.Serializable;
    import java.time.LocalDateTime;
    
    /**
     * 菜品口味
     */
    @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;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    填好所需数据发的添加菜品的mock格式如下:

    {
      "name": "test1",
      "price": 1200,
      "code": "",
      "image": "bbbf37f0-00c1-4dff-8825-b79506ad33cf.jpg",
      "description": "sdfg",
      "status": 1,
      "categoryId": "1397844263642378242",
      "flavors": [
        {
          "name": "辣度",
          "value": "["不辣","微辣","中辣","重辣"]",
          "showOption": false
        },
        {
          "name": "温度",
          "value": "["热饮","常温","去冰","少冰","多冰"]",
          "showOption": false
        }
      ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    **注意:**在Dish(这里)这个对象中并没有封装口味对象,所以我们需要对上面的JSON数据重新封装。

    DishDTO.java

    package com.itheima.reggie.dto;
    
    import com.itheima.reggie.entity.Dish;
    import com.itheima.reggie.entity.DishFlavor;
    import lombok.Data;
    import java.util.ArrayList;
    import java.util.List;
    
    @Data
    public class DishDto extends Dish {
    
        /** 菜品口味*/
        private List flavors = new ArrayList<>();
    
        private String categoryName;
    
        private Integer copies;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    什么是DTO?

    Data Transfer Object,数据传输对象,用于展示层与服务层之间的数据传输

    1.3代码实现

    DishServiceImpl.java中添加如下代码:

    package com.itheima.reggie.service.impl;
    
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.itheima.reggie.dto.DishDto;
    import com.itheima.reggie.entity.Dish;
    import com.itheima.reggie.entity.DishFlavor;
    import com.itheima.reggie.mapper.DishMapper;
    import com.itheima.reggie.service.DishFlavorService;
    import com.itheima.reggie.service.DishService;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import javax.annotation.Resource;
    import java.util.List;
    import java.util.stream.Collectors;
    
    /**
     * @author jektong
     * @date 2022年05月10日 20:15
     */
    @Service
    public class DishServiceImpl extends ServiceImpl implements DishService {
    
        @Resource
        private DishFlavorService dishFlavorService;
    
        /**
         * 新增菜品,同时插入菜品对应的口味数据
         * @param dishDto
         */
        @Override
        @Transactional
        public void saveWithFlover(DishDto dishDto) {
            // 保存菜品基本信息到菜品表dish
            this.save(dishDto);
            // 获取菜品ID
            Long dishId = dishDto.getId();
            List flavors = dishDto.getFlavors();
            // 菜品ID设置进口味中
            flavors = flavors.stream().map((item)->{
                item.setDishId(dishId);
                return item;
            }).collect(Collectors.toList());
    
            // 菜品口味数据保存
            dishFlavorService.saveBatch(flavors);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    由于以上代码涉及多次对数据库的操作,所以需要加上注解:

    @Transactional并需要在启动类上开启事务注解@EnableTransactionManagement才可生效

    package com.itheima.reggie;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.web.servlet.ServletComponentScan;
    import org.springframework.transaction.annotation.EnableTransactionManagement;
    
    /**
     * @author tongbing
     * @date 2022/4/21
     */
    @Slf4j
    @SpringBootApplication
    @ServletComponentScan
    @EnableTransactionManagement
    public class ReggieApplication {
        public static void main(String[] args) {
            SpringApplication.run(ReggieApplication.class,args);
            log.info("reggie======>启动成功");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    DishController调用:

    package com.itheima.reggie.controller;
    
    import com.itheima.reggie.common.R;
    import com.itheima.reggie.dto.DishDto;
    import com.itheima.reggie.service.DishService;
    import lombok.extern.slf4j.Slf4j;
    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;
    
    import javax.annotation.Resource;
    
    /**
     * @author jektong
     * @date 2022年05月16日 22:22
     */
    @RestController
    @Slf4j
    @RequestMapping("/dish")
    public class DishController {
    
        @Resource
        private DishService dishService;
    
        /**
         * 新增菜品,同时插入菜品对应的口味数据
         * @param dishDto
         * @return R
         */
        @PostMapping
        public R save(@RequestBody DishDto dishDto){
            log.info("DishDTO===>{}",dishDto);
            dishService.saveWithFlover(dishDto);
            return R.success("菜品添加成功");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    二. 菜品分页查询

    2.1 需求分析

    分页展示菜品数据如下图:

    交互流程

    1. 页面(backend/page/food/listhtml)发送ajax请求,将分页查询参数(page,pageSize,name)提交到服务端,获取分页数据
    2. 页面发送请求,请求服务端进行图片下载,用于页面图片展示

    开发菜品信息分页查询功能,其实就是在服务端编写代码去处理前端页面发送的这2次请求即可。

    2.2 代码编写

    DishController代码:

        @GetMapping("/page")
        public R page(int page, int pageSize,String name){
            log.info("page={},pageSize={},name={}", page, pageSize, name);
            // 构造分页构造器
            Page pageInfo = new Page(page, pageSize);
            // 因为前端需要展示分类的名称,所以封装成DishDto对象
            Page dishDtoPage = new Page(page, pageSize);
            // 构造条件
            LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper();
            queryWrapper.like(StringUtils.isNotEmpty(name), Dish::getName, name);
            // 添加排序
            queryWrapper.orderByDesc(Dish::getUpdateTime);
            // 执行查询
            dishService.page(pageInfo, queryWrapper);
            // 进行对象拷贝,去除之前已经查出来的集合
            BeanUtils.copyProperties(pageInfo,dishDtoPage,"records");
    
            List records = pageInfo.getRecords();
            List list = records.stream().map((item)->{
                DishDto dishDto = new DishDto();
                BeanUtils.copyProperties(item,dishDto);
                // 获取categoryId
                Long categoryId = item.getCategoryId();
                // 给categoryName赋值
                Category category = categoryService.getById(categoryId);
                // 需要对查出来的分类做判断可能有的菜品没有分类
                if(category!=null){
                    dishDto.setCategoryName(category.getName());
                }
                return dishDto;
            }).collect(Collectors.toList());
            dishDtoPage.setRecords(list);
            return R.success(dishDtoPage);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    以上代码需要注意的是需要展示分类的名称,所以封装成DishDto对象进行返回就需要使用对象的拷贝,以及查出来的分类需要判空操作。

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    平凯星辰合伙人余梦杰:全球化和云计算趋势下的开源生态构建
    FaceNet-pytorch(fixing data imbalance-CASIA)
    QFile 类【官翻】
    C语言例:表达式(a=2,3),a+1的值
    docker学习(十三)docker安装dejavu
    ROS(5)PX4仿真安装及运行
    Ubuntu升级Python报错pydtrace_probes.h: No such file or directory
    电脑录屏快捷键是什么?电脑录屏是什么键
    vue2修改组件样式
    基于RocketMQ实现分布式事务
  • 原文地址:https://blog.csdn.net/m0_67403272/article/details/126081557