瑞吉外卖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数据结构相同,所以服务端只需要提供一个方法统一处理  

<el-button
  v-if="action != 'edit'"
  type="primary"
  size="medium"
  class="continue"
  @click="submitForm('go')"
> 保存并继续添加 </el-button>

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

所以说当我们在前端页面点击 “保存并继续添加” 时,就会发送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组件展示到页面上

// 查询列表接口
const getCategoryPage = (params) => {
  return $axios({
    url: '/category/page',
    method: 'get',
    params
  })
}

具体的请求信息整理如下  

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

3. 删除分类 

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

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

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

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

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

4. 修改分类

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

代码实现

CategoryMapper  

@Mapper
public interface CategoryMapper extends BaseMapper<Category> {
}

CategoryService  

public interface CategoryService extends IService<Category>{

    R<String> saveSortInfo(Category category);

    R<String> deleteSortInfo(Long id);

    R<Page> pageSortInfo(int page, int pageSize);

    R<String> updateSortInfo(Category category);
}

CategoryServiceImpl  

@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private SetmealMapper setmealMapper;

    @Override
    public R<String> saveSortInfo(Category category) {
        categoryMapper.insert(category);
        return R.success("新增分类成功!");
    }

    @Override
    public R<String> deleteSortInfo(Long id) {
        // 添加查询条件,根据分类id进行查询菜品数据
        LambdaQueryWrapper<Dish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishLambdaQueryWrapper.eq(Dish::getCategoryId, id);
        int count1 = dishMapper.selectCount(dishLambdaQueryWrapper);
        
        // 如果已经关联,抛出一个业务异常
        if (count1 > 0) {
            throw new CustomException("当前分类下关联了菜品,不能删除!");
        }
          
        // 查询当前分类是否关联了套餐,如果已经关联,抛出一个业务异常
        LambdaQueryWrapper<Setmeal> setmealLambdaQueryWrapper = new LambdaQueryWrapper<>();
        setmealLambdaQueryWrapper.eq(Setmeal::getCategoryId, id);
        int count2 = setmealMapper.selectCount(setmealLambdaQueryWrapper);

        if (count2 > 0) {
            throw new CustomException("当前分类下套餐了菜品,不能删除!");
        }

        super.removeById(id);
        return R.success("分类信息删除成功!");
    }

    @Override
    public R<String> updateSortInfo(Category category) {
        categoryMapper.updateById(category);
        return R.success("修改完成!");
    }

    @Override
    public R<Page> pageSortInfo(int page, int pageSize) {
        Page<Category> pageInfo = new Page<>(page, pageSize);
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(Category::getSort);
        categoryMapper.selectPage(pageInfo, queryWrapper);
        return R.success(pageInfo);
    }
}

CategoryController  

/**
 * 分类管理
 */
@Slf4j
@RestController
@RequestMapping("/category")
public class CategoryController {

    @Autowired
    private CategoryService categoryService;

    /**
     * 新增菜品
     * @param category
     * @return
     */
    @PostMapping
    public R<String> saveSortInfo(@RequestBody Category category) {
        return categoryService.saveSortInfo(category);
    }

    /**
     * 删除菜品,根据id删除分类,删除之前做一下判断,是否有关联
     * @param id
     * @return
     */
    @DeleteMapping
    public R<String> deleteSortInfo(Long id) {
        return categoryService.deleteSortInfo(id);
    }

    /**
     * 修改菜品
     * @param category
     * @return
     */
    @PutMapping
    public R<String> updateSortInfo(@RequestBody Category category) {
        return categoryService.updateSortInfo(category);
    }

    /**
     * 分页
     * @param page
     * @param pageSize
     * @return
     */
    @GetMapping("/page")
    public R<Page> pageSortInfo(int page, int pageSize) {
        return categoryService.pageSortInfo(page, pageSize);
    }

}

创建自定义异常  

/**
 * 自定义业务异常类
 */
public class CustomException extends RuntimeException{
    public CustomException(String msg) {
        super(msg);
    }
}

GlobalExceptionHandler 

/**
 * 全局异常处理
 * @ControllerAdvice: 表示拦截 类上有 @RestController 注解的类
 * @ResponseBody:封装成JSON数据
 */
@ControllerAdvice(annotations = {RestController.class, Controller.class})
@ResponseBody
@Slf4j
public class  GlobalExceptionHandler {

    /**
     * 异常处理方法
     * @return
     */
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
        log.error(ex.getMessage());
        if(ex.getMessage().contains("Duplicate entry")){
            String[] split = ex.getMessage().split(" ");
            String msg = split[2] + "已存在";
            return R.error(msg);
        }
        return R.error("未知错误");
    }

    /**
     * 异常处理方法
     * @return
     */
    @ExceptionHandler(CustomException.class)
    public R<String> exceptionHandler(CustomException ex){
        log.error(ex.getMessage());

        return R.error(ex.getMessage());
    }
}

代码获取(免费)

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

posted @ 2022-11-03 19:38  金鳞踏雨  阅读(33)  评论(0编辑  收藏  举报  来源