【wiki知识库】05.分类管理实现--前端Vue模块-CSDN博客 上一篇文章我把分类模块的前端部分给大家展示出来了,这篇文章主要是为了配合上一篇,其实这一篇文章应该先写到前边,然后在发前端的部分。文章的主要内容是把分类管理的后端接口写出来。
不知道你是否还记得我们电子书模块后端接口书写的流程,【wiki知识库】02.wiki知识库SpringBoot后端的准备-CSDN博客,在这篇文章当中我是用逆向工程生成了Ebook的一些项目结构,现在我们需要Category模块。我们的第一步还是使用逆向工程。
在我们util包下的 MybatisGenerator类中修改下方的代码,把我们的表换成category,然后运行代码。
package com.my.hawiki.param;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
public class CategoryQueryParam extends PageParam {
}
package com.my.hawiki.param;
import lombok.Data;
import javax.validation.constraints.NotNull;
@Data
public class CategorySaveParam {
private Long id;
private Long parent;
@NotNull(message = "【名称】不能为空")
private String name;
@NotNull(message = "【排序】不能为空")
private Integer sort;
}
package com.my.hawiki.vo;
import lombok.Data;
@Data
public class CategoryQueryVo {
private Long id;
private Long parent;
private String name;
private Integer sort;
}
在CatagotyController中添加以下代码:
@Resource
CategoryService categoryService;
/**
* 查询所有的分类
* @return
*/
@RequestMapping("/all")
public CommonResp all(){
List<CategoryQueryVo> list = categoryService.all();
return new CommonResp(true,"查询成功",list);
}
为CategoryService接口添加all方法。然后CategoryServiceImpl实现该all方法,这个方法很简单,也用不到什么分页功能,因为前端没有去考虑分类功能的分页查询,所以直接查询的就是所有的分页。
@Resource
CategoryMapper categoryMapper;
@Override
public List<CategoryQueryVo> all() {
List<Category> categories = categoryMapper.selectList(null);
List<CategoryQueryVo> list = CopyUtil.copyList(categories, CategoryQueryVo.class);
return list;
}
CategoryController中添加下方代码:
这里我做了一个sort值重复的判断,如果你是添加数据并且数据库中也已经有了这个sort值了,你就不能在添加了。
/**
* 添加分类
* @param categorySaveParam 添加分类参数
* @return
*/
@PostMapping("/save")
public CommonResp save(@Validated @RequestBody CategorySaveParam categorySaveParam){
// 先看看这个sort有没有被占用
Category category = categoryService.getOne(new LambdaQueryWrapper<Category>()
.eq(Category::getSort,categorySaveParam.getSort()));
if(category != null && categorySaveParam.getId()==null){
return new CommonResp(false,"已经存在该顺序了",null);
}
boolean res = categoryService.saveOrUpdate(CopyUtil.copy(categorySaveParam,Category.class));
String message = Boolean.TRUE.equals(res) ? "添加成功":"添加失败";
return new CommonResp(res,message,null);
}
这里的分类删除操作其实考虑的东西还是很多的,你删除掉了这个分类,那么这个分类下的所有子分类也要删除,对应得所有电子书也都需要删除。
这个地方还是有些难度的,不过只要考虑清楚了就可以,我带着大家考虑一下。
在CategotyController中添加如下代码:
/**
* 删除分类
* @param id 分类id
* @return
*/
@DeleteMapping("/delete/{id}")
public CommonResp delete(@PathVariable("id") Long id){
boolean res = categoryService.deleteById(id);
String message = Boolean.TRUE.equals(res) ? "删除成功":"删除失败";
return new CommonResp<>(res,message,null);
}
在CategotyService中添加deleteById()方法,我这里直接写CategotyServiceImpl中的方法实现。
上来拿到Id后先去数据库中查查这个id下有多少子分类,如果大于0的话,就说明有子分类,那么我们要删除的分类就是一级分类了,我用了一个stream流操作,把所有子分类的id提取出来,然后把这个一级分类的id加进去,然后调用mapper的批量删除操作。把分类全部删除了之后,就去看看哪些电子书的一级分类编号和我们传来的一样,直接调用删除操作就行。
如果id本身就是一个二级分类的话,我们直接把这个二级分类删除掉,同样的把该二级分类下的电子书也全部删掉。
这里值得注意的就是这个 @Transactional注解,意味着我们开启事物,一旦这个方法中出错了,我们的事物要进行回滚操作。
@Override
@Transactional
public boolean deleteById(Long id) {
// 先找出来这个分类的子分类
List<Category> categories = categoryMapper.selectList(new LambdaQueryWrapper<Category>()
.eq(Category::getParent, id));
// 证明是一级分类
if(categories.size()>0){
List<Long> collect = categories.stream()
.map(Category::getId)
.collect(Collectors.toList());
collect.add(id);
categoryMapper.deleteBatchIds(collect);
ebookMapper.delete(new LambdaQueryWrapper<Ebook>()
.eq(Ebook::getCategory1Id, id));
}else{
// 否则就是二级分类
categoryMapper.deleteById(id);
ebookMapper.delete(new LambdaQueryWrapper<Ebook>()
.eq(Ebook::getCategory2Id, id));
}
return true;
}