03-瑞吉外卖关于菜品/套餐分类表的增删改查

新增菜品/套餐分类

页面原型

当我们在后台系统中添加菜品/套餐时,需要选择一个菜品/套餐分类,在移动端也会按照菜品分类和套餐分类来展示对应的菜品和套餐

第一步: 用户点击确定按钮执行submitForm函数发送Ajax请求,将新增菜品/套餐表单中输入的数据以json形式提交给服务端,等待服务端响应数据后执行回调函数

在这里插入图片描述

<!--用户在表单页面category/list.html中填写分类名称和排序数字-->
<el-form class="demo-form-inline" label-width="100px"><el-form-item label="分类名称:"><el-input v-model="classData.name" placeholder="请输入分类名称" maxlength="14"/></el-form-item><el-form-item label="排序:"><el-input v-model="classData.sort"  type="number" placeholder="请输入排序" /></el-form-item>
</el-form><span slot="footer" class="dialog-footer"><el-button size="medium" @click="classData.dialogVisible = false">取 消</el-button><el-button type="primary" size="medium" @click="submitForm()">确 定</el-button><el-button v-if="action != 'edit'" type="primary" size="medium" class="continue" @click="submitForm('go')"> 保存并继续添加 </el-button>
submitForm(st) {const classData = this.classDataconst valid = (classData.name === 0 ||classData.name)  && (classData.sort === 0 || classData.sort)if (this.action === 'add') {if (valid) {const reg = /^\d+$/if (reg.test(classData.sort)) {addCategory({'name': classData.name,'type':this.type, sort: classData.sort}).then(res => {console.log(res)if (res.code === 1) {this.$message.success('分类添加成功!')if (!st) {this.classData.dialogVisible = false} else {this.classData.name = ''this.classData.sort = ''}this.handleQuery()}}}}}

第二步: 服务端Controller接收页面提交的数据并通过Service调用Mapper操作数据库保存添加的菜品/套餐分类信息

在这里插入图片描述

数据模型

数据模型category表: id是主键,name字段表示分类名称是唯一的,type字段为1表示菜品分类,为2表示套餐分类

在这里插入图片描述

后端处理请求

第一步: 创建实体类Category,对于createUser和createTime等公共字段使用自动填充功能

@Data
public class Category implements Serializable {private static final long serialVersionUID = 1L;private Long id;//类型 1 菜品分类 2 套餐分类private Integer type;//分类名称private String name;//顺序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;
}

第二步: 创建Mapper接口CategoryMapper和Service接口CategoryService及其实现类CatrgoryServiceImpl

@Mapper
public interface CategoryMapper extends BaseMapper<Category> {
}public interface CategoryService extends IService<Category> {
}@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {
}

第三步: 在CategoryController控制层中编写控制器方法,将接收到的json数据添加到数据库中并响应一个成功的提示信息

@Slf4j
@RestController
@RequestMapping("/category")
public class CategoryController {@Autowiredprivate CategoryService categoryService;@PostMappingpublic Result<String> save(@RequestBody Category category) {log.info("category:{}", category);categoryService.save(category);return Result.success("新增分类成功");}
}

分页查询所有菜品/套餐分类

页面原型

第一步:用户点击分页管理按钮时携带分页查询的相关参数page(默认1)、pageSize(默认10)发送Ajax请求到服务端去查询菜品/套餐的分类信息

在这里插入图片描述

第二步: 服务端Controller接受到请求之后通过Service调用Mapper操作数据库查询相关的菜品/套餐信息

在这里插入图片描述

第三步: Controller将查询到的所有数据和分页信息响应给前端

第四步: 前端接收到后端响应的数据后,通过ElementUI的Table组件渲染到页面上

  • 页面加载完毕之后调用created钩子函数,在该钩子函数内又调用init函数进行初始化
created() {this.init()
}
async init () {await getCategoryPage({'page': this.page, 'pageSize': this.pageSize}).then(res => {if (String(res.code) === '1') {//将服务端查询到的所有数据赋给tableData,然后就能看到了this.tableData = res.data.recordsthis.counts = Number(res.data.total)} else {this.$message.error(res.msg || '操作失败')}}).catch(err => {this.$message.error('请求出错了:' + err)})
}
// 查询列表接口
const getCategoryPage = (params) => {return $axios({url: '/category/page',method: 'get',params})
}

后端处理请求

执行categoryService提供的page方法进行分页查询并将查询到的数据和分页信息响应给前端

@GetMapping("/page")
public Result<Page> page(int page, int pageSize) {// 创建分页构造器Page<Category> pageInfo = new Page<>(page, pageSize);// 构造条件查询器LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();// 添加排序条件,根据sort属性进行排序queryWrapper.orderByDesc(Category::getSort);// 执行分页查询的语句categoryService.page(pageInfo, queryWrapper);// 将查询到的所有数据和分页相关的信息响应给前端return Result.success(pageInfo);
}

删除某个分类(判断有无关联)

页面原型

第一步:在分类管理列表页面, 用户点击某个分类对应的删除按钮发送Ajax请求,请求参数就是该菜品/套餐分类单元格对应的属性Id

  • 删除是个危险的操作,当用户点击删除按钮时先给一个提示信息防止误操作,当用户点确定后才会执行deleCategory回调函数

在这里插入图片描述

<el-buttontype="text"size="small"class="delBut non"<!--删除按钮绑定了deleteHandle函数,参数就是当前单元格的Id-->@click="deleteHandle(scope.row.id)">
</el-button>
<script>deleteHandle(id) {this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {'confirmButtonText': '确定','cancelButtonText': '取消','type': 'warning'}).then(() => {deleCategory(id).then(res => {// 服务端成功删除后提示'删除成功!'if (res.code === 1) {this.$message.success('删除成功!')this.handleQuery()} else {this.$message.error(res.msg || '操作失败')}}).catch(err => {this.$message.error('请求出错了:' + err)})})}// 发其Ajax请求删除当前行const deleCategory = (id) => {return $axios({url: '/category',method: 'delete',params: {id}})}
</script>

第二步:服务端Controller接收页面提交的菜品/套餐分类的Id,通过Service调用Mapper根据Id删除对应的纪录,如果该分类关联了某个菜品或套餐时不允许被删除

在这里插入图片描述

后端处理请求(无关联)

@DeleteMapping
private Result<String> delete(Long id) {log.info("将被删除的id:{}", id);categoryService.removeById(id);return Result.success("分类信息删除成功");
}

查询菜品/套餐

删除某个分类时需要先拿着当前分类的Id值去对应的菜品/套餐表中进行查询,如果能查询到数据则说明该分类关联了菜品/套餐,此时不能删除该分类

在这里插入图片描述

数据模型

套餐信息表setmeal

在这里插入图片描述

菜品信息表dish

在这里插入图片描述

后端处理请求

第一步: 创建菜品表和套餐表对应的模型类DishStemal,对于createUser和createTimecreateUser和updateUser等公共字段使用自动填充功能

/**菜品*/
@Data
public class Dish implements Serializable {private static final long serialVersionUID = 1L;private Long id;//菜品名称private String name;//菜品分类idprivate 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;
}
/*** 套餐*/
@Data
public class Setmeal implements Serializable {private static final long serialVersionUID = 1L;private Long id;//分类idprivate Long categoryId;//套餐名称private String name;//套餐价格private BigDecimal price;//状态 0:停用 1:启用private Integer status;//编码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;
}

第二步: 编写对应的Mapper接口和Service接口及其实现类

@Mapper
public interface DishMapper extends BaseMapper<Dish> {
}@Mapper
public interface SetmealMapper extends BaseMapper<Setmeal> {
}public interface SetmealService extends IService<Setmeal> {
}
@Service
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
}public interface DishService extends IService<Dish> {
}
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
}

第三步: 在common包下新增CustomException异常类用于封装我们的自定义异常

public class CustomException extends RuntimeException{public CustomException(String msg){super(msg);}
}

第四步: 在全局异常处理器中使用@ExceptionHandler注解专门处理CustomerException类型的异常

@ExceptionHandler(CustomException.class)
public Result<String> exceptionHandler(CustomException exception) {log.error(exception.getMessage());return Result.error(exception.getMessage());
}

第五步: CategoryService接口中新增remove方法, 在删除数据之前先根据当前菜品/套餐分类的categoryId值去dish表和setmeal表中查询是否关联了数据

  • 如果查询到了数据: 说明存在关联的菜品/套餐数据即不能删除需要抛出一个自定义异常
  • 如果查询不到数据: 说明不存在关联的菜品/套餐数据那么可以正常删除
@Service
@Slf4j
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {@AutowiredDishService dishService;@AutowiredSetmealService setmealService;/*** 根据id删除分类,删除之前需要进行判断* @param id*/@Overridepublic void remove(Long id) {// 根据菜品的分类id去菜品表中查询关联的菜品记录LambdaQueryWrapper<Dish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();dishLambdaQueryWrapper.eq(Dish::getCategoryId, id);int count1 = dishService.count(dishLambdaQueryWrapper);// 判断菜品当前分类是否关联了菜品,如果已经关联则抛出异常if (count1 > 0){throw new CustomException("当前分类下关联了菜品,不能删除");}// 根据套餐的分类id去套餐表中查询关联的套餐记录LambdaQueryWrapper<Setmeal> setmealLambdaQueryWrapper = new LambdaQueryWrapper<>();setmealLambdaQueryWrapper.eq(Setmeal::getCategoryId,id);// 判断当前套餐分类是否关联了套餐,如果已经关联则抛出异常int count2 = setmealService.count(setmealLambdaQueryWrapper);if (count2 > 0){throw new CustomException("当前分类下关联了套餐,不能删除");}// 没有关联菜品/套餐则调用CategoryService自带的removeById方法正常删除super.removeById(id);}
}

第六步: 在Controller中调用CategoryService新增的remove方法

@DeleteMapping
public Result<String> delete(Long id){log.info("将要删除的分类id:{}",id);categoryService.remove(id);return Result.success("分类信息删除成功");
}

修改分类信息

页面原型

第一步: 用户在分类管理列表页面中点击修改"按钮后弹出修改窗口,此时会回显当前菜品/套餐分类的信息并等待用户修改(通过Vue的数据绑定功能实现自动回显)

在这里插入图片描述

<el-buttontype="text"size="small"class="blueBug"<!--回显当前分类的信息,参数就是当前单元格的信息-->@click="editHandle(scope.row)"
>
修改
</el-button><el-formclass="demo-form-inline"label-width="100px"><el-form-item label="分类名称:"><el-inputv-model="classData.name"placeholder="请输入分类名称"maxlength="14"/></el-form-item><el-form-item label="排序:"><el-input v-model="classData.sort"  type="number" placeholder="请输入排序" /></el-form-item>
</el-form><script>editHandle(dat) {// 这里并没有从后端查数据进行回显,而是对Vue双向绑定的数据classData下的name和sort属性进行赋值实现回显效果this.classData.title = '修改分类'this.action = 'edit'this.classData.name = dat.namethis.classData.sort = dat.sortthis.classData.id = dat.idthis.classData.dialogVisible = true}classData: {'title': '添加菜品分类','dialogVisible': false,'categoryId': '','name': '',sort: ''}
</script>

第二步: 用户点击确定按钮后执行通用的submitForm函数发起Ajax请求,以json格式提交修改后的菜品/套餐分类信息
在这里插入图片描述

<script>submitForm(st) {const classData = this.classDataconst valid = (classData.name === 0 ||classData.name)  && (classData.sort === 0 || classData.sort)// 添加操作从这里执行if (this.action === 'add') {if (valid) {const reg = /^\d+$/if (reg.test(classData.sort)) {addCategory({'name': classData.name,'type':this.type, sort: classData.sort}).then(res => {console.log(res)if (res.code === 1) {this.$message.success('分类添加成功!')if (!st) {this.classData.dialogVisible = false} else {this.classData.name = ''this.classData.sort = ''}this.handleQuery()} else {this.$message.error(res.msg || '操作失败')}}).catch(err => {this.$message.error('请求出错了:' + err)})} else {this.$message.error('排序只能输入数字类型')}} else {this.$message.error('请输入分类名称或排序')}// 修改操作从这里执行} else if (valid) {const reg = /^\d+$/if (reg.test(this.classData.sort)) {// 发起ajax请求修改员工数据editCategory({'id':this.classData.id,'name': this.classData.name, sort: this.classData.sort}).then(res => {if (res.code === 1) {this.$message.success('分类修改成功!')this.classData.dialogVisible = falsethis.handleQuery()} else {this.$message.error(res.msg || '操作失败')}}).catch(err => {this.$message.error('请求出错了:' + err)})} else {this.$message.error('排序只能输入数字类型')}} else {this.$message.error('请输入分类名称或排序')}}// 修改接口const editCategory = (params) => {return $axios({url: '/category',method: 'put',data: { ...params }})}
</script>

后端处理请求

根据用户提交的json格式的菜品/套餐分类信息,去数据表中更新对应的菜品/套餐记录

@PutMapping
public Result<String> update(@RequestBody Category category) {log.info("修改分类信息为:{}", category);categoryService.updateById(category);return Result.success("修改分类信息成功");
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法分析与设计课后练习22

设W(5,7,10,12,15,18,20)和M35&#xff0c;使用过程SUMOFSUB找出W种使得和数等于M的全部子集并画出所生成的部分状态空间树

CV计算机视觉每日开源代码Paper with code速览-2023.11.16

点击CV计算机视觉&#xff0c;关注更多CV干货 论文已打包&#xff0c;点击进入—>下载界面 点击加入—>CV计算机视觉交流群 1.【基础网络架构】ConvNet vs Transformer, Supervised vs CLIP: Beyond ImageNet Accuracy 论文地址&#xff1a;https://arxiv.org//pdf/23…

数据分析思维与模型:多维度拆解分析法

多维度拆解分析法"&#xff08;Multi-Dimensional Analysis and Decomposition Method&#xff09;是一种用于深入分析和解决复杂问题的方法论。这种方法侧重于从多个角度或维度来考察问题&#xff0c;以便于更全面地理解和解决它们。它通常包括以下几个步骤&#xff1a; …

环保回收信息展示预约小程序的效果如何

人们每天在线上的时间非常多&#xff0c;他们会通过线上寻找信息&#xff0c;而环保回收企业也在通过线上寻找客户&#xff0c;但受限于平台限制&#xff0c;无论引流获客还是营销互动、或是数据分析及全面管理方面都面对难题&#xff0c;其中微信/百度/快手/抖音/支付宝/快手等…

我在CSDN开组会1-蒙特卡洛模拟在矿床学的应用展望

各位老师、同学们&#xff0c;大家好。今天组会的内容是蒙特卡洛模拟在矿床学的应用展望。 为什么要讲蒙特卡洛模拟呢&#xff0c;因为我发现在地质学方面已经有不少应用&#xff0c;但是蒙特卡洛模拟延伸的知识太晦涩了&#xff0c;劝退了很多探究者们。因此&#xff0c;计划…

DSP介绍及CCS

文章目录 CCS版本编译器CCS使用注意严禁中文 CCS的基本操作新建工程导入现有工程调整字体的大小工程界面恢复标签的使用 仿真盒小虫子进入在线Debug 芯片TMS320F28355基本介绍特性 DSP中特殊指令dsp指令中的EALLOW EDIS CCS TI官网 版本 CCS版本&#xff1a; CCS8.3.1.0004_…

腾讯云HAI域AI作画

目录 &#x1f433;前言&#xff1a; &#x1f680;了解高性能应用服务 HAI &#x1f47b;即插即用 轻松上手 &#x1f47b;横向对比 青出于蓝 &#x1f424;应用场景-AI作画 &#x1f424;应用场景-AI对话 &#x1f424;应用场景-算法研发 &#x1f680;使用HAI进行…

Web 自动化神器 TestCafe—页面基本操作篇

前 言 Testcafe是基于node.js的框架&#xff0c;以操作简洁著称&#xff0c;是web自动化的神器 今天主要给大家介绍一下testcafe这个框架和页面元素交互的方法。 一、互动要求 使用 TestCafe 与元素进行交互操作&#xff0c;元素需满足以下条件&#xff1a;☟ 元素在 body 页…

怎么让NetCore接口支持Json参数

项目&#xff1a;NetCore Web API 接口支持Json参数需要安装Newtonsoft.Json.Linq和Microsoft.AspNetCore.Mvc.NewtonsoftJson Program代码 //支持json需要安装Microsoft.AspNetCore.Mvc.NewtonsoftJson using Newtonsoft.Json.Serialization;var builder WebApplication.Cr…

【Seata源码学习 】篇三 TM开启全局事务的过程

【Seata源码学习 】篇三 TM开启全局事务的过程 TM发送 单个或批量 消息 以发送GlobalBeginRequest消息为例 TM在执行拦截器链路前将向TC发送GlobalBeginRequest 消息 io.seata.tm.api.DefaultGlobalTransaction#begin(int, java.lang.String) Overridepublic String begin(…

媲美有线操作,支持4KHz响应和无线充电的游戏鼠标,雷柏VT3S上手

对于无线鼠标来说&#xff0c;操作延迟和精度对游戏操作影响很大&#xff0c;常见的游戏鼠标至少都有1KHz的回报率&#xff0c;而雷柏今年已经出了很多支持4KHz回报的鼠标了&#xff0c;像是我现在用的这款VT3S游戏鼠标&#xff0c;就搭载了旗舰级的原相3395引擎&#xff0c;支…

git撤销未git commit的文件

目录 一、问题描述 二、方式1&#xff1a;git命令撤销&#xff08;更专业&#xff09; 1、文件已git add&#xff0c;未git commit 2、本地修改&#xff0c;未git add &#xff08;1&#xff09;撤销处于unstage的文件&#xff0c;即删除已有变动 &#xff08;2&#xff…

netty整合websocket(完美教程)

websocket的介绍&#xff1a; WebSocket是一种在网络通信中的协议&#xff0c;它是独立于HTTP协议的。该协议基于TCP/IP协议&#xff0c;可以提供双向通讯并保有状态。这意味着客户端和服务器可以进行实时响应&#xff0c;并且这种响应是双向的。WebSocket协议端口通常是80&am…

一些损失函数的学习

CrossEntropy loss 交叉熵是用来衡量两个概率分布之间的差异性或不相似性的度量交叉熵定义为两个概率分布p和q之间的度量。其中&#xff0c;p通常是真实分布&#xff0c;而q是模型预测的分布 交叉熵还等于信息熵 相对熵 这里&#xff0c;x遍历所有可能的事件&#xff0c;p(x)…

Window下如何对Redis进行开启与关闭

目录 前言1. 图文界面2. 命令行 前言 由于长期使用Linux界面&#xff0c;对于Window下的Redis&#xff0c;不知如何下手。特此记录该博文 特别注意&#xff0c;刚下载好的Redis&#xff0c;如果需要配置密码&#xff0c;可以再该文件进行配置&#xff1a;redis.windows-servi…

基于知识问答的上下文学习中的代码风格11.20

基于知识问答的上下文学习中的代码风格 摘要1 引言2 相关工作3 方法3.1 概述3.2 元函数设计3.3 推理 4 实验4.1 实验设置4.2 实施细节4.3 主要结果 摘要 现有的基于知识的问题分类方法通常依赖于复杂的训练技术和模型框架&#xff0c;在实际应用中存在诸多局限性。最近&#x…

Redis-高性能原理剖析

redis安装 下载地址&#xff1a;http://redis.io/download 安装步骤&#xff1a; # 安装gcc yum install gcc# 把下载好的redis-5.0.3.tar.gz放在/usr/local文件夹下&#xff0c;并解压 wget http://download.redis.io/releases/redis-5.0.3.tar.gz tar -zxvf redis-5.0.3.tar…

如何让bug远离你?

想让bug远离你&#xff0c;当然是靠佛祖保佑~ /** *************************************************************************** ******************** ********************* ******************** COPYRIGHT INFORMATION *…

09【保姆级】-GO语言的数组和切片

09【保姆级】-GO语言的数组 一、数组1.1 数组定义1.2 数组的使用1.3 数组的遍历1.4 数组的应用案例 二、切片2.1 切片的介绍2.2 切片的原理2.3 切片的三种使用 之前我学过C、Java、Python语言时总结的经验&#xff1a; 先建立整体框架&#xff0c;然后再去抠细节。先Know how&a…

如何使用SD-WAN提升物流供应链网络效率

案例背景 本次分享的物流供应链企业是一家国际性的大型企业&#xff0c;专注于提供全球范围内的物流和供应链解决方案。案例用户在不同国家和地区均设有多个分支机构和办公地点&#xff0c;以支持客户需求和业务运营。 在过去&#xff0c;该企业用户使用传统的MPLS网络来连接各…