• 瑞吉外卖07-对于分类信息的CRUD


    瑞吉外卖07-对于分类信息的CRUD

    数据模型

    需求分析 

    1. 新增分类

    2. 分类信息分页查询

    3. 删除分类

    4. 修改分类

    前端页面分析

    1. 新增分类

    2. 分类信息分页查询

    3. 删除分类 

    4. 修改分类

    代码实现

    代码获取(免费)


    数据模型

    分类信息我们要用一个新的表来存储——category

    我们添加的菜品/套餐名称,是唯一的,不能够重复的,所以在设计表结构时,已经针对于name字段建立了唯一索引 。

    dish(菜品表)

    setmeal(套餐表)   

    需求分析 

    1. 新增分类

    后台系统中可以管理分类信息,分类包括两种类型,分别是 菜品分类套餐分类 。当我们在后台系统中添加菜品时需要选择一个菜品分类,当我们在后台系统中添加一个套餐时需要选择一个套餐分类,在移动端也会按照菜品分类和套餐分类来展示对应的菜品和套餐。

    在分类管理中,我们新增分类时,可以选择新增菜品分类(川菜、湘菜、粤菜...),也可以选择新增套餐分类(营养早餐、超值午餐...)。

    在添加套餐的时候,输入的排序字段,控制的是移动端套餐列表的展示顺序。

    2. 分类信息分页查询

    这个点说白了就是实现一个分页查询功能。

    3. 删除分类

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

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

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

    4. 修改分类

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

    注:这里的回显是前端帮我们做的!

    前端页面分析

    1. 新增分类

    在开发代码之前,需要梳理一下整个程序的执行过程

    (1)在页面(backend/page/category/list.html)的新增分类表单中填写数据,点击 "确定" 发送ajax请求,将新增分类窗口输入的数据以json形式提交到服务端

    (2)服务端Controller接收页面提交的数据并调用Service将数据进行保存

    (3)Service调用Mapper操作数据库,保存数据

    可以看到新增菜品分类和新增套餐分类请求的服务端地址和提交的json数据结构相同,所以服务端只需要提供一个方法统一处理  

    1. v-if="action != 'edit'"
    2. type="primary"
    3. size="medium"
    4. class="continue"
    5. @click="submitForm('go')"
    6. > 保存并继续添加

    1. // 新增接口
    2. const addCategory = (params) => {
    3. return $axios({
    4. url: '/category',
    5. method: 'post',
    6. data: { ...params }
    7. })
    8. }

    所以说当我们在前端页面点击 “保存并继续添加” 时,就会发送POST的请求,具体如下:

    请求说明
    请求方式POST
    请求路径/category
    请求参数json格式 - {"name":"川菜","type":"1","sort":2}

    2. 分类信息分页查询

    在开发代码之前,需要梳理一下整个程序的执行过程

    (1)页面发送ajax请求,将分页查询参数(page、pageSize)提交到服务端

    (2)服务端Controller接收页面提交的数据并调用Service查询数据

    (3)Service调用Mapper操作数据库,查询分页数据

    (4)Controller将查询到的分页数据响应给页面

    (5)页面接收到分页数据并通过ElementUI的Table组件展示到页面上

    1. // 查询列表接口
    2. const getCategoryPage = (params) => {
    3. return $axios({
    4. url: '/category/page',
    5. method: 'get',
    6. params
    7. })
    8. }

    具体的请求信息整理如下  

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

    3. 删除分类 

    在开发代码之前,需要梳理一下整个程序的执行过程

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

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

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

    1. // 删除当前列的接口
    2. const deleCategory = (id) => {
    3. return $axios({
    4. url: '/category',
    5. method: 'delete',
    6. params: { id }
    7. })
    8. }
    请求说明
    请求方式DELETE
    请求路径/category
    请求参数?id=1395291114922618881

    4. 修改分类

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

    代码实现

    CategoryMapper  

    1. @Mapper
    2. public interface CategoryMapper extends BaseMapper {
    3. }

    CategoryService  

    1. public interface CategoryService extends IService{
    2. R saveSortInfo(Category category);
    3. R deleteSortInfo(Long id);
    4. R pageSortInfo(int page, int pageSize);
    5. R updateSortInfo(Category category);
    6. }

    CategoryServiceImpl  

    1. @Service
    2. public class CategoryServiceImpl extends ServiceImpl implements CategoryService {
    3. @Autowired
    4. private CategoryMapper categoryMapper;
    5. @Autowired
    6. private DishMapper dishMapper;
    7. @Autowired
    8. private SetmealMapper setmealMapper;
    9. @Override
    10. public R saveSortInfo(Category category) {
    11. categoryMapper.insert(category);
    12. return R.success("新增分类成功!");
    13. }
    14. @Override
    15. public R deleteSortInfo(Long id) {
    16. // 添加查询条件,根据分类id进行查询菜品数据
    17. LambdaQueryWrapper dishLambdaQueryWrapper = new LambdaQueryWrapper<>();
    18. dishLambdaQueryWrapper.eq(Dish::getCategoryId, id);
    19. int count1 = dishMapper.selectCount(dishLambdaQueryWrapper);
    20. // 如果已经关联,抛出一个业务异常
    21. if (count1 > 0) {
    22. throw new CustomException("当前分类下关联了菜品,不能删除!");
    23. }
    24. // 查询当前分类是否关联了套餐,如果已经关联,抛出一个业务异常
    25. LambdaQueryWrapper setmealLambdaQueryWrapper = new LambdaQueryWrapper<>();
    26. setmealLambdaQueryWrapper.eq(Setmeal::getCategoryId, id);
    27. int count2 = setmealMapper.selectCount(setmealLambdaQueryWrapper);
    28. if (count2 > 0) {
    29. throw new CustomException("当前分类下套餐了菜品,不能删除!");
    30. }
    31. super.removeById(id);
    32. return R.success("分类信息删除成功!");
    33. }
    34. @Override
    35. public R updateSortInfo(Category category) {
    36. categoryMapper.updateById(category);
    37. return R.success("修改完成!");
    38. }
    39. @Override
    40. public R pageSortInfo(int page, int pageSize) {
    41. Page pageInfo = new Page<>(page, pageSize);
    42. LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
    43. queryWrapper.orderByAsc(Category::getSort);
    44. categoryMapper.selectPage(pageInfo, queryWrapper);
    45. return R.success(pageInfo);
    46. }
    47. }

    CategoryController  

    1. /**
    2. * 分类管理
    3. */
    4. @Slf4j
    5. @RestController
    6. @RequestMapping("/category")
    7. public class CategoryController {
    8. @Autowired
    9. private CategoryService categoryService;
    10. /**
    11. * 新增菜品
    12. * @param category
    13. * @return
    14. */
    15. @PostMapping
    16. public R saveSortInfo(@RequestBody Category category) {
    17. return categoryService.saveSortInfo(category);
    18. }
    19. /**
    20. * 删除菜品,根据id删除分类,删除之前做一下判断,是否有关联
    21. * @param id
    22. * @return
    23. */
    24. @DeleteMapping
    25. public R deleteSortInfo(Long id) {
    26. return categoryService.deleteSortInfo(id);
    27. }
    28. /**
    29. * 修改菜品
    30. * @param category
    31. * @return
    32. */
    33. @PutMapping
    34. public R updateSortInfo(@RequestBody Category category) {
    35. return categoryService.updateSortInfo(category);
    36. }
    37. /**
    38. * 分页
    39. * @param page
    40. * @param pageSize
    41. * @return
    42. */
    43. @GetMapping("/page")
    44. public R pageSortInfo(int page, int pageSize) {
    45. return categoryService.pageSortInfo(page, pageSize);
    46. }
    47. }

    创建自定义异常  

    1. /**
    2. * 自定义业务异常类
    3. */
    4. public class CustomException extends RuntimeException{
    5. public CustomException(String msg) {
    6. super(msg);
    7. }
    8. }

    GlobalExceptionHandler 

    1. /**
    2. * 全局异常处理
    3. * @ControllerAdvice: 表示拦截 类上有 @RestController 注解的类
    4. * @ResponseBody:封装成JSON数据
    5. */
    6. @ControllerAdvice(annotations = {RestController.class, Controller.class})
    7. @ResponseBody
    8. @Slf4j
    9. public class GlobalExceptionHandler {
    10. /**
    11. * 异常处理方法
    12. * @return
    13. */
    14. @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    15. public R exceptionHandler(SQLIntegrityConstraintViolationException ex){
    16. log.error(ex.getMessage());
    17. if(ex.getMessage().contains("Duplicate entry")){
    18. String[] split = ex.getMessage().split(" ");
    19. String msg = split[2] + "已存在";
    20. return R.error(msg);
    21. }
    22. return R.error("未知错误");
    23. }
    24. /**
    25. * 异常处理方法
    26. * @return
    27. */
    28. @ExceptionHandler(CustomException.class)
    29. public R exceptionHandler(CustomException ex){
    30. log.error(ex.getMessage());
    31. return R.error(ex.getMessage());
    32. }
    33. }

    代码获取(免费)

    瑞吉外卖: 瑞吉外卖项目完整代码,使用Sprinboot,SSM,MP,MySQL,Redis,Nginx等技术。 - Gitee.comicon-default.png?t=M85Bhttps://gitee.com/Harmony_TL/reggie_take_out/tree/reggie_v7_sort

  • 相关阅读:
    DataX更新null值到ElasticSearch不生效的问题
    如何用Python机器学习、深度学习提升气象、海洋、水文领域实践能力!!!
    threehit漏洞复现以及防御
    【FPGA教程案例79】通信案例5——基于FPGA的QPSK调制解调系统实现
    Linux基本命令
    多测师肖sir_高级讲师_第2个月第12讲pyhton+pymysql
    内存分析总结
    下一代实时数据库:Apache Doris 【四】扩容缩容
    Apache Derby的使用
    大数据调度最佳实践 | 从Airflow迁移到Apache DolphinScheduler
  • 原文地址:https://blog.csdn.net/weixin_43715214/article/details/127675745