From af9bc8f21ec1dcb06a082af658d4a3ad323b2c98 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 8 Mar 2026 15:10:09 +0800 Subject: [PATCH] =?UTF-8?q?fix(frontend):=20=E6=94=B6=E6=95=9B=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E9=94=99=E8=AF=AF=E5=BC=B9=E7=AA=97=E5=B9=B6=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E5=8E=BB=E9=87=8D=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- music-qianduan/src/api/index.js | 12 +++++++++++- music-qianduan/src/utils/errorHandler.js | 16 ++++++++++++++++ music-qianduan/src/views/MusicDetail.vue | 9 +++++---- music-qianduan/src/views/Playlist.vue | 3 ++- music-qianduan/src/views/PlaylistDetail.vue | 13 +++++++------ music-qianduan/src/views/Search.vue | 7 ++++--- music-qianduan/src/views/Singer.vue | 3 ++- music-qianduan/src/views/SingerDetail.vue | 7 ++++--- 8 files changed, 51 insertions(+), 19 deletions(-) create mode 100644 music-qianduan/src/utils/errorHandler.js diff --git a/music-qianduan/src/api/index.js b/music-qianduan/src/api/index.js index 1a6268f..52438c8 100644 --- a/music-qianduan/src/api/index.js +++ b/music-qianduan/src/api/index.js @@ -89,7 +89,12 @@ api.interceptors.response.use( // 其他错误 ElMessage.error(res.message || '未知错误') } - return Promise.reject(new Error(res.message || '未知错误')) + const businessError = new Error(res.message || '未知错误') + businessError.code = res.code + businessError.message = res.message || '未知错误' + // 标记为已提示,避免页面 catch 再次弹窗 + businessError.__handled = true + return Promise.reject(businessError) } else { return res } @@ -111,11 +116,16 @@ api.interceptors.response.use( // 处理网络错误 if (error.message && error.message.includes('timeout')) { ElMessage.error('请求超时,请稍后再试') + error.message = '请求超时,请稍后再试' } else if (error.message && error.message.includes('Network Error')) { ElMessage.error('网络错误,请检查网络连接') + error.message = '网络错误,请检查网络连接' } else { ElMessage.error(error.message || '未知错误') + error.message = error.message || '未知错误' } + // 标记为已提示,避免页面 catch 再次弹窗 + error.__handled = true return Promise.reject(error) } ) diff --git a/music-qianduan/src/utils/errorHandler.js b/music-qianduan/src/utils/errorHandler.js new file mode 100644 index 0000000..b28ef83 --- /dev/null +++ b/music-qianduan/src/utils/errorHandler.js @@ -0,0 +1,16 @@ +import { ElMessage } from 'element-plus' + +/** + * 统一错误提示入口,避免拦截器和页面重复弹窗 + * @param {Error|Object|string} error 错误对象 + * @param {string} fallbackMsg 兜底提示文案 + */ +export const showErrorOnce = (error, fallbackMsg = '操作失败,请稍后重试') => { + // 已在请求拦截器中提示过,则直接跳过 + if (error && error.__handled) { + return + } + + const message = error?.message || fallbackMsg + ElMessage.error(message) +} diff --git a/music-qianduan/src/views/MusicDetail.vue b/music-qianduan/src/views/MusicDetail.vue index 7791185..17c2935 100644 --- a/music-qianduan/src/views/MusicDetail.vue +++ b/music-qianduan/src/views/MusicDetail.vue @@ -263,6 +263,7 @@ import { connect, subscribe, unsubscribe, disconnect } from '../utils/websocket' import { ElMessage, ElMessageBox } from 'element-plus' import { VideoPlay, VideoPause, Star, StarFilled, Plus } from '@element-plus/icons-vue' import { processImageUrl } from '../utils/imageUtils' +import { showErrorOnce } from '../utils/errorHandler' const route = useRoute() const router = useRouter() @@ -425,7 +426,7 @@ const submitComment = async (isReply = false) => { } } catch (error) { console.error('提交评论失败:', error); - ElMessage.error('评论失败,请稍后重试'); + showErrorOnce(error, '评论失败,请稍后重试'); } }; @@ -449,7 +450,7 @@ const deleteComment = async (commentId) => { } catch (error) { if (error !== 'cancel') { console.error('删除评论失败:', error); - ElMessage.error('删除失败,请稍后重试'); + showErrorOnce(error, '删除失败,请稍后重试'); } } }; @@ -560,7 +561,7 @@ const toggleCollect = async () => { } } catch (error) { console.error('收藏操作失败:', error) - ElMessage.error('操作失败,请稍后重试') + showErrorOnce(error, '操作失败,请稍后重试') } } @@ -583,7 +584,7 @@ const toggleLike = async () => { } } catch (error) { console.error('点赞操作失败:', error); - ElMessage.error('操作失败,请稍后重试'); + showErrorOnce(error, '操作失败,请稍后重试'); } }; diff --git a/music-qianduan/src/views/Playlist.vue b/music-qianduan/src/views/Playlist.vue index a272de9..aaac174 100644 --- a/music-qianduan/src/views/Playlist.vue +++ b/music-qianduan/src/views/Playlist.vue @@ -3,6 +3,7 @@ import { ref, onMounted } from 'vue' import { useRouter } from 'vue-router' import { useUserStore } from '../stores/user' import { ElMessage } from 'element-plus' +import { showErrorOnce } from '../utils/errorHandler' import { Search, Headset } from '@element-plus/icons-vue' import { getPlaylistList, getHotPlaylist, toggleCollectPlaylist, isPlaylistCollected, uncollectPlaylist, collectPlaylist } from '../api/playlist' import { getPlaylistTypeList } from '../api/playlistType' @@ -170,7 +171,7 @@ const toggleCollect = async (playlist) => { } } catch (error) { console.error('收藏操作失败:', error) - ElMessage.error('操作失败,请稍后重试') + showErrorOnce(error, '操作失败,请稍后重试') } } diff --git a/music-qianduan/src/views/PlaylistDetail.vue b/music-qianduan/src/views/PlaylistDetail.vue index 4ed2157..8070bb9 100644 --- a/music-qianduan/src/views/PlaylistDetail.vue +++ b/music-qianduan/src/views/PlaylistDetail.vue @@ -9,6 +9,7 @@ import { getMusicStatus } from '../api/music' import { getCommentList, addComment, deleteComment as apiDeleteComment } from '../api/comment' import { connect, subscribe, unsubscribe, disconnect } from '../utils/websocket' // 导入 WebSocket 工具 import { processImageUrl } from '../utils/imageUtils' +import { showErrorOnce } from '../utils/errorHandler' import MusicList from '../components/MusicList.vue' const route = useRoute() @@ -201,7 +202,7 @@ const toggleCollect = async () => { } } catch (error) { console.error('收藏操作失败:', error) - ElMessage.error('操作失败,请稍后重试') + showErrorOnce(error, '操作失败,请稍后重试') } } @@ -226,7 +227,7 @@ const deleteComment = async (commentId) => { } catch (error) { if (error !== 'cancel') { console.error('删除评论失败:', error) - ElMessage.error('删除失败,请稍后重试') + showErrorOnce(error, '删除失败,请稍后重试') } } } @@ -319,7 +320,7 @@ const submitComment = async (isReply = false) => { } } catch (error) { console.error('提交评论失败:', error) - ElMessage.error('评论失败,请稍后重试') + showErrorOnce(error, '评论失败,请稍后重试') } } @@ -364,7 +365,7 @@ const submitEdit = async () => { } } catch (error) { console.error('更新歌单失败:', error) - ElMessage.error('更新失败,请稍后重试') + showErrorOnce(error, '更新失败,请稍后重试') } } @@ -390,7 +391,7 @@ const deletePlaylist = () => { } } catch (error) { console.error('删除歌单失败:', error) - ElMessage.error('删除失败,请稍后重试') + showErrorOnce(error, '删除失败,请稍后重试') } }).catch(() => {}) } @@ -510,7 +511,7 @@ const deleteFromPlaylist = async (music) => { } catch (error) { if (error !== 'cancel') { console.error('移除歌曲失败:', error) - ElMessage.error('移除失败,请稍后重试') + showErrorOnce(error, '移除失败,请稍后重试') } } } diff --git a/music-qianduan/src/views/Search.vue b/music-qianduan/src/views/Search.vue index befd6bc..f2b606b 100644 --- a/music-qianduan/src/views/Search.vue +++ b/music-qianduan/src/views/Search.vue @@ -152,6 +152,7 @@ import { ref, computed, onMounted, watch } from 'vue' import { useRoute, useRouter } from 'vue-router' import { useUserStore } from '../stores/user' import { ElMessage } from 'element-plus' +import { showErrorOnce } from '../utils/errorHandler' import { Search } from '@element-plus/icons-vue' import { searchMusic, toggleCollectMusic, getMusicStatus } from '../api/music' import { searchPlaylist, toggleCollectPlaylist } from '../api/playlist' @@ -362,7 +363,7 @@ const handleCollectChange = async (id) => { } } catch (error) { console.error('收藏操作失败:', error) - ElMessage.error('操作失败,请稍后重试') + showErrorOnce(error, '操作失败,请稍后重试') } } @@ -387,7 +388,7 @@ const handleCollectPlaylist = async (id) => { } } catch (error) { console.error('收藏操作失败:', error) - ElMessage.error('操作失败,请稍后重试') + showErrorOnce(error, '操作失败,请稍后重试') } } @@ -414,7 +415,7 @@ const handleCollectSinger = async (id, event) => { } } catch (error) { console.error('收藏操作失败:', error) - ElMessage.error('操作失败,请稍后重试') + showErrorOnce(error, '操作失败,请稍后重试') } } diff --git a/music-qianduan/src/views/Singer.vue b/music-qianduan/src/views/Singer.vue index fbe951a..2907736 100644 --- a/music-qianduan/src/views/Singer.vue +++ b/music-qianduan/src/views/Singer.vue @@ -3,6 +3,7 @@ import { ref, onMounted } from 'vue' import { useRouter } from 'vue-router' import { useUserStore } from '../stores/user' import { ElMessage } from 'element-plus' +import { showErrorOnce } from '../utils/errorHandler' import { Search } from '@element-plus/icons-vue' import { getSingerList, getHotSinger, isSingerCollected, collectSinger, uncollectSinger } from '../api/singer' import { getSingerTypeList } from '../api/singerType' @@ -170,7 +171,7 @@ const toggleCollect = async (singer, event) => { } } catch (error) { console.error('收藏操作失败:', error) - ElMessage.error('操作失败,请稍后重试') + showErrorOnce(error, '操作失败,请稍后重试') } } diff --git a/music-qianduan/src/views/SingerDetail.vue b/music-qianduan/src/views/SingerDetail.vue index 3a7c4e5..8a17f7e 100644 --- a/music-qianduan/src/views/SingerDetail.vue +++ b/music-qianduan/src/views/SingerDetail.vue @@ -7,6 +7,7 @@ import { ElMessage, ElMessageBox } from 'element-plus' import { getSingerById, isSingerCollected, collectSinger, uncollectSinger } from '../api/singer' import { getCommentList, addComment, deleteComment as apiDeleteComment } from '../api/comment' import { processImageUrl } from '../utils/imageUtils' +import { showErrorOnce } from '../utils/errorHandler' import { processMusicUrl, getMusicBySinger, getMusicStatus } from '../api/music' import { connect, subscribe, unsubscribe, disconnect } from '../utils/websocket' // 导入 WebSocket 工具 import MusicList from '../components/MusicList.vue' @@ -219,7 +220,7 @@ const toggleCollect = async () => { } } catch (error) { console.error('收藏操作失败:', error) - ElMessage.error('操作失败,请稍后重试') + showErrorOnce(error, '操作失败,请稍后重试') } } @@ -311,7 +312,7 @@ const submitComment = async (isReply = false) => { } } catch (error) { console.error('提交评论失败:', error) - ElMessage.error('评论失败,请稍后重试') + showErrorOnce(error, '评论失败,请稍后重试') } } @@ -336,7 +337,7 @@ const deleteComment = async (commentId) => { } catch (error) { if (error !== 'cancel') { console.error('删除评论失败:', error) - ElMessage.error('删除失败,请稍后重试') + showErrorOnce(error, '删除失败,请稍后重试') } } }