从零用java实现 小红书 springboot vue uniapp (12)实现分类筛选与视频笔记功能

发布于:2025-07-04 ⋅ 阅读:(16) ⋅ 点赞:(0)

移动端演示 http://8.146.211.120:8081/#/

管理端演示 http://8.146.211.120:8088/#/

项目整体介绍及演示

前言

在前面的系列文章中,我们已经基本完成了小红书项目的核心框架搭建和图文笔记的发布、展示流程。为了丰富App的功能和用户体验,今天我们将在此基础上进行两大核心升级:一、为笔记增加分类,并在首页实现筛选功能;二、支持用户发布视频笔记。


一、首页分类筛选

首先,我们参考主流内容App的设计,在首页的“发现”模块顶部增加一个分类导航栏,让用户可以快速筛选自己感兴趣的内容。

最终效果如下:

在这里插入图片描述

1. 后端实现

要实现分类,必须先有分类的存储。我们需要创建一张 business_category 表来管理所有分类。

CREATE TABLE `business_category` (
  `CATEGORY_ID` varchar(32) NOT NULL COMMENT '分类id',
  `CATEGORY_NAME` varchar(255) DEFAULT NULL COMMENT '分类名称',
  `SORT` int(11) DEFAULT '0' COMMENT '排序',
  `DELETED` tinyint(2) DEFAULT '0' COMMENT '0正常 1删除',
  `CREATE_TIME` datetime DEFAULT NULL,
  `UPDATE_TIME` datetime DEFAULT NULL,
  PRIMARY KEY (`CATEGORY_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='笔记分类表';

我们增加了 SORT 字段,方便后台进行排序管理。

接着,在后端的 NoteController.java 中,我们对查询笔记的接口进行改造,使其支持按 noteCategory 参数进行过滤。

// Mybatis-Plus Wrapper
QueryWrapper<Note> queryWrapper = new QueryWrapper<>();
// ...其他查询条件
// 如果分类ID不为空,则增加分类筛选条件
if (StringUtils.isNotBlank(noteCategory)) {
    queryWrapper.eq("NOTE_CATEGORY", noteCategory);
}
// ...执行查询

同时,提供一个 /api/getCategories 接口,用于让App端获取所有已排序的分类列表。

2. 前端实现

后台管理:
我们在后台管理系统中,创建了对应的分类管理页面,实现了对笔记分类的增、删、改、查以及拖拽排序功能。
在这里插入图片描述

App端 (index.vue):
在首页 onLoad 时,调用接口获取分类数据。
在这里插入图片描述

onLoad() {
    this.getCategories();
    // ...
},
methods:{
    getCategories() {
        uni.app.get('/getCategories', {}, (res) => {
            if (res.code === 200) {
                // 将后台返回的分类列表处理成导航组件需要的数据格式
                const categories = res.data.map(item => ({
                    id: item.categoryId,
                    name: item.categoryName
                }));
                // 在最前面加上“推荐”
                this.navItems = [{ id: '', name: '推荐' }, ...categories];
            }
        });
    },
    // ...
}

然后使用 gui-switch-navigation-shopping 组件来渲染这个可横向滚动的导航栏。当用户点击不同分类时,触发 @change 事件,调用查询笔记的接口并传入当前分类的ID。

<gui-switch-navigation-shopping 
    :data="navItems" 
    :currentIndex="navCurrentIndex"
    @change="navchange">
</gui-switch-navigation-shopping>

// methods
navchange: function(index) {
    this.navCurrentIndex = index;
    // this.navItems[index].id 就是分类ID
    this.noteCategory = this.navItems[index].id;
    // 清空现有列表,重新加载数据
    this.notes = [];
    this.page = 1;
    this.getNotes(); 
}

至此,首页的分类筛选功能就完成了。


二、支持视频笔记

图文内容已经无法满足所有创作场景,接下来我们为项目增加发布视频笔记的功能。

创建页效果:
在这里插入图片描述

1. 数据库与后端修改

首先,我们需要在笔记表 business_note 中增加一个字段来存储视频的地址。

ALTER TABLE `business_note` 
ADD COLUMN `VIDEO_URL` varchar(500) NULL COMMENT '视频地址' AFTER `FIRST_PICTURE`;

然后在对应的实体类 Note.java, NoteDto.java, NoteVo.java 中都加上 videoUrl 属性。

最后,修改发布笔记的接口 addNote,使其能够接收并保存 videoUrl 字段。

2. 前端实现 (create.vue)

我们对发布页 create.vue 进行了改造。

笔记类型选择:
将原来的Tab切换改为了点击后从底部弹出的ActionSheet,交互更友好。

文件上传:
当用户选择发布“视频笔记”时,界面会展示两个上传入口:一个用于上传视频,一个用于上传封面。

<!-- v-if="note.noteType === 2" -->
<view>
    <view class="gui-h6">上传视频</view>
    <!-- 视频上传组件 -->
    ...
</view>
<view style="margin-top:20rpx;">
    <view class="gui-h6">上传封面</view>
    <!-- 封面上传组件 -->
    ...
</view>

提交逻辑:
submit 方法中,我们对视频笔记的提交流程进行了重构。使用 Promise.all 来并发上传视频文件和封面图片,可以有效提升上传效率。

async submit() {
    // ...表单校验...
    
    uni.showLoading({ title: '发布中...' });

    if (this.note.noteType === 2) { // 视频笔记
        if (!this.videoTempPath || !this.coverTempPath) {
            // ...提示用户选择文件...
            return;
        }
        
        try {
            // 并发上传封面和视频
            const [coverRes, videoRes] = await Promise.all([
                this.uploadFile(this.coverTempPath, 'avatar'),
                this.uploadFile(this.videoTempPath, 'video')
            ]);
            
            // 从返回结果中获取完整URL和文件ID
            this.note.firstPicture = coverRes.data; // 封面URL
            this.note.videoUrl = videoRes.data;     // 视频URL
            this.note.imgs = [coverRes.result.fileId]; // 封面ID
            
            // 调用接口,将数据提交到后端
            this.postNoteData();

        } catch (error) {
            uni.hideLoading();
            uni.showToast({ title: `上传失败: ${error}`, icon: "none" });
        }

    } else { // 图文笔记
        // ...执行原来的图文上传逻辑...
    }
}

通过以上改造,我们就完整地实现了视频笔记的发布功能。在首页信息流和笔记详情页,只需要将 note.videoUrl 绑定到 <video> 组件的 src 属性上即可播放。
在这里插入图片描述


后面我们计划实现商城功能,敬请期待。

代码地址
https://gitee.com/ddeatrr/springboot_vue_xhs