feat(music): 添加音乐点赞功能及前端交互
- 后端新增点赞接口 /music/{id}/like,支持用户登录后点赞/取消点赞音乐,记录点赞数据到 user_like_music 表
- 后端修改 MusicController.getMusicById 接口,支持传入用户ID以判断当前音乐是否被该用户点赞
- 后端 MusicDTO 新增 isLiked 字段,用于前端展示点赞状态
- 数据库新增 user_like_music 表,记录用户与音乐的点赞关系,包含唯一约束防止重复点赞
- 前端 MusicDetail.vue 页面新增点赞按钮及状态展示,支持点击切换点赞状态并实时更新 UI 与点赞数
- 前端新增 toggleLikeMusic API 调用及相应交互逻辑,成功后展示操作提示信息
- 评论表 comment 新增 target_type 字段注释及状态字段注释,播放历史与各关联表新增索引优化与外键约束微调
This commit is contained in:
@@ -116,6 +116,15 @@ export function toggleCollectMusic(id) {
|
||||
return api.post(`/music/${id}/collect`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 点赞/取消点赞音乐
|
||||
* @param {number} id 音乐ID
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
export function toggleLikeMusic(id) {
|
||||
return api.post(`/music/${id}/like`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取收藏的音乐列表
|
||||
* @param {number} page 页码
|
||||
|
||||
@@ -73,6 +73,14 @@
|
||||
{{ music.collected ? '已收藏' : '收藏' }}
|
||||
</el-button>
|
||||
|
||||
<el-button
|
||||
:type="music.liked ? 'success' : 'default'"
|
||||
@click="toggleLike"
|
||||
>
|
||||
<el-icon><component :is="music.liked ? 'Check' : 'Pointer'" /></el-icon>
|
||||
{{ music.liked ? '已点赞' : '点赞' }} ({{ music.likeCount || 0 }})
|
||||
</el-button>
|
||||
|
||||
<el-button
|
||||
@click="addToPlaylist"
|
||||
icon="Plus"
|
||||
@@ -194,7 +202,7 @@ import { ref, computed, onMounted, watch, onUnmounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { usePlayerStore } from '../stores/player'
|
||||
import { useUserStore } from '../stores/user'
|
||||
import { getMusicById, toggleCollectMusic, getHotMusic } from '../api/music'
|
||||
import { getMusicById, toggleCollectMusic, getHotMusic, toggleLikeMusic } from '../api/music'
|
||||
import { getCommentList, addComment, deleteComment as apiDeleteComment } from '../api/comment'
|
||||
import { connect, subscribe, unsubscribe, disconnect } from '../utils/websocket'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
@@ -399,8 +407,9 @@ const toggleCollect = async () => {
|
||||
try {
|
||||
const res = await toggleCollectMusic(music.value.id)
|
||||
if (res.code === 200) {
|
||||
music.value.collected = !music.value.collected
|
||||
ElMessage.success(music.value.collected ? '收藏成功' : '已取消收藏')
|
||||
// 后端直接返回了最新的收藏状态 (true/false),直接赋值即可
|
||||
music.value.collected = res.data
|
||||
ElMessage.success(res.message || (music.value.collected ? '收藏成功' : '已取消收藏'))
|
||||
} else {
|
||||
ElMessage.error(res.message || '操作失败')
|
||||
}
|
||||
@@ -410,6 +419,29 @@ const toggleCollect = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 切换点赞状态
|
||||
const toggleLike = async () => {
|
||||
try {
|
||||
const res = await toggleLikeMusic(music.value.id);
|
||||
if (res.code === 200) {
|
||||
// 后端直接返回了最新的点赞状态 (true/false),直接赋值
|
||||
music.value.liked = res.data;
|
||||
// 更新点赞数
|
||||
if (music.value.liked) {
|
||||
music.value.likeCount = (music.value.likeCount || 0) + 1;
|
||||
} else {
|
||||
music.value.likeCount = Math.max(0, (music.value.likeCount || 0) - 1);
|
||||
}
|
||||
ElMessage.success(res.message || (music.value.liked ? '点赞成功' : '已取消点赞'));
|
||||
} else {
|
||||
ElMessage.error(res.message || '操作失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('点赞操作失败:', error);
|
||||
ElMessage.error('操作失败,请稍后重试');
|
||||
}
|
||||
};
|
||||
|
||||
// 添加到播放列表
|
||||
const addToPlaylist = () => {
|
||||
playerStore.addToPlaylist(music.value)
|
||||
|
||||
Reference in New Issue
Block a user