一、分类模块(Category)接口
1. 全量分类查询 findAllDetail()
java
运行
@Override
public Result findAllDetail() {
LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
List<Category> categories = categoryMapper.selectList(queryWrapper);
return Result.success(copyList(categories));
}
- 逻辑:无筛选条件查询全部分类,调用
copyList批量转 VO 后返回 - 特点:返回所有分类数据,常用于前端分类下拉框、侧边栏等场景
2. 分类详情查询 categoryDetailById()
java
运行
@Override
public Result categoryDetailById(Long id) {
Category category = categoryMapper.selectById(id);
return Result.success(copy(category));
}
- 逻辑:根据 ID 查询单个分类详情,调用
copy方法转为 VO - 关键:
copy方法实现了Long 雪花 ID 转 String,避免前端精度丢失
3. 核心 VO 转换方法
java
运行
public CategoryVo copy(Category category) {
CategoryVo categoryVo = new CategoryVo();
BeanUtils.copyProperties(category, categoryVo);
// 关键处理:将Long类型的ID转为String,适配前端JS
categoryVo.setId(String.valueOf(category.getId()));
return categoryVo;
}
public List<CategoryVo> copyList(List<Category> categoryList) {
List<CategoryVo> categoryVoList = new ArrayList<>();
for (Category category : categoryList) {
categoryVoList.add(copy(category));
}
return categoryVoList;
}
BeanUtils.copyProperties:实现同名属性快速拷贝String.valueOf(category.getId()):核心处理,解决前端 JS 对大整数精度丢失的问题
二、标签模块(Tag)接口
1. 全量标签查询 findAllDetail()
java
运行
@Override
public Result findAllDetail() {
LambdaQueryWrapper<Tag> queryWrapper = new LambdaQueryWrapper<>();
List<Tag> tags = this.tagMapper.selectList(queryWrapper);
return Result.success(copyList(tags));
}
- 逻辑与分类接口完全一致,查询全量标签后转 VO 返回
2. 标签详情查询 findDetailById()
java
运行
@Override
public Result findDetailById(Long id) {
Tag tag = tagMapper.selectById(id);
return Result.success(copy(tag));
}
- 逻辑:根据 ID 查询单个标签详情,转 VO 后返回
- 注:代码结构与分类详情接口高度一致,体现了代码的复用性设计
三、文章列表接口 listArticle()(分页 + 多条件 + Redis 浏览量)
java
运行
@Override
public Result listArticle(PageParams pageParams) {
// 1. 构建分页对象
Page<Article> page = new Page<>(pageParams.getPage(), pageParams.getPageSize());
// 2. 多条件分页查询文章(分类、标签、年份、月份)
IPage<Article> articleIPage = articleMapper.listArticle(
page,
pageParams.getCategoryId(),
pageParams.getTagId(),
pageParams.getYear(),
pageParams.getMonth());
List<Article> records = articleIPage.getRecords();
// 3. 从Redis补充实时浏览量(替代DB数据)
for (Article record : records) {
String viewCount = (String) redisTemplate.opsForHash()
.get("view_count", String.valueOf(record.getId()));
if (viewCount != null) {
record.setViewCounts(Integer.parseInt(viewCount));
}
}
// 4. 转VO并返回
return Result.success(copyList(records, isTag: true, isAuthor: true));
}
核心亮点拆解
- MyBatis-Plus 分页 :
Page对象封装当前页、页大小,IPage接收分页结果,自动处理总条数、分页数据 - 多条件查询:支持按分类 ID、标签 ID、发布年份 / 月份筛选文章
- Redis 浏览量补充 :
- 从 Redis 的
view_countHash 结构中获取实时浏览量 - 覆盖 DB 中的旧浏览量数据,保证前端展示的是最新计数
- 从 Redis 的
- VO 扩展转换 :
copyList额外传入isTag、isAuthor参数,自动封装标签、作者信息,减少前端请求