前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >瑞吉外卖(三)分类管理业务开发

瑞吉外卖(三)分类管理业务开发

作者头像
小沐沐吖
发布2022-09-21 15:04:57
5350
发布2022-09-21 15:04:57
举报
文章被收录于专栏:小沐沐吖小沐沐吖

01、公共字段自动填充

1、需求分析

创建时间、创建人、修改时间、修改人等字段,在处理业务时几乎都会使用。因此这些字段属于公共字段,而且很多表中都有这些字段,我们想要对这些字段进行统一处理

我们可以使用Mybatis Plus提供的公共字段自动填充功能

2、代码实现

1、在实体类的属性上接入@TableField注解,指定自动填充的策略

代码语言:javascript
复制
@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;

2、编写BaseContext工具类,基于ThreadLocal封装的工具类 目录:common

代码语言:javascript
复制
package cn.mu00.reggie.common;

/**
 * 基于ThreadLocal封装工具类,用于保存和获取当前登录用户的id
 */
public class BaseContext {
    private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();


    public static void setCurrentId(Long id){
        threadLocal.set(id);
    }

    public static Long getCurrentId(){
        return threadLocal.get();
    }
}

3、在LoginCheckFilterdoFilter方法中调用BaseContext来设置当前登录用户的id

代码语言:javascript
复制
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    ...

    // 4、判断登陆状态,如果已登录,则直接放行
    if (request.getSession().getAttribute("employee") != null){
        
        // 调用BaseContext来设置当前登录用户的id
        Long empId = (Long) request.getSession().getAttribute("employee");
        BaseContext.setCurrentId(empId);
        
        log.info("用户已登录,用户id为:{}", empId);
        filterChain.doFilter(request, response);
        return;
    }
    
    ...
}

4、按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要实现MetaObjectHandler接口 目录:commonMyMetaObjectHandler的方法中调用BaseContext获取登录用户的id

代码语言:javascript
复制
package cn.mu00.reggie.common;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 自定义元数据对象处理器
 */
@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {

    /**
     * 插入操作,自动填充
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("公共字段自动填充【insert】...");
        log.info(metaObject.toString());
        metaObject.setValue("createTime", LocalDateTime.now());
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("createUser", BaseContext.getCurrentId());
        metaObject.setValue("updateUser", BaseContext.getCurrentId());
    }

    /**
     * 更新操作,自动填充
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("公共字段自动填充【update】...");
        log.info(metaObject.toString());
        metaObject.setValue("updateTime", LocalDateTime.now());
        metaObject.setValue("updateUser", BaseContext.getCurrentId());
    }
}

5、删除EmployeeController中关于创建时间、创建人、修改时间、修改人等字段的设置,以及部分请求方法中没有使用的request参数

02、新增分类

1、需求分析

  • 请求地址:http://localhost:8080/category
  • 请求类型:POST
  • 请求参数:namesorttype
  • 注:type:1-菜品分类、2-套餐分类
新增分类
新增分类

2、代码实现

01.Category实体类

代码语言:javascript
复制
package cn.mu00.reggie.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 分类
 */
@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;


}

02.CategoryMapper

代码语言:javascript
复制
package cn.mu00.reggie.mapper;

import cn.mu00.reggie.entity.Category;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

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

03.CategoryService

代码语言:javascript
复制
package cn.mu00.reggie.service;

import cn.mu00.reggie.entity.Category;
import com.baomidou.mybatisplus.extension.service.IService;

public interface CategoryService extends IService<Category> {
}

04.CategoryServiceImpl

代码语言:javascript
复制
package cn.mu00.reggie.service.impl;

import cn.mu00.reggie.entity.Category;
import cn.mu00.reggie.mapper.CategoryMapper;
import cn.mu00.reggie.service.CategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

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

05.CategoryController

代码语言:javascript
复制
package cn.mu00.reggie.controller;

import cn.mu00.reggie.service.CategoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 分类管理
 */
@Slf4j
@RestController
@RequestMapping("/category")
public class CategoryController {
    @Autowired
    private CategoryService categoryService;
}

06.新增分类方法

位置:CategoryController

代码语言:javascript
复制
/**
 * 新增分类
 * @param category
 * @return
 */
@PostMapping
public R<String> save(@RequestBody Category category){
    log.info("category: {}", category.toString());
    categoryService.save(category);
    return R.success("新增分类成功");
}

03、分类信息分页查询

1、需求分析

  • 请求地址:http://localhost:8080/category/page?page=页码&pageSize=每页数量
  • 请求类型:GET
  • 请求参数:pagepageSize
  • 注:page默认:1,pageSize默认:10
分类信息分页查询
分类信息分页查询

2、代码实现

位置:CategoryController

代码语言:javascript
复制
/**
 * 分类信息分页查询
 * @param page
 * @param pageSize
 * @return
 */
@GetMapping("/page")
public R<Page<Category>> page(int page, int pageSize){
    // 分页构造器
    Page<Category> pageInfo = new Page<>(page, pageSize);
    // 条件构造器
    LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
    // 添加排序条件,根据sort进行排序
    queryWrapper.orderByAsc(Category::getSort);

    // 进行分页查询
    categoryService.page(pageInfo, queryWrapper);
    return R.success(pageInfo);
}

04、删除分类

1、需求分析

  • 请求地址:http://localhost:8080/category?id=分类id
  • 请求类型:DELETE
  • 注:当分类关联了菜品或套餐时,不允许删除
删除分类
删除分类

2、代码实现

位置:CategoryController

代码语言:javascript
复制
/**
 * 根据id删除分类
 * @param id
 * @return
 */
@DeleteMapping
public R<String> delete(Long id){
    log.info("删除分类,id为:{}", id);

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

3、功能完善

我们虽然实现了根据id删除分类的功能,但是并没有检查删除的分类是否关联了菜品或者套餐,所以我们需要进行功能完善

准备

01.Dish实体类

代码语言:javascript
复制
package cn.mu00.reggie.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
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;


    //菜品分类id
    private 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;


    //是否删除
    private Integer isDeleted;

}

02.DishMapper

代码语言:javascript
复制
package cn.mu00.reggie.mapper;

import cn.mu00.reggie.entity.Dish;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface DishMapper extends BaseMapper<Dish> {
}

03.DishService

代码语言:javascript
复制
package cn.mu00.reggie.service;

import cn.mu00.reggie.entity.Dish;
import com.baomidou.mybatisplus.extension.service.IService;

public interface DishService extends IService<Dish> {
}

04.DishServiceImpl

代码语言:javascript
复制
package cn.mu00.reggie.service.impl;

import cn.mu00.reggie.entity.Dish;
import cn.mu00.reggie.mapper.DishMapper;
import cn.mu00.reggie.service.DishService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
}

05.Setmeal实体类

代码语言:javascript
复制
package cn.mu00.reggie.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
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;


    //分类id
    private 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;


    //是否删除
    private Integer isDeleted;
}

06.SetmealMapper

代码语言:javascript
复制
package cn.mu00.reggie.mapper;

import cn.mu00.reggie.entity.Setmeal;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface SetmealMapper extends BaseMapper<Setmeal> {
}

07.SetmealService

代码语言:javascript
复制
package cn.mu00.reggie.service;

import cn.mu00.reggie.entity.Setmeal;
import com.baomidou.mybatisplus.extension.service.IService;

public interface SetmealService extends IService<Setmeal> {
}

08.SetmealServiceImpl

代码语言:javascript
复制
package cn.mu00.reggie.service.impl;

import cn.mu00.reggie.entity.Setmeal;
import cn.mu00.reggie.mapper.SetmealMapper;
import cn.mu00.reggie.service.SetmealService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class SetmealServiceImpl extends ServiceImpl<SetmealMapper, Setmeal> implements SetmealService {
}

09.代码实现

1、改造delete方法 位置:CategoryController

代码语言:javascript
复制
/**
 * 根据id删除分类
 * @param id
 * @return
 */
@DeleteMapping
public R<String> delete(Long id){
    log.info("删除分类,id为:{}", id);

    categoryService.remove(id);
    return R.success("分类信息删除成功");
}

2、添加remove方法 位置:CategoryService

代码语言:javascript
复制
public void remove(Long id);

3、实现remove方法 位置:CategoryServiceImpl

代码语言:javascript
复制
/**
 *根据id删除分类,删除之前需要进行判断
 * @param id
 */
@Override
public void remove(Long id) {
    LambdaQueryWrapper<Dish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();
    // 添加查询条件,根据分类id
    dishLambdaQueryWrapper.eq(Dish::getCategoryId, id);
    int dishCount = dishService.count(dishLambdaQueryWrapper);

    // 查询当前分类是否关联菜品,如果已经关联,抛出一个业务异常
    if (dishCount > 0){
        // 已经关联菜品,抛出一个业务异常
        throw new CustomException("当前分类下关联了菜品,不能删除");
    }


    // 查询当前分类是否关联套餐,如果已经关联,抛出一个业务异常
    LambdaQueryWrapper<Setmeal> setmealLambdaQueryWrapper = new LambdaQueryWrapper<>();
    // 添加查询条件,根据分类id
    setmealLambdaQueryWrapper.eq(Setmeal::getCategoryId, id);
    int setmealCount = setmealService.count(setmealLambdaQueryWrapper);

    if (setmealCount > 0){
        // 已经关联套餐,抛出一个业务异常
        throw new CustomException("当前分类下关联了套餐,不能删除");
    }

    // 正常删除分类
    super.removeById(id);
}

4、创建业务异常CustomException 目录:common

代码语言:javascript
复制
package cn.mu00.reggie.common;

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

5、在全局异常处理器GlobalExceptionHandler中,捕获异常CustomException

代码语言:javascript
复制
/**
 * 业务异常处理方法
 * @return
 */
@ExceptionHandler(CustomException.class)
public R<String> exceptionHandler(CustomException ex){
    log.error(ex.getMessage());
    return R.error(ex.getMessage());
}

05、修改分类

1、需求分析

  • 请求地址:http://localhost:8080/category
  • 请求类型:PUT
  • 请求参数:idnamesort
修改分类
修改分类

2、代码实现

位置:CategoryController

代码语言:javascript
复制
/**
 * 根据id修改分类信息
 * @param category
 * @return
 */
@PutMapping
public R<String> update(@RequestBody Category category){
    log.info("修改分类信息:{}", category.toString());
    categoryService.updateById(category);
    return R.success("分类信息修改成功");
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022 年 08 月,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01、公共字段自动填充
    • 1、需求分析
      • 2、代码实现
      • 02、新增分类
        • 1、需求分析
          • 2、代码实现
            • 01.Category实体类
            • 02.CategoryMapper
            • 03.CategoryService
            • 04.CategoryServiceImpl
            • 05.CategoryController
            • 06.新增分类方法
        • 03、分类信息分页查询
          • 1、需求分析
            • 2、代码实现
            • 04、删除分类
              • 1、需求分析
                • 2、代码实现
                  • 3、功能完善
                    • 01.Dish实体类
                    • 02.DishMapper
                    • 03.DishService
                    • 04.DishServiceImpl
                    • 05.Setmeal实体类
                    • 06.SetmealMapper
                    • 07.SetmealService
                    • 08.SetmealServiceImpl
                    • 09.代码实现
                • 05、修改分类
                  • 1、需求分析
                    • 2、代码实现
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档