feat: 优化登录失效

This commit is contained in:
alger
2025-01-06 22:03:50 +08:00
parent 020aca7384
commit 9eb17fd978
8 changed files with 118 additions and 66 deletions

View File

@@ -14,5 +14,6 @@ declare global {
restart: () => void;
unblockMusic: (id: number, data: any) => Promise<any>;
};
$message:any
}
}

View File

@@ -32,10 +32,6 @@ onMounted(() => {
'setMenus',
homeRouter.filter((item) => item.meta.isMobile)
);
console.log(
'qqq ',
homeRouter.filter((item) => item.meta.isMobile)
);
}
});
</script>

View File

@@ -70,7 +70,7 @@ const store = useStore()
// 添加计算属性
const showUpdateModalState = computed({
get: () => store.state.showUpdateModal,
set: (val) => store.commit('SET_SHOW_UPDATE_MODAL', val)
set: (val) => store.commit('setShowUpdateModal', val)
})
// 替换原来的 watch

View File

@@ -199,8 +199,7 @@ const selectItem = async (key: string) => {
switch (key) {
case 'logout':
logout().then(() => {
store.state.user = null;
localStorage.clear();
store.commit('logout');
router.push('/login');
});
break;
@@ -241,7 +240,7 @@ const checkForUpdates = async () => {
const toGithubRelease = () => {
if (updateInfo.value.hasUpdate) {
store.commit('SET_SHOW_UPDATE_MODAL', true)
store.commit('setShowUpdateModal', true)
} else {
window.open('https://github.com/algerkong/AlgerMusicPlayer/releases', '_blank');
}

View File

@@ -126,8 +126,13 @@ const mutations = {
state.theme = state.theme === 'dark' ? 'light' : 'dark';
applyTheme(state.theme);
},
SET_SHOW_UPDATE_MODAL(state, value) {
setShowUpdateModal(state, value) {
state.showUpdateModal = value
},
logout(state: State) {
state.user = null;
localStorage.removeItem('user');
localStorage.removeItem('token');
}
};
@@ -153,18 +158,20 @@ const actions = {
},
async initializeFavoriteList({ state }: { state: State }) {
try {
const res = await getLikedList();
if (res.data?.ids) {
state.favoriteList = res.data.ids.reverse();
localStorage.setItem('favoriteList', JSON.stringify(state.favoriteList));
if(state.user && localStorage.getItem('token')){
const res = await getLikedList();
if (res.data?.ids) {
state.favoriteList = res.data.ids.reverse();
localStorage.setItem('favoriteList', JSON.stringify(state.favoriteList));
}
}else{
const localFavoriteList = localStorage.getItem('favoriteList');
if (localFavoriteList) {
state.favoriteList = JSON.parse(localFavoriteList);
}
}
} catch (error) {
console.error('获取收藏列表失败:', error);
// 如果获取失败,使用本地存储的数据
const localFavoriteList = localStorage.getItem('favoriteList');
if (localFavoriteList) {
state.favoriteList = JSON.parse(localFavoriteList);
}
}
}
};

View File

@@ -1,8 +1,14 @@
import axios, { InternalAxiosRequestConfig } from 'axios';
import { isElectron } from '.';
import store from '@/store';
import { createDiscreteApi } from 'naive-ui'
const { notification } = createDiscreteApi(
['notification']
)
let setData: any = null;
const getSetData = ()=>{
if (window.electron) {
setData = window.electron.ipcRenderer.sendSync('get-store-value', 'set');
@@ -74,6 +80,7 @@ request.interceptors.response.use(
return response;
},
async (error) => {
console.log('error',error)
const config = error.config as CustomAxiosRequestConfig;
// 如果没有配置,直接返回错误
@@ -81,6 +88,30 @@ request.interceptors.response.use(
return Promise.reject(error);
}
// 处理 301 状态码
if (error.response?.status === 301) {
// 使用 store mutation 清除用户信息
store.commit('logout');
// 如果还可以重试,则重新发起请求
if (config.retryCount === undefined || config.retryCount < MAX_RETRIES) {
config.retryCount = (config.retryCount || 1) + 1;
console.log(`301 状态码,清除登录信息后重试第 ${config.retryCount}`);
notification.error({
content: '登录状态失效,请重新登录',
meta: '请重新登录',
duration: 2500,
keepAliveOnHover: true
})
// 延迟重试
await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY));
// 重新发起请求
return request(config);
}
}
// 检查是否还可以重试
if (config.retryCount !== undefined && config.retryCount < MAX_RETRIES) {
config.retryCount++;

View File

@@ -112,6 +112,27 @@
<n-button size="small" type="primary" @click="openAuthor"><i class="ri-github-line"></i>前往github</n-button>
</div>
</div>
<div class="set-item">
<div>
<div class="set-item-title">音质设置</div>
<div class="set-item-content">选择音乐播放音质VIP</div>
</div>
<n-select
v-model:value="setData.musicQuality"
:options="[
{ label: '标准', value: 'standard' },
{ label: '较高', value: 'higher' },
{ label: '极高', value: 'exhigh' },
{ label: '无损', value: 'lossless' },
{ label: 'Hi-Res', value: 'hires' },
{ label: '高清环绕声', value: 'jyeffect' },
{ label: '沉浸环绕声', value: 'sky' },
{ label: '杜比全景声', value: 'dolby' },
{ label: '超清母带', value: 'jymaster' }
]"
style="width: 160px"
/>
</div>
<div class="set-item" v-if="isElectron">
<div>
<div class="set-item-title">关闭行为</div>
@@ -129,6 +150,7 @@
style="width: 160px"
/>
</div>
<div class="set-item" v-if="isElectron">
<div>
<div class="set-item-title">重启</div>
@@ -168,27 +190,7 @@
/>
</div>
</div>
<div class="set-item">
<div>
<div class="set-item-title">音质设置</div>
<div class="set-item-content">选择音乐播放音质VIP</div>
</div>
<n-select
v-model:value="setData.musicQuality"
:options="[
{ label: '标准', value: 'standard' },
{ label: '较高', value: 'higher' },
{ label: '极高', value: 'exhigh' },
{ label: '无损', value: 'lossless' },
{ label: 'Hi-Res', value: 'hires' },
{ label: '高清环绕声', value: 'jyeffect' },
{ label: '沉浸环绕声', value: 'sky' },
{ label: '杜比全景声', value: 'dolby' },
{ label: '超清母带', value: 'jymaster' }
]"
style="width: 160px"
/>
</div>
</div>
<PlayBottom/>
<n-modal
@@ -315,7 +317,7 @@ const checkForUpdates = async (isClick = false) => {
};
const openReleasePage = () => {
store.commit('SET_SHOW_UPDATE_MODAL', true)
store.commit('setShowUpdateModal', true)
};
const selectDownloadPath = async () => {

View File

@@ -89,7 +89,7 @@
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { computed, ref, watch, onBeforeUnmount } from 'vue';
import { useRouter } from 'vue-router';
import { useStore } from 'vuex';
@@ -112,42 +112,58 @@ const userDetail = ref<IUserDetail>();
const playList = ref<any[]>([]);
const recordList = ref();
const infoLoading = ref(false);
const mounted = ref(true);
const isShowList = ref(false);
const list = ref<Playlist>();
const listLoading = ref(false);
const user = computed(() => store.state.user);
onBeforeUnmount(() => {
mounted.value = false;
});
const loadPage = async () => {
if (!user.value) {
router.push('/login');
return;
if (!mounted.value || !user.value) return;
try {
infoLoading.value = true;
const { data: userData } = await getUserDetail(user.value.userId);
if (!mounted.value) return;
userDetail.value = userData;
const { data: playlistData } = await getUserPlaylist(user.value.userId);
if (!mounted.value) return;
playList.value = playlistData.playlist;
const { data: recordData } = await getUserRecord(user.value.userId);
if (!mounted.value) return;
recordList.value = recordData.allData.map((item: any) => ({
...item,
...item.song,
picUrl: item.song.al.picUrl
}));
} catch (error) {
console.error('加载用户页面失败:', error);
} finally {
if (mounted.value) {
infoLoading.value = false;
}
}
infoLoading.value = true;
const { data: userData } = await getUserDetail(user.value.userId);
userDetail.value = userData;
const { data: playlistData } = await getUserPlaylist(user.value.userId);
playList.value = playlistData.playlist;
const { data: recordData } = await getUserRecord(user.value.userId);
recordList.value = recordData.allData.map((item: any) => ({
...item,
...item.song,
picUrl: item.song.al.picUrl
}));
infoLoading.value = false;
};
onActivated(() => {
if (!user.value) {
// 监听用户状态变化
watch(() => store.state.user, (newUser) => {
if (!mounted.value) return;
if (!newUser) {
router.push('/login');
} else {
loadPage();
}
});
}, { immediate: true });
const isShowList = ref(false);
const list = ref<Playlist>();
const listLoading = ref(false);
// 展示歌单
const showPlaylist = async (id: number, name: string) => {
isShowList.value = true;