移动端演示 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 就是分类IDthis.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和文件IDthis.note.firstPicture = coverRes.data; // 封面URLthis.note.videoUrl = videoRes.data; // 视频URLthis.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