function i18n(key) { return lang[selectedLang][key] || key; } // 显示用户中心特定部分 async function showUserCenterSection(section) { try { const userInfo = await fetchUserInfo(); if (!userInfo) { alert(lang[selectedLang].pleaseLogin); window.location.href = 'login.html'; // 重定向到登录页面 return; } // 检查邮箱验证状态 const emailVerified = userInfo.email_verified === 'True' || userInfo.email_verified === true; console.log('Email Verified:', emailVerified); // 打印邮箱验证状态 if (!emailVerified && section !== 'profile') { alert(lang[selectedLang].pleaseVerifyEmail); section = 'profile'; // 如果邮箱未验证,强制显示个人资料页面 // showUserCenterSection('profile'); // 跳转到个人资料页面 return; } const dashboardContent = document.getElementById('dashboardContent'); const usersContent = document.getElementById('usersContent'); const chatContent = document.getElementById('chatContent'); const featureContent = document.getElementById('featureContent'); const userCenterContent = document.getElementById('userCenterContent'); const pageTitle = document.getElementById('pageTitle'); const showApiDocs = document.getElementById('showApiDocs'); const apiDocsContent = document.getElementById('apiDocsContent'); if (apiDocsContent) apiDocsContent.style.display = 'none'; if (dashboardContent) dashboardContent.style.display = 'none'; if (usersContent) usersContent.style.display = 'none'; if (chatContent) chatContent.style.display = 'none'; if (featureContent) featureContent.style.display = 'none'; if (userCenterContent) userCenterContent.style.display = 'block'; if (showApiDocs) showApiDocs.style.display = 'none'; // 根据选择的部分设置相应的标题 if (pageTitle) { switch(section) { case 'profile': pageTitle.innerText = i18n('personalInfo'); break; case 'apiKey': pageTitle.innerText = i18n('apiKeys'); break; case 'apiUsage': pageTitle.innerText = i18n('modelCalls'); break; default: pageTitle.innerText = i18n('userCenter'); } } const navButtons = document.querySelectorAll('.user-center-nav-btn'); const sections = document.querySelectorAll('.user-center-section'); navButtons.forEach(btn => btn.classList.remove('active')); sections.forEach(sec => sec.classList.remove('active')); const targetButton = document.querySelector(`.user-center-nav-btn[data-target="${section}"]`); const targetSection = document.getElementById(`${section}Section`); if (targetButton) targetButton.classList.add('active'); if (targetSection) targetSection.classList.add('active'); if (section === 'profile') { loadUserProfile(); } else if (section === 'apiKey') { loadApiKeys(); } else if (section === 'apiUsage') { loadapiUsage(); } } catch (error) { console.error('Error in showFeature:', error); alert(lang[selectedLang].errorGettingUserInfo); } } // 将 showUserCenterSection 函数添加到全局作用域 window.showUserCenterSection = showUserCenterSection; const BASE_URL = 'https://user.obscura.work/user'; function updateAllAvatars(avatarUrl) { const avatars = document.querySelectorAll('.user-avatar, #currentAvatar'); avatars.forEach(avatar => { avatar.src = avatarUrl || 'picture/cn__03041_.png'; }); } // 加载用户个人资料 async function loadUserProfile() { try { const response = await fetch(`${BASE_URL}/me`, { headers: { 'Authorization': `Bearer ${localStorage.getItem('access_token')}` } }); if (response.ok) { const userData = await response.json(); const profileSection = document.getElementById('profileSection'); updateAllAvatars(userData.avatar) profileSection.innerHTML = `
${i18n("emailVerification")}${userData.email_verified ? i18n("verified") : i18n("unverified")}
${userData.email_verified ? '' : ` `}${i18n("phoneVerification")}${userData.phone_verified ? i18n("verified") : i18n("unverified")}
${userData.phone_verified ? '' : ` `}| ${i18n("apiKeyTable")} | ${i18n("createdAt")} | ${i18n("expiresAt")} | ${i18n("operation")} | |
|---|---|---|---|---|
| ${maskApiKey(actualKey)} | ${new Date(key.created_at).toLocaleString()} | ${new Date(key.expires_at).toLocaleString()} |
${i18n('loadApiKeysFailed')}
`; } } catch (error) { console.error(i18n('loadApiKeysError'), error); const apiKeyContent = document.getElementById('apiKeyContent'); apiKeyContent.innerHTML = `${i18n('loadApiKeysFailed')}
`; } } // 切换 API 密钥可见性 function toggleApiKeyVisibility(index, fullKey) { const keyElement = document.getElementById(`apiKey${index}`); if (keyElement.textContent === fullKey) { keyElement.textContent = maskApiKey(fullKey); } else { keyElement.textContent = fullKey; } } // 复制到剪贴板 function copyToClipboard(text) { navigator.clipboard.writeText(text).then(() => { alert(i18n('apiKeyCopied')); }).catch(err => { console.error(i18n('copyTextFailed'), err); }); } // 生成新的 API 密钥 async function generateNewApiKey() { try { const response = await fetch(`${BASE_URL}/api-keys`, { method: 'POST', headers: { 'Authorization': `Bearer ${localStorage.getItem('access_token')}` } }); if (response.ok) { const newKey = await response.json(); alert(`${i18n('newApiKeyGenerated')}${newKey.api_key}\n${i18n('expirationTime')}${new Date(newKey.expires_at).toLocaleString()}`); loadApiKeys(); // 重新加载 API 密钥列表 } else { const errorData = await response.json(); alert(`${i18n('generateNewApiKeyFailed')}${errorData.detail || i18n('unknownError')}`); } } catch (error) { console.error(i18n('generateNewApiKeyError'), error); alert(i18n('generateNewApiKeyFailed')); } } // 修改 deleteApiKey 函数 async function deleteApiKey(keyId) { const confirmed = confirm(i18n('confirmDeleteApiKey')); if (confirmed) { try { const encodedKeyId = encodeURIComponent(keyId); const response = await fetch(`${BASE_URL}/api-keys/${encodedKeyId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${localStorage.getItem('access_token')}` } }); const data = await response.json(); if (response.ok) { alert(data.message); } else { const errorData = await response.json(); alert(`${i18n('deleteApiKeyFailed')}${errorData.detail || i18n('unknownError')}`); } if (data.action === 'clear_api_info') { await loadApiKeys(); // 重新加载API密钥列表 } } catch (error) { console.error(i18n('deleteApiKeyError'), error); alert(i18n('deleteApiKeyFailed')); } finally { await loadApiKeys(); // 无论成功与否,都重新加载API密钥列表 } } } // 新增清除缓存并重新加载的函数 // 确保 refreshApiKeys 函数被正确定义 async function refreshApiKeys() { try { await fetch(`${BASE_URL}/clear-cache`, { method: 'POST', headers: { 'Authorization': `Bearer ${localStorage.getItem('access_token')}` } }); console.log(i18n('cacheCleared')); } catch (error) { console.error(i18n('clearCacheFailed'), error); } finally { await loadApiKeys(); console.log(i18n('apiKeyListRefreshed')); } } // 加载模型调用信息 async function loadapiUsage() { try { const response = await fetch(`${BASE_URL}/api-usage`, { headers: { 'Authorization': `Bearer ${localStorage.getItem('access_token')}` } }); if (response.ok) { const usageData = await response.json(); const apiUsageContent = document.getElementById('apiUsageContent'); apiUsageContent.innerHTML = `| API KEY | ${i18n("tokensUsed")} | ${i18n("totalTokens")} | ${i18n("lastUsedAt")} | |
|---|---|---|---|---|
| ${i18n("noUsageRecord")} | ||||
| ${maskApiKey(key)} | ${usage.tokens_used || 0} token | ${usage.total_tokens || 0} token | ${usage.last_used_at ? new Date(usage.last_used_at).toLocaleString() : i18n("unused")} | |
加载中...
${i18n('loadModelCallInfoFailed')}
`; } } catch (error) { console.error(i18n('loadModelCallInfoError'), error); const apiUsageContent = document.getElementById('apiUsageContent'); apiUsageContent.innerHTML = `${i18n('loadModelCallInfoFailed')}
`; } } // 显示 API 使用情况 function showApiUsage() { document.getElementById('apiUsageBtn').classList.add('active'); document.getElementById('modelUsageBtn').classList.remove('active'); document.getElementById('apiUsageTable').classList.add('active'); document.getElementById('modelUsageTable').classList.remove('active'); // 添加动画效果 document.getElementById('apiUsageTable').style.animation = 'none'; setTimeout(() => { document.getElementById('apiUsageTable').style.animation = 'fadeIn 0.5s ease-in-out'; }, 10); } // 显示模型使用情况 async function showModelUsage() { document.getElementById('apiUsageBtn').classList.remove('active'); document.getElementById('modelUsageBtn').classList.add('active'); document.getElementById('apiUsageTable').classList.remove('active'); document.getElementById('modelUsageTable').classList.add('active'); // 添加动画效果 document.getElementById('modelUsageTable').style.animation = 'none'; setTimeout(() => { document.getElementById('modelUsageTable').style.animation = 'fadeIn 0.5s ease-in-out'; }, 10); // 加载模型使用情况数据 try { const response = await fetch(`${BASE_URL}/model-usage`, { headers: { 'Authorization': `Bearer ${localStorage.getItem('access_token')}` } }); if (response.ok) { const modelUsageData = await response.json(); const modelUsageTable = document.getElementById('modelUsageTable'); modelUsageTable.innerHTML = `| ${i18n("modelName")} | ${i18n("lastCallTime")} | ${i18n("usage")} |
|---|---|---|
| ${model} | ${usage.last_called_at ? new Date(usage.last_called_at).toLocaleString() : '未使用'} | ${usage.calls} token |
${i18n('loadModelUsageFailed')}
`; } } // 初始化用户中心 function initUserCenter() { const navButtons = document.querySelectorAll('.user-center-nav-btn'); navButtons.forEach(button => { button.addEventListener('click', () => { const target = button.getAttribute('data-target'); showUserCenterSection(target); }); }); // 加载用户信息并更新头像 fetch(`${BASE_URL}/me`, { headers: { 'Authorization': `Bearer ${localStorage.getItem('access_token')}` } }) .then(response => response.json()) .then(userData => { updateAllAvatars(userData.avatar); if (!userData.email_verified) { const sendVerificationEmailBtn = document.getElementById('sendVerificationEmail'); const submitVerificationCodeBtn = document.getElementById('submitVerificationCode'); if (sendVerificationEmailBtn) { sendVerificationEmailBtn.addEventListener('click', sendVerificationEmail); } if (submitVerificationCodeBtn) { submitVerificationCodeBtn.addEventListener('click', submitVerificationCode); } } }) .catch(error => console.error(i18n('getUserInfoFailed'), error)); } // 页面加载完成后初始化用户中心 window.addEventListener('load', initUserCenter); // 将 showUserCenterSection 函数添加到全局作用域 window.showUserCenterSection = showUserCenterSection; window.generateNewApiKey = generateNewApiKey; window.deleteApiKey = deleteApiKey; window.copyToClipboard = copyToClipboard; window.refreshApiKeys = refreshApiKeys; window.loadapiUsage = loadapiUsage; window.showApiUsage = showApiUsage; window.showModelUsage = showModelUsage; window.toggleApiKeyVisibility = toggleApiKeyVisibility; window.openAvatarModal = openAvatarModal; window.selectAvatar = selectAvatar; window.closeAvatarModal = closeAvatarModal; window.showUserCenterSection = showUserCenterSection; window.sendPhoneVerification = sendPhoneVerification; window.submitPhoneVerificationCode = submitPhoneVerificationCode; window.sendVerificationEmail = sendVerificationEmail; window.submitVerificationCode = submitVerificationCode; // 获取用户信息的函数 async function fetchUserInfo() { try { const token = localStorage.getItem('access_token'); if (!token) { console.error(i18n('noAccessTokenFound')); return null; } const response = await fetch(`${BASE_URL}/me`, { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { console.error(i18n('failedToFetchUserInfo')); return null; } const userInfo = await response.json(); return userInfo; } catch (error) { console.error(i18n('errorFetchingUserInfo'), error); // 可以在这里处理错误,比如清除 token 并重定向到登录页面 localStorage.removeItem('access_token'); window.location.href = 'login.html'; // 重定向到登录页面 return null; } }