基于Springboot外卖系统12:删除菜品套餐类别+修改套餐类别信息

1. 删除分类

1.1 需求分析

在分类管理列表页面,可以对某个分类进行删除操作。需要注意的是当分类关联了菜品或者套餐时,此分类不允许删除。

1.2 前端页面分析

在前端页面中,点击 "删除" 按钮,就会触发定义的方法,然后往服务端发送异步请求,并传递参数id,执行删除分类操作。

删除操作的具体执行流程如下:

1). 点击删除,页面发送ajax请求,将参数(id)提交到服务端

2). 服务端Controller接收页面提交的数据并调用Service删除数据

3). Service调用Mapper操作数据库

从上述的分析中,可以得到请求的信息如下:

请求说明
请求方式DELETE
请求路径/category
请求参数?id=1395291114922618881

1.3 改进思路分析

删除分类数据需要检查删除的分类是否关联了菜品或者套餐,所以需要进行功能完善。完善后的逻辑为:

  • 根据当前分类的ID,查询该分类下是否存在菜品,如果存在,则提示错误信息

  • 根据当前分类的ID,查询该分类下是否存在套餐,如果存在,则提示错误信息

  • 执行正常的删除分类操作

那么在这里又涉及到两张表结构 dish(菜品表) 和 setmeal(套餐表)。具体的表结构如下:

1.4 准备工作

1.4.1 Dish菜品实体类

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.math.BigDecimal;
import java.time.LocalDateTime;/**菜品*/
@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;}

1.4.2 Setmeal套餐实体类 

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.math.BigDecimal;
import java.time.LocalDateTime;/*** 套餐*/
@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;}

1.4.3. Mapper接口DishMapper和SetmealMapper

DishMapper

package com.itheima.reggie.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.reggie.entity.Dish;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface DishMapper extends BaseMapper<Dish> {
}

SetmealMapper 

package com.itheima.reggie.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.reggie.entity.Setmeal;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface SetmealMapper extends BaseMapper<Setmeal> {
}

1.4.3 Service接口DishService和SetmealService

DishService

package com.itheima.reggie.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.reggie.entity.Dish;public interface DishService extends IService<Dish> {
}

SetmealService 

package com.itheima.reggie.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.reggie.entity.Setmeal;public interface SetmealService extends IService<Setmeal> {
}

1.5 代码实现

1). 创建自定义异常

在业务逻辑操作过程中,如果遇到一些业务参数、操作异常的情况下,直接抛出此异常。

package com.itheima.reggie.common;import javax.xml.crypto.dsig.spec.XSLTTransformParameterSpec;/*** Description: 自定义业务异常类* @date 2022/8/16 10:32*/
public class CustomException extends RuntimeException{public CustomException(String message){super(message);}
}

2). 在CategoryService中扩展remove方法

package com.itheima.reggie.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.reggie.entity.Category;public interface CategoryService extends IService<Category> {public void remove(Long id);
}

3). 在CategoryServiceImpl中实现remove方法

package com.itheima.reggie.service.impl;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.common.CustomException;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.mapper.CategoryMapper;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishService;
import com.itheima.reggie.service.SetmealService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** Description: 类别业务层接口* @version 1.0* @date 2022/8/15 13:55*/@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {@Autowiredprivate DishService dishService ;@Autowiredprivate SetmealService setmealService;@Override/**@Description: 根据id删除分类,删除之前需要判定是否关联菜品* @version v1.0* @author LiBiGo* @date 2022/8/16 10:20*/public void remove(Long id) {// A.查询当前分类是否关联菜品,关联则抛出业务异常类LambdaQueryWrapper<Dish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();// 添加查询条件,根据id查询dishLambdaQueryWrapper.eq(Dish::getCategoryId,id);int count1 = dishService.count(dishLambdaQueryWrapper);if (count1 > 0){// 已关联菜品,抛出异常throw new CustomException("当前分类下关联了菜品,不能删除");}// B.查询当前分类是否关联套餐,关联则抛出业务异常类LambdaQueryWrapper<Setmeal> setmealLambdaQueryWrapper = new LambdaQueryWrapper<>();// 添加查询条件,根据id查询setmealLambdaQueryWrapper.eq(Setmeal::getCategoryId,id);int count2 = setmealService.count(setmealLambdaQueryWrapper);if (count2 > 0){// 已关联套餐,抛出异常throw new CustomException("当前分类下关联了套餐,不能删除");}// 均无关联,则删除super.removeById(id);  // 父类实现了最基本的根据id查询的删除,所以直接调用就行}
}

那么在上述的业务逻辑中,当分类下关联的有菜品或者套餐时,在业务代码中抛出了自定义异常,会被异常处理器捕获,只需要在异常处理器中捕获这一类的异常,然后给页面返回对应的提示信息即可。

4). 在GlobalExceptionHandler中处理自定义异常

在全局异常处理器中增加方法,用于捕获自定义的异常 CustomException

package com.itheima.reggie.common;import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.sql.SQLIntegrityConstraintViolationException;
/*** Description: 全局异常处理器*/@ControllerAdvice(annotations = {RestController.class, Controller.class})// 处理@RestController、@Controller的函数异常 //指定拦截那些类型的控制器;
@ResponseBody   //将方法的返回值 R 对象转换为json格式的数据, 响应给页面;
@Slf4j
public class GlobalExceptionHandler {/**@Description: 异常处理方法* @author LiBiGo* @date 2022/8/12 17:46*/@ExceptionHandler(SQLIntegrityConstraintViolationException.class) // 处理指定异常类public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){log.error(ex.getMessage());//Duplicate entry '299067' for key 'idx_username'if(ex.getMessage().contains("Duplicate entry")){String[] split = ex.getMessage().split(" "); //提取重复字段,即哪个用户名重复 从0开始第2个即为用户名String msg = split[2] + "已存在";return R.error(msg);}return R.error("未知错误");}@ExceptionHandler(CustomException.class) // 处理自定义业务异常类public R<String> exceptionHandler(CustomException ex){log.error(ex.getMessage());return R.error(ex.getMessage());}}

5). 改造CategoryController的delete方法

注释掉原有的代码,在delete方法中直接调用categoryService中自定义的remove方法。

package com.itheima.reggie.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.R;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.service.CategoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;/*** Description: 分类管理*/@RestController
@RequestMapping("/category")
@Slf4j
public class CategoryController {@Autowiredprivate CategoryService categoryService;/**@Description: 新增分类* @author LiBiGo* @date 2022/8/15 14:05*/@PostMappingpublic R<String> save(@RequestBody Category category){log.info("category:{}",category);categoryService.save(category);return R.success("新增分类成功");}@GetMapping("/page")public R<Page> page(int page,int pageSize){/**@Description: 分页查询* @author LiBiGo* @date 2022/8/15 14:21*/// 分页构造Page<Category> pageinfo = new Page<>(page,pageSize);// 构造条件构造器对象LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper();// 添加排序条件,根据sore进行排序queryWrapper.orderByAsc(Category::getSort);// 进行分页查询categoryService.page(pageinfo,queryWrapper);return R.success(pageinfo);}@DeleteMappingpublic R<String> delete(Long id){/**@Description: 根据id删除分类* @author LiBiGo* @date 2022/8/16 9:58*/log.info("删除分类,id为{}",id);categoryService.remove(id);return R.success("分类信息删除成功");}@PutMappingpublic  R<String> update(@RequestBody Category category){/**@Description: 根据id修改分类信息* @author LiBiGo* @date 2022/8/16 10:49*/log.info("根据id修改分类信息:{}",category);categoryService.updateById(category);return R.success("修改分类成功");}
}

2. 修改分类

2.1 需求分析

在分类管理列表页面点击修改按钮,弹出修改窗口,在修改窗口回显分类信息并进行修改,最后点击确定按钮完成修改操作。

2.2 前端页面分析

这里面大家会发现,修改功能我们还没有实现,但是当点击 "修改" 按钮的时候,我们并没有开发根据ID查询数据,进行页面回显的功能,但是页面的分类数据确实回显回来了。这是怎么做到的呢,我们来解析一下前端的代码实现(前端代码已经实现):

 

 那么回显这一步的操作前端已经实现,我们就只需要开发一个方法,修改操作的方法即可。我们可以通过浏览器来抓取一下修改操作的请求信息,如图:

具体的请求信息,整理如下:

请求说明
请求方式PUT
请求路径/category
请求参数{id: "1399923597874081794", name: "超值午餐", sort: 0}

2.3 代码实现

html页面中相关的代码都已经提供好了,我们已经分析了请求的信息,接下来就可以来创建服务端的CategoryController方法update方法。

 【见上一个代码块,已集成】

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

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

相关文章

html5手机移动端三级联动城市选择器

//我的地址 var area1 new LArea(); area1.init({ trigger: #demo1, //触发选择控件的文本框&#xff0c;同时选择完毕后name属性输出到该位置 valueTo: #value1, //选择完毕后id属性输出到该位置 keys: { id: id, name: name }, //绑定数据源相关字段 id对应valueTo的value属…

我的师傅是风清扬

1 珍惜那些处处帮助你的人 国庆假期就要过去了&#xff0c;国庆这几天一直在考虑一个问题&#xff08;先保留是什么问题&#xff09;&#xff0c;也咨询了几个比较信任的朋友&#xff0c;都没有得到肯定的答案。 回家路上跟了一个大哥哥&#xff08;陈哥&#xff09;&#xf…

要多大内存才满足_佛龛的尺寸要多大?

佛龛是用于供奉佛像或者牌位的小阁子&#xff0c;大多数是木制家具。佛龛在一般是仿中国古代的房子等工程建筑制做而成&#xff0c;在其纹样层面有很高的要求&#xff0c;有关纹样今日姑且先不谈。除此之外佛龛的尺寸大小多少才算吉祥也是很有讲究的&#xff0c;那麼这个问题跟…

【YOLOV5-6.x讲解】数据配置文件 data/XXX.yaml

主干目录&#xff1a; 【YOLOV5-6.x 版本讲解】整体项目代码注释导航现在YOLOV5已经更新到6.X版本&#xff0c;现在网上很多还停留在5.X的源码注释上&#xff0c;因此特开一贴传承开源精神&#xff01;5.X版本的可以看其他大佬的帖子本文章主要从6.X版本出发&#xff0c;主要解…

python print 输出到txt_(Python基础教程之七)Python字符串操作

Python基础教程在SublimeEditor中配置Python环境Python代码中添加注释Python中的变量的使用Python中的数据类型Python中的关键字Python字符串操作Python中的list操作Python中的Tuple操作Pythonmax()和min()–在列表或数组中查找最大值和最小值Python找到最大的N个(前N个)或最小…

【YOLOV5-6.x讲解】常用工具类 models/common.py

主干目录&#xff1a; 【YOLOV5-6.x 版本讲解】整体项目代码注释导航现在YOLOV5已经更新到6.X版本&#xff0c;现在网上很多还停留在5.X的源码注释上&#xff0c;因此特开一贴传承开源精神&#xff01;5.X版本的可以看其他大佬的帖子本文章主要从6.X版本出发&#xff0c;主要解…

【YOLOV5-6.x讲解】DIY实验文件 models/experimental.py

主干目录&#xff1a; 【YOLOV5-6.x 版本讲解】整体项目代码注释导航现在YOLOV5已经更新到6.X版本&#xff0c;现在网上很多还停留在5.X的源码注释上&#xff0c;因此特开一贴传承开源精神&#xff01;5.X版本的可以看其他大佬的帖子本文章主要从6.X版本出发&#xff0c;主要解…

mysql 触发器_MySQL入门之触发器

触发器作用当操作了某张表时&#xff0c;希望同时触发一些动作/行为&#xff0c;可以使用触发器完成&#xff01;&#xff01;例如&#xff1a; 当向员工表插入一条记录时&#xff0c;希望同时往日志表插入数据。首先创建日志表-- 日志表CREATE TABLE test_log(id INT PRIMARY …

【YOLOV5-6.x讲解】模型搭建模块 models/yolo.py

主干目录&#xff1a; 【YOLOV5-6.x 版本讲解】整体项目代码注释导航现在YOLOV5已经更新到6.X版本&#xff0c;现在网上很多还停留在5.X的源码注释上&#xff0c;因此特开一贴传承开源精神&#xff01;5.X版本的可以看其他大佬的帖子本文章主要从6.X版本出发&#xff0c;主要解…

C++primer拾遗(第八章:IO库)

第八章内容不多&#xff0c;不过包含比较实用的文件读写操作。 总结不易&#xff0c;转载注明出处&#xff0c;谢谢。 http://www.cnblogs.com/linhaowei0389/ 转载于:https://www.cnblogs.com/linhaowei0389/p/6628471.html

python中cmd是什么_python中的cmd是什么

cmd模块是python中包含的一个公共模块&#xff0c;用于交互式shell和其它命令解释器等的基类。我们可以基于cmd模块自定义我们的子类&#xff0c;实现我们自己的交互式shell。 它的执行流程也挺简单的&#xff0c;使用命令行解释器循环读取输入的所有行并解析它们&#xff0c;然…

基于Springboot外卖系统13:实现文件上传下载模块

1. 上传功能模块 1.1 上传概述 文件上传&#xff0c;也称为upload&#xff0c;是指将本地图片、视频、音频等文件上传到服务器上&#xff0c;可以供其他用户浏览或下载的过程。 文件上传时&#xff0c;对页面的form表单有如下要求&#xff1a; 表单属性取值说明methodpost必…

hihoCoder #1143 : 骨牌覆盖问题·一

#1143 : 骨牌覆盖问题一 时间限制:10000ms单点时限:1000ms内存限制:256MB描述 骨牌&#xff0c;一种古老的玩具。今天我们要研究的是骨牌的覆盖问题&#xff1a;我们有一个2xN的长条形棋盘&#xff0c;然后用1x2的骨牌去覆盖整个棋盘。对于这个棋盘&#xff0c;一共有多少种不同…

关于CPU Cache -- 程序猿需要知道的那些事

关于CPU Cache -- 程序猿需要知道的那些事 本文将介绍一些作为程序猿或者IT从业者应该知道的CPU Cache相关的知识 文章欢迎转载&#xff0c;但转载时请保留本段文字&#xff0c;并置于文章的顶部 作者&#xff1a;卢钧轶(cenalulu) 本文原文地址&#xff1a;http://cenalulu.gi…

python线性回归代码_day-12 python实现简单线性回归和多元线性回归算法

1、问题引入 在统计学中&#xff0c;线性回归是利用称为线性回归方程的最小二乘函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。这种函数是一个或多个称为回归系数的模型参数的线性组合。一个带有一个自变量的线性回归方程代表一条直线。我们需要对线性回归结…

基于Springboot外卖系统14:菜品新增模块+多个数据表操作+文件上传下载复用

2.1 需求分析 后台系统中可以管理菜品信息&#xff0c;通过新增功能来添加一个新的菜品&#xff0c;在添加菜品时需要选择当前菜品所属的菜品分类&#xff0c;并且需要上传菜品图片&#xff0c;在移动端会按照菜品分类来展示对应的菜品信息 。 2.2 数据模型 新增菜品&#xff…

python层次聚类_python实现层次聚类

BAFIMINARMTO BA0662877255412996 FI6620295468268400 MI8772950754564138 NA2554687540219869 RM4122685642190669 TO9964001388696690 这是一个距离矩阵。不管是scipy还是fastcluster&#xff0c;都有一个计算距离矩阵的步骤&#xff08;也可以不用&#xff09;。距离矩阵是冗…

解析统计文本文件中的字符数、单词数、行数。

用android 编程解析统计文本文件中的字符数、单词数、行数&#xff08;作业&#xff09; 主要代码 ... private void analysis() { String str " "; int words 0; int chars 0; int lines 0; int spaces 0; int marks 0; int character 0; String filename e…

shell自动生成的文件有一个问号的后缀

写了一个脚本&#xff0c;自动处理一个文件。 rm -f session.log rm -f link wget ftp://hostname/f:/ddn/session.log egrep ^N[[:digit:]]|^D[1-4] session.log >>link egrep -c ^N[[:digit:]]|^D[1-4] session.log >>link egrep -v ACT/UP link>>link ls …

基于Springboot外卖系统15:菜品分页查询模块+根据类别ID填充类别信息

3.1 菜品分页查询功能需求分析 系统中的菜品数据很多的时候&#xff0c;如果在一个页面中全部展示出来会显得比较乱&#xff0c;不便于查看&#xff0c;所以一般的系统中都会以分页的方式来展示列表数据。 在菜品列表展示时&#xff0c;除了菜品的基本信息(名称、售价、售卖状…