Files
phaten-audio/zh/docs/common/checklogin_form.md
2025-08-06 14:42:54 +08:00

29 KiB
Raw Blame History

<style> .login-modal { display: none !important; position: fixed !important; z-index: 100 !important; left: 0 !important; top: 0 !important; width: 100% !important; height: 100% !important; background-color: rgba(0,0,0,0.5) !important; } .login-modal[style*="block"] { display: block !important; } .login-content { background-color: #fefefe; margin: 10% auto; padding: 20px; border: 1px solid #888; width: 400px; border-radius: 15px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); } .login-content h2 { text-align: center; margin-bottom: 15px; color: #333; font-size: 22px; } /* Tab 样式 */ .tab-container { display: flex; margin-bottom: 20px; border-bottom: 1px solid #ddd; } .tab-button { flex: 1; padding: 12px; background: none; border: none; cursor: pointer; font-size: 16px; transition: all 0.3s ease; border-bottom: 2px solid transparent; } .tab-button.active { color: #3498db; border-bottom-color: #3498db; font-weight: bold; } .tab-button:hover { color: #3498db; background-color: #f8f9fa; } .tab-content { display: none; } .tab-content.active { display: block; } .login-form input { width: 100%; padding: 10px; margin: 10px 0; border: 1px solid #ddd; border-radius: 8px; box-sizing: border-box; font-size: 15px; } .login-form .code-container { display: flex; gap: 10px; margin: 10px 0; } .login-form .hint-text { font-size: 12px; color: #666; margin-top: 3px; margin-bottom: 3px; text-align: left; } .login-form .code-input { flex: 3; padding: 10px; border: 1px solid #ddd; border-radius: 8px; box-sizing: border-box; font-size: 15px; } .login-form .send-code-btn { flex: 1; min-width: 95px; padding: 0 8px; background-color: #3498db; color: white; border: none; border-radius: 8px; cursor: pointer; font-size: 14px; transition: background-color 0.3s ease; white-space: nowrap; } .login-form .send-code-btn:hover { background-color: #2980b9; } .login-form .send-code-btn:disabled { background-color: #95a5a6; cursor: not-allowed; } .login-form button[type="submit"] { width: 100%; padding: 10px; background-color: #3498db; color: white; border: none; border-radius: 8px; cursor: pointer; margin-top: 12px; font-size: 16px; transition: background-color 0.3s ease; } .login-form button[type="submit"]:hover { background-color: #2980b9; } /* 忘记密码链接样式 */ .forgot-password-link { display: block; text-align: center; margin-top: 15px; color: #3498db; text-decoration: none; font-size: 14px; transition: color 0.3s ease; } .forgot-password-link:hover { color: #2980b9; text-decoration: underline; } .close { float: right; cursor: pointer; font-size: 24px; color: #666; transition: color 0.3s ease; } .close:hover { color: #333; } /* 消息弹出框样式 */ .message-modal { display: none; position: fixed; z-index: 1001; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); } .message-content { background-color: #fefefe; margin: 15% auto; padding: 20px; border: 1px solid #888; width: 400px; border-radius: 15px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); text-align: center; } .message-content h3 { margin: 0 0 15px 0; color: #333; font-size: 18px; } .message-content p { margin: 15px 0; color: #666; line-height: 1.5; white-space: pre-line; } .message-content .success { color: #27ae60; } .message-content .error { color: #e74c3c; } .message-btn { background-color: #3498db; color: white; border: none; border-radius: 8px; padding: 10px 20px; cursor: pointer; font-size: 14px; margin-top: 10px; transition: background-color 0.3s ease; } .message-btn:hover { background-color: #2980b9; } .close-message { float: right; cursor: pointer; font-size: 24px; color: #666; transition: color 0.3s ease; } .close-message:hover { color: #333; } /* 下载按钮样式 */ .download-btn { font-size: 12px !important; padding: 6px 12px !important; min-height: auto !important; line-height: 1.2 !important; } .download-btn.loading { pointer-events: none; opacity: 0.7; position: relative; } .download-btn.loading::after { content: ""; position: absolute; width: 12px; height: 12px; top: 50%; left: 50%; margin-left: -6px; margin-top: -6px; border: 2px solid #ffffff; border-radius: 50%; border-top-color: transparent; animation: button-loading-spinner 1s ease infinite; } @keyframes button-loading-spinner { from { transform: rotate(0turn); } to { transform: rotate(1turn); } } </style>
×

提示

确定
×

飞腾云登录/注册

    <!-- Tab 切换按钮 -->
    <div class="tab-container">
        <button class="tab-button active" onclick="switchTab('login')">登录</button>
        <button class="tab-button" onclick="switchTab('register')">注册</button>
    </div>
    
    <!-- 登录表单 -->
    <div id="loginTab" class="tab-content active">
        <form id="loginForm" class="login-form">
            <input type="email" id="loginEmail" placeholder="请输入邮箱" required>
            <input type="password" id="loginPassword" placeholder="请输入密码" required>
            <button type="submit">登录</button>
            <a href="javascript:void(0)" class="forgot-password-link" onclick="switchTab('reset')">忘记密码?</a>
        </form>
    </div>
    
    <!-- 注册表单 -->
    <div id="registerTab" class="tab-content">
        <form id="registerForm" class="login-form">
            <input type="email" id="registerEmail" placeholder="请输入邮箱" required>
            <div class="code-container">
                <input type="text" id="verificationCode" class="code-input" placeholder="请输入验证码" required>
                <button type="button" id="sendCodeBtn" class="send-code-btn">发送验证码</button>
            </div>
            <input type="password" id="registerPassword" placeholder="请输入密码" required>
            <input type="password" id="confirmPassword" placeholder="请确认密码" required>
            <button type="submit">注册</button>
        </form>
    </div>
    
    <!-- 忘记密码表单 -->
    <div id="resetTab" class="tab-content">
        <form id="resetForm" class="login-form">
            <input type="email" id="resetEmail" placeholder="请输入邮箱" required>
            <div class="code-container">
                <input type="text" id="resetVerificationCode" class="code-input" placeholder="请输入验证码" required>
                <button type="button" id="sendResetCodeBtn" class="send-code-btn">发送验证码</button>
            </div>
            <input type="password" id="resetPassword" placeholder="请输入新密码" required>
            <input type="password" id="resetConfirmPassword" placeholder="请确认新密码" required>
            <button type="submit">重置密码</button>
            <a href="javascript:void(0)" class="forgot-password-link" onclick="switchTab('login')">返回登录</a>
        </form>
    </div>
</div>
<script> // 避免重复声明,使用立即执行函数创建作用域 (function() { 'use strict'; // 定义API的基础URL const baseUrl = 'https://api.phaten-audio.com/api'; //const baseUrl = 'http://localhost:8010/api'; // 获取模态框元素 const modal = document.getElementById("loginModal"); const loginForm = document.getElementById("loginForm"); const registerForm = document.getElementById("registerForm"); const resetForm = document.getElementById("resetForm"); const sendCodeBtn = document.getElementById("sendCodeBtn"); const sendResetCodeBtn = document.getElementById("sendResetCodeBtn"); let countdownTimer; let resetCountdownTimer; // 获取消息弹出框元素 const messageModal = document.getElementById("messageModal"); const messageTitle = document.getElementById("messageTitle"); const messageText = document.getElementById("messageText"); const messageBtn = document.getElementById("messageBtn"); const closeMessage = document.getElementsByClassName("close-message")[0]; // Tab 切换功能 window.switchTab = function(tabName) { // 获取tab容器 const tabContainer = document.querySelector('.tab-container'); // 隐藏所有tab内容 const tabContents = document.querySelectorAll('.tab-content'); tabContents.forEach(tab => tab.classList.remove('active')); // 移除所有tab按钮的active状态 const tabButtons = document.querySelectorAll('.tab-button'); tabButtons.forEach(btn => btn.classList.remove('active')); // 显示对应的tab内容和设置按钮active状态 if (tabName === 'login') { // 显示tab容器 tabContainer.style.display = 'flex'; document.getElementById('loginTab').classList.add('active'); document.querySelector('.tab-button').classList.add('active'); } else if (tabName === 'register') { // 显示tab容器 tabContainer.style.display = 'flex'; document.getElementById('registerTab').classList.add('active'); document.querySelectorAll('.tab-button')[1].classList.add('active'); } else if (tabName === 'reset') { // 忘记密码面板时隐藏tab容器 tabContainer.style.display = 'none'; document.getElementById('resetTab').classList.add('active'); } } // 显示自定义消息弹出框 function showMessage(title, text, type = 'info') { messageTitle.textContent = title; messageText.textContent = text; // 根据类型设置样式 messageText.className = type === 'success' ? 'success' : (type === 'error' ? 'error' : ''); messageModal.style.display = "block"; } // 关闭消息弹出框 function closeMessageModal() { messageModal.style.display = "none"; } // 绑定消息弹出框关闭事件 closeMessage.onclick = closeMessageModal; messageBtn.onclick = closeMessageModal; // 添加登录框关闭按钮 function closeLoginModal() { console.log("用户关闭了登录模态框"); modal.style.display = "none"; // 清除待下载的URL因为用户取消了登录 const pendingUrl = sessionStorage.getItem('pendingDownloadUrl'); if (pendingUrl) { console.log("清除待下载URL:", pendingUrl); sessionStorage.removeItem('pendingDownloadUrl'); } // 恢复下载按钮状态 const downloadBtn = document.getElementById('designDownloadBtn'); if (downloadBtn) { downloadBtn.classList.remove('loading'); downloadBtn.innerHTML = '下载'; console.log("恢复下载按钮状态"); } } // 点击消息模态框外部关闭(只关闭消息框,不关闭登录框) window.addEventListener('click', function(event) { if (event.target == messageModal) { closeMessageModal(); } // 点击登录框外部也可以关闭 if (event.target == modal) { closeLoginModal(); } }); // 检查本地存储中是否有token function getLocalToken() { return localStorage.getItem('ftyToken'); } // 保存token到本地存储 function saveToken(token) { localStorage.setItem('ftyToken', token); } // 清除token function clearToken() { localStorage.removeItem('ftyToken'); } // 验证token是否有效 async function validateToken() { const token = getLocalToken(); console.log("validateToken函数被调用token:", token); if (!token) { console.log("没有token返回false"); return false; } try { console.log("发送token验证请求..."); const response = await fetch(`${baseUrl}/fty/validateToken`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` } }); const data = await response.json(); console.log("token验证服务器响应:",data); const isValid = data.data && data.data.valid === true; console.log("token是否有效:", isValid); // 如果token无效清除本地存储 if (!isValid) { console.log("token无效清除本地存储"); clearToken(); } return isValid; } catch (error) { console.error('Token validation error:', error); console.log("token验证出错清除本地存储"); clearToken(); return false; } } // 检查登录状态 async function checkLogin(downloadUrl = null) { // 获取触发按钮并添加loading状态 const downloadBtn = document.getElementById('designDownloadBtn'); if (downloadBtn) { downloadBtn.classList.add('loading'); downloadBtn.innerHTML = '...'; } try { // 检查token是否有效 console.log("开始验证token..."); const token = getLocalToken(); console.log("本地token:", token); const isLoggedIn = await validateToken(); console.log("验证结果 isLoggedIn:",isLoggedIn); if (!isLoggedIn) { // 如果未登录,保存下载链接并显示登录模态框 if (downloadUrl) { sessionStorage.setItem('pendingDownloadUrl', downloadUrl); if (modal) { modal.style.display = "block"; } else { console.error("modal元素未找到!"); } } } else { // 如果已登录,直接进行下载 if (downloadUrl) { if (downloadBtn) { downloadBtn.innerHTML = '下载中...'; } window.location.href = downloadUrl; } } } catch (error) { console.error("登录验证出错:", error); } finally { // 恢复按钮状态(如果没有跳转的话) if (downloadBtn && !downloadBtn.innerHTML.includes('下载中')) { setTimeout(() => { downloadBtn.classList.remove('loading'); downloadBtn.innerHTML = '下载'; }, 500); } } } // 发送验证码 sendCodeBtn.onclick = function() { const contactValue = document.getElementById('registerEmail').value; if (!validateEmail(contactValue)) { showMessage('输入错误', '请输入有效的邮箱地址!', 'error'); return; } // 禁用按钮并开始倒计时 startCountdown(); // 发送AJAX请求获取验证码 fetch(`${baseUrl}/fty/sendCode`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ type: "1", // 固定为邮箱类型 username: contactValue }) }) .then(response => response.json()) .then(data => { console.log("验证码发送返回",data); if (data.code==2000) { showMessage('发送成功', '验证码已发送到您的邮箱!', 'success'); } else { showMessage('发送失败', data.msg || '验证码发送失败,请稍后重试!', 'error'); resetCountdown(); } }) .catch(error => { console.error('Error:', error); showMessage('网络错误', '验证码发送请求失败,请稍后重试!', 'error'); resetCountdown(); }); } // 发送重置密码验证码 sendResetCodeBtn.onclick = function() { const contactValue = document.getElementById('resetEmail').value; if (!validateEmail(contactValue)) { showMessage('输入错误', '请输入有效的邮箱地址!', 'error'); return; } // 禁用按钮并开始倒计时 startResetCountdown(); // 发送AJAX请求获取验证码 fetch(`${baseUrl}/fty/sendCode`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ type: "1", // 固定为邮箱类型 username: contactValue }) }) .then(response => response.json()) .then(data => { console.log("重置密码验证码发送返回",data); if (data.code==2000) { showMessage('发送成功', '验证码已发送到您的邮箱!', 'success'); } else { showMessage('发送失败', data.msg || '验证码发送失败,请稍后重试!', 'error'); resetResetCountdown(); } }) .catch(error => { console.error('Error:', error); showMessage('网络错误', '验证码发送请求失败,请稍后重试!', 'error'); resetResetCountdown(); }); } // 验证邮箱格式 function validateEmail(email) { const re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; return re.test(String(email).toLowerCase()); } // 开始倒计时 function startCountdown() { let countdown = 60; sendCodeBtn.disabled = true; sendCodeBtn.textContent = `${countdown}秒后重试`; countdownTimer = setInterval(() => { countdown--; sendCodeBtn.textContent = `${countdown}秒后重试`; if (countdown <= 0) { resetCountdown(); } }, 1000); } // 重置倒计时 function resetCountdown() { clearInterval(countdownTimer); sendCodeBtn.disabled = false; sendCodeBtn.textContent = '发送验证码'; } // 开始重置密码验证码倒计时 function startResetCountdown() { let countdown = 60; sendResetCodeBtn.disabled = true; sendResetCodeBtn.textContent = `${countdown}秒后重试`; resetCountdownTimer = setInterval(() => { countdown--; sendResetCodeBtn.textContent = `${countdown}秒后重试`; if (countdown <= 0) { resetResetCountdown(); } }, 1000); } // 重置重置密码验证码倒计时 function resetResetCountdown() { clearInterval(resetCountdownTimer); sendResetCodeBtn.disabled = false; sendResetCodeBtn.textContent = '发送验证码'; } // 处理登录表单提交 loginForm.onsubmit = function(e) { console.log("Login form submitted"); e.preventDefault(); const email = document.getElementById("loginEmail").value; const password = document.getElementById("loginPassword").value; if (!validateEmail(email)) { showMessage('输入错误', '请输入有效的邮箱地址!', 'error'); return; } if (!password) { showMessage('输入错误', '请输入密码!', 'error'); return; } // 发送AJAX请求 fetch(`${baseUrl}/fty/userLogin`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ username: email, type: 1, password: password }) }) .then(response => response.json()) .then(data => { console.log("登录返回",data); if (data.code==2000) { // 保存token到本地存储 if (data.data.token) { saveToken(data.data.token); } showMessage('登录成功', '登录成功!', 'success'); // 登录成功后关闭模态框 modal.style.display = "none"; // 检查是否有待下载的链接 const pendingDownloadUrl = sessionStorage.getItem('pendingDownloadUrl'); if (pendingDownloadUrl) { sessionStorage.removeItem('pendingDownloadUrl'); // 延迟一下再跳转,让用户看到成功消息 setTimeout(() => { const downloadBtn = document.getElementById('designDownloadBtn'); if (downloadBtn) { downloadBtn.innerHTML = '下载中...'; } window.location.href = pendingDownloadUrl; }, 1500); } } else { showMessage('登录失败', data.msg || '登录失败,请检查邮箱和密码!', 'error'); } }) .catch(error => { console.error('Error:', error); showMessage('网络错误', '登录请求失败,请稍后重试!', 'error'); }); } // 处理注册表单提交 registerForm.onsubmit = function(e) { console.log("Register form submitted"); e.preventDefault(); const email = document.getElementById("registerEmail").value; const verificationCode = document.getElementById("verificationCode").value; const password = document.getElementById("registerPassword").value; const confirmPassword = document.getElementById("confirmPassword").value; if (!validateEmail(email)) { showMessage('输入错误', '请输入有效的邮箱地址!', 'error'); return; } if (!verificationCode) { showMessage('输入错误', '请输入验证码!', 'error'); return; } if (!password) { showMessage('输入错误', '请输入密码!', 'error'); return; } if (password !== confirmPassword) { showMessage('输入错误', '两次输入的密码不一致!', 'error'); return; } // 发送AJAX请求 fetch(`${baseUrl}/fty/register`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 1, // 固定为邮箱类型 username: email, code: verificationCode, password: password, confirm_password:confirmPassword }) }) .then(response => response.json()) .then(data => { console.log("注册返回",data); if (data.code==2000) { // 保存token到本地存储 if (data.data.token) { saveToken(data.data.token); } showMessage('注册成功', '注册成功!', 'success'); // 注册成功后关闭模态框 modal.style.display = "none"; resetCountdown(); // 检查是否有待下载的链接 const pendingDownloadUrl = sessionStorage.getItem('pendingDownloadUrl'); if (pendingDownloadUrl) { sessionStorage.removeItem('pendingDownloadUrl'); // 延迟一下再跳转,让用户看到成功消息 setTimeout(() => { const downloadBtn = document.getElementById('designDownloadBtn'); if (downloadBtn) { downloadBtn.innerHTML = '下载中...'; } window.location.href = pendingDownloadUrl; }, 1500); } } else { showMessage('注册失败', data.msg || '注册失败,请检查输入信息!', 'error'); } }) .catch(error => { console.error('Error:', error); showMessage('网络错误', '注册请求失败,请稍后重试!', 'error'); }); } // 处理忘记密码表单提交 resetForm.onsubmit = function(e) { console.log("Reset password form submitted"); e.preventDefault(); const email = document.getElementById("resetEmail").value; const verificationCode = document.getElementById("resetVerificationCode").value; const password = document.getElementById("resetPassword").value; const confirmPassword = document.getElementById("resetConfirmPassword").value; if (!validateEmail(email)) { showMessage('输入错误', '请输入有效的邮箱地址!', 'error'); return; } if (!verificationCode) { showMessage('输入错误', '请输入验证码!', 'error'); return; } if (!password) { showMessage('输入错误', '请输入新密码!', 'error'); return; } if (password !== confirmPassword) { showMessage('输入错误', '两次输入的密码不一致!', 'error'); return; } // 显示加载状态 const submitBtn = resetForm.querySelector('button[type="submit"]'); const originalText = submitBtn.textContent; submitBtn.textContent = '重置中...'; submitBtn.disabled = true; // 发送AJAX请求 fetch(`${baseUrl}/fty/resetpwd`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 1, // 固定为邮箱类型 username: email, code: verificationCode, password: password, confirm_password: confirmPassword }) }) .then(response => response.json()) .then(data => { console.log("重置密码返回",data); if (data.code==2000) { showMessage('重置成功', '密码重置成功!请使用新密码登录', 'success'); resetResetCountdown(); // 延迟切换到登录标签 setTimeout(() => { switchTab('login'); // 清空重置表单 resetForm.reset(); }, 1500); } else { showMessage('重置失败', data.msg || '密码重置失败,请检查输入信息!', 'error'); } }) .catch(error => { console.error('Error:', error); showMessage('网络错误', '密码重置请求失败,请稍后重试!', 'error'); }) .finally(() => { // 恢复按钮状态 submitBtn.textContent = originalText; submitBtn.disabled = false; }); } // ESC键关闭登录框 document.addEventListener('keydown', function(event) { if (event.key === 'Escape' && modal.style.display === 'block') { console.log("用户按ESC键关闭登录框"); closeLoginModal(); } }); // 页面加载时自动验证token document.addEventListener('DOMContentLoaded', async function() { // 自动检查登录状态(但不自动弹出登录框) await validateToken(); // 额外检查modal元素是否正确获取 console.log("页面加载完成modal元素:", modal); }); // 将需要全局访问的函数暴露到window对象 window.checkLogin = checkLogin; window.closeLoginModal = closeLoginModal; })(); // 立即执行函数结束 </script>