refactor(admin): 重构歌单管理功能提升代码质量
- 移除未使用的 computed 导入语句 - 添加错误处理工具 showErrorOnce 的导入 - 新增 playlistMusics 响应式变量存储歌单音乐数据 - 优化歌单详情加载逻辑,完善异常情况的数据重置 - 在音乐添加和移除操作后同步更新歌单列表数据 - 添加统一的错误处理机制替代原有 console.error - 重构歌单权限校验逻辑,提取为独立的验证方法 - 增强管理员权限支持,允许后台管理员维护用户歌单
This commit is contained in:
@@ -540,14 +540,7 @@ public class PlaylistServiceImpl implements PlaylistService {
|
|||||||
// 获取歌单
|
// 获取歌单
|
||||||
Playlist playlist = playlistRepository.findById(id)
|
Playlist playlist = playlistRepository.findById(id)
|
||||||
.orElseThrow(() -> new BusinessException("歌单不存在"));
|
.orElseThrow(() -> new BusinessException("歌单不存在"));
|
||||||
|
validatePlaylistManagePermission(playlist, "无权修改该歌单");
|
||||||
// 获取当前登录用户
|
|
||||||
Long userId = StpUtil.getLoginIdAsLong();
|
|
||||||
|
|
||||||
// 检查是否是歌单创建者
|
|
||||||
if (!playlist.getCreator().getId().equals(userId)) {
|
|
||||||
throw new BusinessException("无权修改该歌单");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取音乐
|
// 获取音乐
|
||||||
Music music = musicRepository.findById(musicId)
|
Music music = musicRepository.findById(musicId)
|
||||||
@@ -571,14 +564,7 @@ public class PlaylistServiceImpl implements PlaylistService {
|
|||||||
// 获取歌单
|
// 获取歌单
|
||||||
Playlist playlist = playlistRepository.findById(id)
|
Playlist playlist = playlistRepository.findById(id)
|
||||||
.orElseThrow(() -> new BusinessException("歌单不存在"));
|
.orElseThrow(() -> new BusinessException("歌单不存在"));
|
||||||
|
validatePlaylistManagePermission(playlist, "无权修改该歌单");
|
||||||
// 获取当前登录用户
|
|
||||||
Long userId = StpUtil.getLoginIdAsLong();
|
|
||||||
|
|
||||||
// 检查是否是歌单创建者
|
|
||||||
if (!playlist.getCreator().getId().equals(userId)) {
|
|
||||||
throw new BusinessException("无权修改该歌单");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取音乐
|
// 获取音乐
|
||||||
Music music = musicRepository.findById(musicId)
|
Music music = musicRepository.findById(musicId)
|
||||||
@@ -620,6 +606,21 @@ public class PlaylistServiceImpl implements PlaylistService {
|
|||||||
.orElseThrow(() -> new BusinessException("歌单不存在"));
|
.orElseThrow(() -> new BusinessException("歌单不存在"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验当前登录用户是否有权限管理歌单。
|
||||||
|
*
|
||||||
|
* 允许歌单创建者或管理员执行管理操作,避免后台管理员无法维护用户歌单。
|
||||||
|
*
|
||||||
|
* @param playlist 歌单实体
|
||||||
|
* @param errorMessage 无权限时的提示文案
|
||||||
|
*/
|
||||||
|
private void validatePlaylistManagePermission(Playlist playlist, String errorMessage) {
|
||||||
|
Long userId = StpUtil.getLoginIdAsLong();
|
||||||
|
if (!playlist.getCreator().getId().equals(userId) && !StpUtil.hasRole("admin")) {
|
||||||
|
throw new BusinessException(errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将实体转换为DTO
|
* 将实体转换为DTO
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, computed } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { getPlaylistList, getPlaylistById, addPlaylist as apiAddPlaylist, updatePlaylist as apiUpdatePlaylist, deletePlaylist as apiDeletePlaylist } from '../../api/playlist'
|
import { getPlaylistList, getPlaylistById, addPlaylist as apiAddPlaylist, updatePlaylist as apiUpdatePlaylist, deletePlaylist as apiDeletePlaylist } from '../../api/playlist'
|
||||||
import { getPlaylistTypeList } from '../../api/playlistType'
|
import { getPlaylistTypeList } from '../../api/playlistType'
|
||||||
import { processMusicUrl } from '../../api/music'
|
import { processMusicUrl } from '../../api/music'
|
||||||
|
import { showErrorOnce } from '../../utils/errorHandler'
|
||||||
|
|
||||||
// 歌单列表
|
// 歌单列表
|
||||||
const playlistList = ref([])
|
const playlistList = ref([])
|
||||||
@@ -251,6 +252,7 @@ const musicDialogVisible = ref(false)
|
|||||||
const currentPlaylistId = ref(null)
|
const currentPlaylistId = ref(null)
|
||||||
const currentPlaylistName = ref('')
|
const currentPlaylistName = ref('')
|
||||||
const musicList = ref([])
|
const musicList = ref([])
|
||||||
|
const playlistMusics = ref([])
|
||||||
const selectedMusicIds = ref([])
|
const selectedMusicIds = ref([])
|
||||||
const musicSearchKeyword = ref('')
|
const musicSearchKeyword = ref('')
|
||||||
const musicLoading = ref(false)
|
const musicLoading = ref(false)
|
||||||
@@ -278,10 +280,17 @@ const fetchPlaylistMusic = async (playlistId) => {
|
|||||||
try {
|
try {
|
||||||
const res = await getPlaylistById(playlistId)
|
const res = await getPlaylistById(playlistId)
|
||||||
if (res.code === 200 && res.data.musics) {
|
if (res.code === 200 && res.data.musics) {
|
||||||
|
playlistMusics.value = res.data.musics
|
||||||
selectedMusicIds.value = res.data.musics.map(m => m.id)
|
selectedMusicIds.value = res.data.musics.map(m => m.id)
|
||||||
|
} else {
|
||||||
|
playlistMusics.value = []
|
||||||
|
selectedMusicIds.value = []
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取歌单音乐失败:', error)
|
console.error('获取歌单音乐失败:', error)
|
||||||
|
playlistMusics.value = []
|
||||||
|
selectedMusicIds.value = []
|
||||||
|
showErrorOnce(error, '获取歌单音乐失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,6 +299,8 @@ const managePlaylistMusic = async (row) => {
|
|||||||
currentPlaylistId.value = row.id
|
currentPlaylistId.value = row.id
|
||||||
currentPlaylistName.value = row.name
|
currentPlaylistName.value = row.name
|
||||||
musicSearchKeyword.value = ''
|
musicSearchKeyword.value = ''
|
||||||
|
playlistMusics.value = []
|
||||||
|
selectedMusicIds.value = []
|
||||||
musicDialogVisible.value = true
|
musicDialogVisible.value = true
|
||||||
|
|
||||||
// 加载音乐列表和已选音乐
|
// 加载音乐列表和已选音乐
|
||||||
@@ -305,13 +316,16 @@ const addMusicToPlaylistLocal = async (musicId) => {
|
|||||||
const res = await addMusicToPlaylist(currentPlaylistId.value, musicId)
|
const res = await addMusicToPlaylist(currentPlaylistId.value, musicId)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
ElMessage.success('添加成功')
|
ElMessage.success('添加成功')
|
||||||
await fetchPlaylistMusic(currentPlaylistId.value)
|
await Promise.all([
|
||||||
|
fetchPlaylistMusic(currentPlaylistId.value),
|
||||||
|
fetchPlaylistList()
|
||||||
|
])
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error(res.message || '添加失败')
|
ElMessage.error(res.message || '添加失败')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('添加音乐失败:', error)
|
console.error('添加音乐失败:', error)
|
||||||
ElMessage.error('添加失败')
|
showErrorOnce(error, '添加失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,13 +335,16 @@ const removeMusicFromPlaylistLocal = async (musicId) => {
|
|||||||
const res = await removeMusicFromPlaylist(currentPlaylistId.value, musicId)
|
const res = await removeMusicFromPlaylist(currentPlaylistId.value, musicId)
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
ElMessage.success('移除成功')
|
ElMessage.success('移除成功')
|
||||||
await fetchPlaylistMusic(currentPlaylistId.value)
|
await Promise.all([
|
||||||
|
fetchPlaylistMusic(currentPlaylistId.value),
|
||||||
|
fetchPlaylistList()
|
||||||
|
])
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error(res.message || '移除失败')
|
ElMessage.error(res.message || '移除失败')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('移除音乐失败:', error)
|
console.error('移除音乐失败:', error)
|
||||||
ElMessage.error('移除失败')
|
showErrorOnce(error, '移除失败')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -737,7 +754,7 @@ import { addMusicToPlaylist, removeMusicFromPlaylist } from '../../api/playlist'
|
|||||||
<div class="selected-music-container">
|
<div class="selected-music-container">
|
||||||
<h3>已添加的音乐</h3>
|
<h3>已添加的音乐</h3>
|
||||||
<el-table
|
<el-table
|
||||||
:data="musicList.filter(m => selectedMusicIds.includes(m.id))"
|
:data="playlistMusics"
|
||||||
stripe
|
stripe
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
empty-text="暂无音乐"
|
empty-text="暂无音乐"
|
||||||
|
|||||||
Reference in New Issue
Block a user