feat: 添加Cookie登录功能及自动获取等相关管理设置

feat: #413 #424
This commit is contained in:
alger
2025-08-06 22:36:30 +08:00
parent 09ccd9f2a6
commit 16aeaf2948
18 changed files with 1245 additions and 115 deletions
+145
View File
@@ -108,6 +108,34 @@
</div>
</div>
<!-- Token管理 -->
<div class="set-item">
<div>
<div class="set-item-title">{{ t('settings.basic.tokenManagement') }}</div>
<div class="set-item-content">
<div class="text-sm text-gray-500 mb-2">
{{ t('settings.basic.tokenStatus') }}:
{{
currentToken ? t('settings.basic.tokenSet') : t('settings.basic.tokenNotSet')
}}
</div>
<div v-if="currentToken" class="text-xs text-gray-400 mb-2 font-mono break-all">
{{ currentToken.substring(0, 50) }}...
</div>
</div>
</div>
<div class="flex gap-2">
<n-button size="small" @click="showTokenModal = true">
{{
currentToken ? t('settings.basic.modifyToken') : t('settings.basic.setToken')
}}
</n-button>
<n-button v-if="currentToken" size="small" type="error" @click="clearToken">
{{ t('settings.basic.clearToken') }}
</n-button>
</div>
</div>
<div class="set-item">
<div>
<div class="set-item-title">{{ t('settings.basic.animation') }}</div>
@@ -524,6 +552,44 @@
<remote-control-setting v-model:visible="showRemoteControlModal" />
</template>
<!-- Token设置弹窗 -->
<n-modal v-model:show="showTokenModal" preset="dialog" title="Cookie设置">
<template #header>
<div class="flex items-center gap-2">
<i class="ri-key-line"></i>
<span>Cookie设置</span>
</div>
</template>
<div class="space-y-4">
<div>
<div class="text-sm text-gray-600 dark:text-gray-400 mb-2">
请输入网易云音乐的Cookie
</div>
<n-input
v-model:value="tokenInput"
type="textarea"
placeholder="请粘贴完整的Cookie..."
:rows="6"
:autosize="{ minRows: 4, maxRows: 8 }"
style="font-family: monospace; font-size: 12px"
/>
</div>
<div class="text-xs text-gray-500">
<p> Cookie通常以 "MUSIC_U=" 开头</p>
<p> 可以从浏览器开发者工具的网络请求中获取</p>
<p> Cookie设置后将自动保存到本地存储</p>
</div>
</div>
<template #action>
<div class="flex gap-2">
<n-button @click="showTokenModal = false">取消</n-button>
<n-button type="primary" @click="saveToken" :disabled="!tokenInput.trim()">
保存Cookie
</n-button>
</div>
</template>
</n-modal>
<!-- 清除缓存弹窗 -->
<clear-cache-settings v-model:show="showClearCacheModal" @confirm="clearCache" />
</div>
@@ -536,6 +602,7 @@ import { computed, h, nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import localData from '@/../main/set.json';
import { getUserDetail } from '@/api/login';
import Coffee from '@/components/Coffee.vue';
import DonationList from '@/components/common/DonationList.vue';
import PlayBottom from '@/components/common/PlayBottom.vue';
@@ -991,6 +1058,84 @@ const showMusicSourcesModal = ref(false);
// 远程控制设置弹窗
const showRemoteControlModal = ref(false);
// Token管理相关
const showTokenModal = ref(false);
const tokenInput = ref('');
const currentToken = ref(localStorage.getItem('token') || '');
// 保存Token
const saveToken = async () => {
if (!tokenInput.value.trim()) {
message.error('请输入Token');
return;
}
try {
// 临时保存原有token
const originalToken = localStorage.getItem('token');
// 设置新token
localStorage.setItem('token', tokenInput.value.trim());
// 验证token有效性
const user = await getUserDetail();
if (user.data && user.data.profile) {
// token有效,更新用户信息
userStore.setUser(user.data.profile);
currentToken.value = tokenInput.value.trim();
message.success('Token设置成功');
showTokenModal.value = false;
tokenInput.value = '';
// 刷新当前页面
setTimeout(() => {
window.location.reload();
}, 1000);
} else {
// token无效,恢复原有token
if (originalToken) {
localStorage.setItem('token', originalToken);
} else {
localStorage.removeItem('token');
}
message.error('Token无效,请检查后重试');
}
} catch (error) {
// token无效,恢复原有token
const originalToken = localStorage.getItem('token');
if (originalToken) {
localStorage.setItem('token', originalToken);
} else {
localStorage.removeItem('token');
}
message.error('Token无效,请检查后重试');
console.error('Token验证失败:', error);
}
};
// 清除Token
const clearToken = () => {
localStorage.removeItem('token');
localStorage.removeItem('user');
currentToken.value = '';
userStore.user = null;
message.success('Token已清除');
// 刷新页面
setTimeout(() => {
window.location.reload();
}, 1000);
};
// 监听localStorage中token的变化
watch(
() => localStorage.getItem('token'),
(newToken) => {
currentToken.value = newToken || '';
},
{ immediate: true }
);
</script>
<style lang="scss" scoped>