springboot项目:瑞吉外卖 前后端详细分析 part4

news2024/11/15 8:48:24

part 1
part 2
part 3
part 4 本页

文章目录

  • 5 套餐管理
    • 5.1 新增套餐
      • 5.1.1 整体分析
      • 5.1.2 前端分析
      • 5.1.3 后端分析
  • 持续更新中

5 套餐管理

5.1 新增套餐
5.2 套餐信息分页查询
5.3 删除套餐
其他小功能都比较简单且类似,不再赘述

5.1 新增套餐

5.1.1 整体分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 套餐是由菜品构成的,在添加套餐里面,可以添加菜品(会弹出每个菜品分类下的菜,比如主食下面有米饭)。套餐分类那里之前controller已经写好了,前端传不同的type分别查菜品分类、套餐分类,去修改对于的请求url即可。

在这里插入图片描述

  • 类似的,添加菜品的时候有多少菜品分类也列出来了,需要写controller处理菜品分类下对于的菜品。
    在这里插入图片描述

5.1.2 前端分析

  • 获取套餐分类的列表
getDishTypeList() {
  //通过category中的type = 1/2 查出对于的菜品分类或是套餐分类,显示到前端的下拉框中
  //返回值中的data的类型是:List<Category>,赋值给了setMealList属性进行双向绑定
  getCategoryList({ type: 2, page: 1, pageSize: 1000 }).then((res) => {
    if (res.code === 1) {
      this.setMealList = res.data.map((obj) => ({ ...obj, idType: obj.id }))
    } else {
      this.$message.error(res.msg || '操作失败')
    }
  })
},
  • 添加菜品,注意getDishList()方法!
// 添加菜品,之前有按钮点击事件绑定了这个函数
//<div class="addBut" style="margin-bottom: 20px" @click="openAddDish">+ 添加菜品</div>
openAddDish() {
  this.seachKey = ''
  this.dialogVisible = true
  //搜索条件清空,菜品重新查询,菜品类别选第一个重新查询
  this.value = ''
  this.keyInd = 0
  //每个菜品对应有哪些菜,在dishList中循环显示出来
  this.getDishList(this.dishType[0].id)
},
  • 通过套餐ID获取菜品列表分类:getDishList (id)
getDishList (id) {
  queryDishList({categoryId: id}).then(res => {
    if (res.code === 1) {
      if (res.data.length == 0) {
        this.dishAddList = []
        return
      }
      let newArr = res.data;
      newArr.forEach((n) => {
        n.dishId = n.id
        n.copies = 1
        // n.dishCopies = 1
        n.dishName = n.name
      })
      this.dishAddList = newArr
    } else {
      this.$message.error(res.msg)
    }
  })
},

其中queryDishList({categoryId: id}) 发送ajax请求,根据categoryId获取dish(获取当前套餐分类下的菜)。dish表中有category_id(相当于是副键),也就是说,一个category对应很多的dish。

//提交表单,最主要的代码,把整体数据提交上去。
submitForm(formName, st) {
  this.$refs[formName].validate((valid) => {
    if (valid) {
      let prams = { ...this.ruleForm }
      prams.price *= 100
      prams.setmealDishes = this.dishTable.map((obj) => ({
        copies: obj.copies,
        dishId: obj.dishId,
        name: obj.name,
        price: obj.price,
      }))
      prams.status = this.ruleForm ? 1 : 0
      prams.categoryId = this.ruleForm.idType
      if(prams.setmealDishes.length < 1){
        this.$message.error('请选择菜品!')
        return 
      }
      if(!this.imageUrl){
        this.$message.error('请上传套餐图片')
        return 
      }
      // delete prams.dishList
      if (this.actionType == 'add') {
        delete prams.id
        //发送请求
        addSetmeal(prams)
          .then((res) => {
            if (res.code === 1) {
              this.$message.success('套餐添加成功!')
              if (!st) {
                this.goBack()
              } else {
                this.$refs.ruleForm.resetFields()
                this.dishList = []
                this.dishTable = []
                this.ruleForm = {
                  name: '',
                  categoryId: '',
                  price: '',
                  code: '',
                  image: '',
                  description: '',
                  dishList: [],
                  status: true,
                  id: '',
                  idType: '',
                }
                this.imageUrl = ''
              }
            } else {
              this.$message.error(res.msg || '操作失败')
            }
          })
          .catch((err) => {
            this.$message.error('请求出错了:' + err)
          })
      } else {
        delete prams.updateTime
        editSetmeal(prams)
          .then((res) => {
            if (res.code === 1) {
              this.$message.success('套餐修改成功!')
              this.goBack()
            } else {
              this.$message.error(res.msg || '操作失败')
            }
          })
          .catch((err) => {
            this.$message.error('请求出错了:' + err)
          })
      }
    } else {
      return false
    }
  })
},

其中调用的方法

// 新增数据接口
const addSetmeal = (params) => {
  return $axios({
    url: '/setmeal',
    method: 'post',
    data: { ...params }
  })
}

5.1.3 后端分析

  • 对应的套餐分类复用了之前的,根据 category中的type = 1/2 查出对于的菜品分类或是套餐分类,显示到前端的下拉框中

在这里插入图片描述

  1. 现在解决点击某个分类,显示该分类下具体菜品。
    在这里插入图片描述
    代码:
/**
 * 根据菜品分类查菜品比如: 川菜这个选项一点击,就通过这个controller返回一个list(元素就是各种川菜dish)
 * @param dish 参数只有一个categoryId,
 * @return
 */
@GetMapping("list/getDishByCategoryId.do")
public RetObj getDishByCategoryId(Dish dish){
    LambdaQueryWrapper<Dish> lambdaQueryWrapper = new LambdaQueryWrapper<>();
    lambdaQueryWrapper.eq(dish != null,Dish::getCategoryId,dish.getCategoryId())
            .orderByDesc(Dish::getSort);

    List<Dish> dishList = dishService.list(lambdaQueryWrapper);
    return RetObj.success(dishList);
}

在这里插入图片描述
2. 对应菜品分类下的菜品查询到并显示到前端后,整体添加页面提交请求给后端,进行插入数据。这里 肯定需要操作来个表,因为新增套餐这个页面提交的数据就涉及来个表的数据,主要是套餐下有很多菜品。
在这里插入图片描述
分析前端发送过来的数据

{
  "name": "二逼餐饮",
  "categoryId": "1641061323236622337",
  "price": 12300,
  "code": "",
  "image": "abfe28a3-35af-493d-a043-295189807847.jpg",
  "description": "asdf",
  "dishList": [],
  "status": 1,
  "idType": "1641061323236622337",
  
  "setmealDishes": [
    {
      "copies": 1,
      "dishId": "1645433949618958337",
      "name": "二逼2",
      "price": 32100
    },
    {
      "copies": 1,
      "dishId": "1413384757047271425",
      "name": "王老吉",
      "price": 500
    },
    {
      "copies": 1,
      "dishId": "1413385247889891330",
      "name": "米饭",
      "price": 200
    },
    {
      "copies": 1,
      "dishId": "1397860578738352129",
      "name": "白切鸡",
      "price": 6600
    }
  ]
}

注意setmealDishes,这里面只有我们选中的菜品的信息,对setmeal_dish这个表进行操作的时候,肯定还需要setmeal_id,就是这个菜现在属于哪个套餐分类中,这个要自己加。
思路和之前类似,写一个MealDto,把meal的信息(名称、价格、图片等等存进去),还要报错对应的dish的信息,一次封装到MealDto
中。

  • Dto类如下
@Data
public class SetMealDto extends Setmeal {
    //名字一定要和前端一致,否则无法注入
    List<SetmealDish> setmealDishes;
}

  • service的处理,注意需要给setmeal_dish这个表插入具体菜品的时候,需要setmeal_id这个信息。List<SetmealDish>这个前端传来的数据中肯定没有这些菜品对应的套餐的setmeal_id,这个就需要我们重新构造一个list,把前端传来的那个list进行完善,添加setmeal_id的值。
@Transactional
public void saveMealWithFlavor(SetMealDto setMealDto) {
    this.save(setMealDto);
    List<SetmealDish> setmealDishes = setMealDto.getSetmealDishes();
    //setmealDishes中有一个字段:setmeal_id,这个字段在上面那个list中肯定是没有的!
    // 只有每个菜品自己的信息,这个setmeal_id就是setMealDto中的id
    List<SetmealDish> afterCompleteList = setmealDishes.stream().map(item -> {
        SetmealDish setmealDish = new SetmealDish();
        BeanUtils.copyProperties(item,setmealDish);
        setmealDish.setSetmealId(setMealDto.getId().toString());
        return setmealDish;
    }).collect(Collectors.toList());
    boolean res = setmealDishService.saveBatch(afterCompleteList);
    if (res == false){
        throw new RuntimeException("套餐中菜品导入失败!");
    }
}
  • controller 简单编写
@PostMapping("/add/setmeal.do")
public RetObj setMealController(@RequestBody SetMealDto setMealDto){
    setmealService.saveMealWithFlavor(setMealDto);
    return RetObj.success("成功新增套餐!");
}

持续更新中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/452801.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jmeter取样器javaRequest脚本8

1,创建一个maven工程2,通过maven编译打包生成一个jar包3,重启jmeter&#xff0c;新建java request请求4,开始执行脚本本文永久更新地址: 1,创建一个maven工程 在pom.xml文件中添加 maven下载地址&#xff1a;https://mvnrepository.com/artifact/org.apache.jmeter/ApacheJMe…

【MySQL】关于 SQL 语句执行分析的二三事

一、为什么要发生这件事 确实&#xff0c; 平时我们增删改查写的好好的&#xff0c; 各种业务代码&#xff0c;各种小接口写的不亦乐乎&#xff0c;正常是没时间干这个的&#xff0c;但是但是&#xff0c;这不是还有点技术追求嘛&#xff0c;假如我们平时测一个小接口&#xf…

【LeetCode】199.二叉树的右视图

1.问题 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1,3,4] 示例 2: 输入: [1,null,3] 输出: [1,3] 示例 3: 输入: [] 输出: []…

类加载过程

基本说明 反射机制是Java实现动态语言的关键&#xff0c;也就是通过反射实现类动态加载。 静态加载&#xff1a;编译时加载相关的类&#xff0c;如果没有则报错&#xff0c;依赖性太强动态加载&#xff1a;运行时加载需要的类&#xff0c;如果运行时不用该类&#xff0c;即使…

C++关于线程的一些操作

线程创建和接收 std::this_thread::get_id()获取当前线程的线程ID std::this_thread::yield()让步结束当前线程的时间片 int main() {vector<thread> threads(2);threads[0] thread([]() {cout << this_thread::get_id() << endl;});threads[1] thread([](…

Baumer工业相机中偏振相机如何使用Baumer堡盟GAPI SDK来进行偏振数据的计算转换输出(C#)

项目场景 Baumer工业相机堡盟相机是一种高性能、高质量的工业相机&#xff0c;可用于各种应用场景&#xff0c;如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能&#xff0c;可以实时传输高分辨率图像。此外&#xff0c;该相机还具…

ansible自动运维——ansible使用临时命令通过模块来执行任务

大家好&#xff0c;这里是天亮之前ict&#xff0c;本人网络工程大三在读小学生&#xff0c;拥有锐捷的ie和红帽的ce认证。每天更新一个linux进阶的小知识&#xff0c;希望能提高自己的技术的同时&#xff0c;也可以帮助到大家 另外其它专栏请关注&#xff1a; 锐捷数通实验&…

【机器学习实战】Python基于SVD奇异值分解进行矩阵分解(八)

文章目录 1 前言1.1 奇异值分解1.2 奇异值分解的应用 2 简单计算SVD2.1 NumPy 计算 SVD2.2 scikit-learn 计算截断 SVD2.3 scikit-learn 计算随机 SVD 3 demo数据演示3.1 导入函数3.2 导入数据3.3 计算SVD 4 讨论 1 前言 1.1 奇异值分解 奇异值分解&#xff08;Singular Valu…

信息安全复习四:置换密码乘积密码隐写术

一、章节梗概 置换密码、Rail Fence密码、行置换密码、乘积密码、转子机、隐写术 二、置换技术 2.1 定义 重新排列明文字母&#xff0c;达到信息加密的目的。 与替代密码不同的是&#xff0c;原来明文中的字母同样出现在密文中&#xff0c;只是顺序被打断。 古典的置换密码…

.net6 core Worker Service项目发布部署到Linux,以守护进程服务的形式部署启动

一、发布项目 1、以文件夹形式 2、目标运行时选对应的平台&#xff08;Linux-x64&#xff09; 3、文件夹选项&#xff1a;在发布前删除所有现有文件 二、部署项目&#xff08;安装.net6环境&#xff1a;参考Linux安装 dotnet sdk 6.0&#xff09; &#xff08;1&#xff09;…

《Spring MVC》 第二章 让程序run起来

前言 Spring MVC 是 Spring 框架提供的一款基于 MVC 模式的轻量级 Web 开发框架。 Spring MVC 本质是对 Servlet 的进一步封装&#xff0c;其最核心的组件是DispatcherServlet&#xff0c;它是 Spring MVC 的前端控制器&#xff0c;主要负责对请求和响应的统一地处理和分发。C…

用好Python自然语言工具包-- 实例“基于本地知识库的自动问答”

首先鸣谢thomas-yanxin 本问中示例来自他在GitHub上的开源项目“基于本地知识库的自动问答”&#xff0c;链接如下&#xff1a; thomas-yanxin/LangChain-ChatGLM-Webui: 基于LangChain和ChatGLM-6B的针对本地知识库的自动问答 (github.com) 目录 1. 基础知识&#xff1a; …

JVM调优最佳参数

项目背景 C端的项目&#xff0c;用户量比较多&#xff0c;请求比较多。 启动参数表 Xmx指定应用程序可用的最大堆大小。 Xms指定应用程序可用的最小堆大小。 &#xff08;一般情况下&#xff0c;需要设置Xmx和Xms为相等的值&#xff0c;且为一个固定的值&#xff09; 如果该值…

HCIP之链路聚合、VRRP

链路聚合 链路聚合 --- 可以将多个物理接口绑定成一个逻辑接口&#xff0c;即将N条物理链路聚合为一条逻辑链路。可以在不升级硬件的条件下&#xff0c;达到增加带宽的效果 我们将逻辑链路&#xff0c;称为聚合链路&#xff0c;在华为设备中称为ETH-TRUNK链路&#xff08;这个技…

Vue表单进阶操作

多选框另类使用场景 这个复选框和上面爱好那个复选框是不一样的&#xff0c;它不需要收集value值&#xff0c;只需要知道是否被选择&#xff0c;也就是ture或false&#xff0c;这时候就可以安装输入框的方式去写&#xff0c;直接去定义字符串&#xff0c;而不是数组 然后把全部…

“esp8266mod模块连接机智云Arduino实现pwm调节led的亮度“+_+

经过几天的漫长的探索和调试&#xff0c;终于连上机智云了。 历经的困难&#xff1a;esp8266总是连接机智云app超时&#xff0c;连接无反应&#xff0c;无数据。 1、机智云开发者中心&#xff0c;新建数据点&#xff0c;生成muc代码包&#xff0c;具体配置可以参考其他文章。…

go破冰之旅·5·常量、变量、数据类型

成体系的、快速学通Go&#xff0c;就在此时&#xff0c;持续连载&#xff01; 上一篇&#xff1a; https://lan6193.blog.csdn.net/article/details/123454411https://lan6193.blog.csdn.net/article/details/123454411上文熟悉了Go的基础符号、基础规则&#xff0c;本文我们…

前端项目代码规范

一、变量与函数的命名&#xff08;变量名和函数名是最好的注释&#xff09; 通常情况下函数小陀峰、类名大陀峰、变量短横线/小陀峰、const全大写单词要表达出正确的语义&#xff0c;如&#xff1a;array类型或其它集合类型用英语复数格式、其它类型不要用复数格式区分函数为功…

async/await 在 C# 语言中是如何工作的?(下)

接《async/await 在 C# 语言中是如何工作的&#xff1f;&#xff08;上&#xff09;》、《async/await 在 C# 语言中是如何工作的&#xff1f;&#xff08;中&#xff09;》&#xff0c;今天我们继续介绍 SynchronizationContext 和 ConfigureAwait。 ▌SynchronizationContext…

【SVN已解决】修改svn服务端地址为ip或者域名地址的方法

介绍 这里是小编成长之路的历程&#xff0c;也是小编的学习之路。希望和各位大佬们一起成长&#xff01; 以下为小编最喜欢的两句话&#xff1a; 要有最朴素的生活和最遥远的梦想&#xff0c;即使明天天寒地冻&#xff0c;山高水远&#xff0c;路远马亡。 一个人为什么要努力&a…