一.接口文档与需求分析
请求方式为DELETE,因此要使用@DeleteMapping。请求参数为id。响应为Result结果。
二.Controller层
package com.sky.controller.admin;
import com.sky.dto.CategoryDTO;
import com.sky.dto.CategoryPageQueryDTO;
import com.sky.entity.Category;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.CategoryService;
import com.sky.service.impl.CategoryServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 分类管理
*/
@RestController
@Api(tags = "分类相关接口")
@RequestMapping("/admin/category")
@Slf4j
public class CategoryController {
@Autowired
private CategoryService categoryService;
/**
* 新增分类
* @param categoryDTO
* @return
*/
@PostMapping
@ApiOperation("新增分类")
public Result save(@RequestBody CategoryDTO categoryDTO){
log.info("新增分类:{}",categoryDTO);
categoryService.save(categoryDTO);
return Result.success();
}
/**
* 分类分页查询
* @param categoryPageQueryDTO
* @return
*/
@GetMapping("/page")
@ApiOperation("分类分页查询")
public Result<PageResult> page(CategoryPageQueryDTO categoryPageQueryDTO){
log.info("分类分页查询:{}",categoryPageQueryDTO);
PageResult pageResult = categoryService.pageQuery(categoryPageQueryDTO);
return Result.success(pageResult);
}
/**
* 启用、禁用分类
* @param id
* @param status
* @return
*/
@PostMapping("/status/{status}")
@ApiOperation("启用、禁用分类")
public Result startOrStop(Long id,@PathVariable Integer status) {
log.info("启用、禁用分类:{},{}",id,status);
categoryService.startOrStop(id,status);
return Result.success();
}
/**
* 根据类型查询分类
* @param type
* @return
*/
@GetMapping("/list")
@ApiOperation("根据类型查询分类")
public Result<List<Category>> getByType(Integer type) {
log.info("根据类型查询分类:{}",type);
List<Category> list = categoryService.list(type);
return Result.success(list);
}
/**
* 修改分类
* @param categoryDTO
* @return
*/
@PutMapping
@ApiOperation("修改分类")
public Result update(@RequestBody CategoryDTO categoryDTO){
categoryService.update(categoryDTO);
return Result.success();
}
/**
* 根据id删除分类
* @param id
* @return
*/
@DeleteMapping
@ApiOperation("根据id删除分类")
public Result deleteById(Long id) {
categoryService.deleteById(id);
return Result.success();
}
}
三.Service层
接口
package com.sky.service;
import com.sky.dto.CategoryDTO;
import com.sky.dto.CategoryPageQueryDTO;
import com.sky.entity.Category;
import com.sky.result.PageResult;
import io.swagger.models.auth.In;
import java.util.List;
public interface CategoryService {
/**
* 新增分类
* @param categoryDTO
*/
void save(CategoryDTO categoryDTO);
/**
* 分类分页查询
* @param categoryPageQueryDTO
* @return
*/
PageResult pageQuery(CategoryPageQueryDTO categoryPageQueryDTO);
/**
* 启用、禁用分类
* @param id
* @param status
*/
void startOrStop(Long id, Integer status);
/**
* 根据类型查询分类
* @param type
* @return
*/
List<Category> list(Integer type);
/**
* 修改分类
* @param categoryDTO
*/
void update(CategoryDTO categoryDTO);
/**
* 根据id删除分类
* @param id
*/
void deleteById(Long id);
}
实现类
package com.sky.service.impl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.context.BaseContext;
import com.sky.dto.CategoryDTO;
import com.sky.dto.CategoryPageQueryDTO;
import com.sky.entity.Category;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.CategoryMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.CategoryService;
import io.swagger.models.auth.In;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class CategoryServiceImpl implements CategoryService {
@Autowired
private CategoryMapper categoryMapper;
@Autowired
private DishMapper dishMapper;
@Autowired
private SetmealMapper setmealMapper;
/**
* 新增分类
* @param categoryDTO
*/
@Override
public void save(CategoryDTO categoryDTO) {
Category category = new Category();
BeanUtils.copyProperties(categoryDTO,category);
category.setStatus(StatusConstant.DISABLE);
category.setCreateTime(LocalDateTime.now());
category.setUpdateTime(LocalDateTime.now());
category.setCreateUser(BaseContext.getCurrentId());
category.setUpdateUser(BaseContext.getCurrentId());
categoryMapper.insert(category);
}
/**
* 分类分页查询
* @param categoryPageQueryDTO
* @return
*/
@Override
public PageResult pageQuery(CategoryPageQueryDTO categoryPageQueryDTO) {
// 使用PageHelper插件进行分页查询
PageHelper.startPage(categoryPageQueryDTO.getPage(), categoryPageQueryDTO.getPageSize());
Page<Category> page = categoryMapper.pageQuery(categoryPageQueryDTO); // 因为要保证可以进行分类名称和分类类型的查询,因此要将categoryPageQueryDTO对象传入mapper层,从而在SQL语句中可以调用其中的属性分类名称name,分类类型type;
long total = page.getTotal();
List<Category> result = page.getResult();
PageResult pageResult = new PageResult(total,result);
return pageResult;
}
/**
* 启用、禁用分类
* @param id
* @param status
*/
@Override
public void startOrStop(Long id, Integer status) {
Category category = Category.builder()
.id(id)
.status(status)
.build();
categoryMapper.update(category);
}
/**
* 根据类型查询分类
* @param type
* @return
*/
@Override
public List<Category> list(Integer type) {
List<Category> list = categoryMapper.list(type);
return list;
}
/**
* 修改分类
* @param categoryDTO
*/
@Override
public void update(CategoryDTO categoryDTO) {
Category category = new Category();
BeanUtils.copyProperties(categoryDTO,category);
categoryMapper.update(category);
}
/**
* 根据id删除分类
* @param id
*/
@Override
public void deleteById(Long id) {
// 首先判断该分类下是否有套餐或菜品,如果有的话,就不允许删除该分类
/* 方法一
Integer count = dishMapper.countByCategoryId(id);
if(count == 0) {
count = setmealMapper.countByCategoryId(id);
if (count == 0) {
categoryMapper.deleteById(id);
} else {
throw new DeletionNotAllowedException(MessageConstant.CATEGORY_BE_RELATED_BY_SETMEAL);
}
} else {
throw new DeletionNotAllowedException(MessageConstant.CATEGORY_BE_RELATED_BY_DISH);
}
*/
Integer count = dishMapper.countByCategoryId(id);
if (count > 0)
throw new DeletionNotAllowedException(MessageConstant.CATEGORY_BE_RELATED_BY_DISH);
count = setmealMapper.countByCategoryId(id);
if (count > 0)
throw new DeletionNotAllowedException(MessageConstant.CATEGORY_BE_RELATED_BY_SETMEAL);
categoryMapper.deleteById(id);
}
}
在删除分类前,首先判断该分类下是否有套餐或菜品,如果有的话,就不允许删除该分类。那么该如何判断呢?首先要通过SQL语句对Dish和Setmeal数据库进行查询,如果所属该分类的菜品或套餐数量>0,那么就证明该分类下有套餐或者菜品,那么就不允许删除该分类。
在dish中有category_id字段,表明该菜品属于哪一个分类。
在setmeal中有category_id字段,表明该套餐属于哪一个分类。
因此我们使用语句“select count(*) from dish where category_id = #{categoryId}”来查询属于当前分类的菜品数量有多少。
使用语句"select count(*) from setmeal where category_id = #{categoryId}"来查询属于当前分类的套餐数量有多少。
因此我们定义菜品和套餐的mapper接口用来动态查询dish和setmeal数据库。
DishMapper:
package com.sky.mapper;
import com.sky.entity.Dish;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface DishMapper {
/**
* 根据category_id查询菜品中的该分类数
* @param categoryId
* @return
*/
@Select("select count(*) from dish where category_id = #{categoryId}")
Integer countByCategoryId(Long categoryId);
}
SetmealMapper:
package com.sky.mapper;
import com.sky.entity.Setmeal;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface SetmealMapper {
/**
* 根据category_id查询套餐中的该分类数
* @param categoryId
* @return
*/
@Select("select count(*) from setmeal where category_id = #{categoryId}")
Integer countByCategoryId(Long categoryId);
}
在Service层执行categoryMapper.deleteById(id);语句之前,要先进行dish和setmeal的数量判断。首先将DishMapper和SetMealMapper接口依赖注入Service层。
@Autowired
private DishMapper dishMapper;
@Autowired
private SetmealMapper setmealMapper;
然后调用其countByCategoryId方法,将categoryId传入。然后执行查询操作。如果DishMapper和SetmealMapper中的countByCategoryId方法有一个查询数量大于零,那么证明其分类下有套餐或者菜品,那么就抛出我们提前定义好的异常类DeletionNotAllowedException。传入常量CATEGORY_BE_RELATED_BY_DISH或CATEGORY_BE_RELATED_BY_SETMEAL。
DeletionNotAllowedException.class
package com.sky.exception;
public class DeletionNotAllowedException extends BaseException {
public DeletionNotAllowedException(String msg) {
super(msg);
}
}
MessageConstant.class
package com.sky.constant;
/**
* 信息提示常量类
*/
public class MessageConstant {
public static final String PASSWORD_ERROR = "密码错误";
public static final String ACCOUNT_NOT_FOUND = "账号不存在";
public static final String ACCOUNT_LOCKED = "账号被锁定";
public static final String UNKNOWN_ERROR = "未知错误";
public static final String USER_NOT_LOGIN = "用户未登录";
public static final String CATEGORY_BE_RELATED_BY_SETMEAL = "当前分类关联了套餐,不能删除";
public static final String CATEGORY_BE_RELATED_BY_DISH = "当前分类关联了菜品,不能删除";
public static final String SHOPPING_CART_IS_NULL = "购物车数据为空,不能下单";
public static final String ADDRESS_BOOK_IS_NULL = "用户地址为空,不能下单";
public static final String LOGIN_FAILED = "登录失败";
public static final String UPLOAD_FAILED = "文件上传失败";
public static final String SETMEAL_ENABLE_FAILED = "套餐内包含未启售菜品,无法启售";
public static final String PASSWORD_EDIT_FAILED = "密码修改失败";
public static final String DISH_ON_SALE = "起售中的菜品不能删除";
public static final String SETMEAL_ON_SALE = "起售中的套餐不能删除";
public static final String DISH_BE_RELATED_BY_SETMEAL = "当前菜品关联了套餐,不能删除";
public static final String ORDER_STATUS_ERROR = "订单状态错误";
public static final String ORDER_NOT_FOUND = "订单不存在";
public static final String ALREADY_EXISTS = "已存在";
}
如果分类下既无菜品又无套餐,那么就执行categoryMapper.deleteById(id);,调用Mapper层的deleteById执行删除操作。
四.Mapper层
package com.sky.mapper;
import com.github.pagehelper.Page;
import com.sky.dto.CategoryPageQueryDTO;
import com.sky.entity.Category;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface CategoryMapper {
/**
* 新增分类接口
* @param category
*/
@Insert("insert into category(type, name, sort, status, create_time, update_time, create_user, update_user) " +
"values " +
"(#{type},#{name},#{sort},#{status},#{createTime},#{updateTime},#{createUser},#{updateUser})")
void insert(Category category);
/**
* 分类分页查询
* @return
*/
Page<Category> pageQuery(CategoryPageQueryDTO categoryPageQueryDTO);
/**
* 启用、禁用分类/修改分类
* @param category
*/
void update(Category category);
/**
* 根据类型查询分类
* @param type
* @return
*/
List<Category> list(Integer type);
/**
* 根据id删除分类
* @param id
*/
@Delete("delete from category where id = #{id}")
void deleteById(Long id);
}
五.前后端联调:

