实战--11

一、分类模块(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));
}

核心亮点拆解

  1. MyBatis-Plus 分页 :Page对象封装当前页、页大小,IPage接收分页结果,自动处理总条数、分页数据
  2. 多条件查询:支持按分类 ID、标签 ID、发布年份 / 月份筛选文章
  3. Redis 浏览量补充 :
    • 从 Redis 的view_count Hash 结构中获取实时浏览量
    • 覆盖 DB 中的旧浏览量数据,保证前端展示的是最新计数
  4. VO 扩展转换 :copyList额外传入isTag、isAuthor参数,自动封装标签、作者信息,减少前端请求
相关推荐
上火的金鱼妹18 小时前
关于多进程sse连接通知的实战
javascript·状态模式·sse
阿俊-全栈开发19 小时前
LikeShop 小程序商城首页可配置弹窗的设计与实现(Java + uni-app)
小程序·状态模式·likeshop·likeshop开源商城
lingyubb1 天前
配音工具怎么选?从 TTS 合成链路看 6 个可量化参数
状态模式
平头哥技术团队3 天前
从预订问到退房:一间山野民宿的数字人「旅程地图」——Theme07_Homestay.vue 端到端拆解
状态模式·数字人
未来之窗软件服务4 天前
web网络请求竞态问题与取消方案-东方仙盟
前端·状态模式·仙盟创梦ide·东方仙盟·网络取消
一级新生5 天前
多智能体协作:常用协作模式详解
人工智能·状态模式·agent·多智能体·智能体
喜欢打篮球的普通人7 天前
LLVM 前端与优化层:Clang 如何把 C 代码变成 IR
c语言·前端·状态模式
m0_敲代码的彭于晏1687 天前
Vercel 前端部署与全栈开发实战指南
前端·状态模式
星恒随风8 天前
Linux线程同步与互斥(二):从日志系统与线程池设计,到线程安全单例、可重入函数和死锁原理
linux·运维·状态模式
学Linux的语莫9 天前
python中类的常见写法
开发语言·python·状态模式