复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户认证中心</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.gradient-bg {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.card-shadow {
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.tab-active {
border-bottom: 3px solid #667eea;
color: #667eea;
font-weight: 600;
}
.input-focus:focus {
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.5);
}
.slide-in {
animation: slideIn 0.3s ease-out;
}
@keyframes slideIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body class="gradient-bg min-h-screen flex items-center justify-center p-4">
<div class="bg-white rounded-2xl p-8 w-full max-w-md card-shadow">
<!-- 选项卡导航 -->
<div class="flex border-b border-gray-200 mb-6">
<button id="tabLogin" class="flex-1 py-2 px-4 text-center font-medium text-gray-700 tab-active">
密码登录
</button>
<button id="tabSmsLogin" class="flex-1 py-2 px-4 text-center font-medium text-gray-700">
验证码登录
</button>
<button id="tabRegister" class="flex-1 py-2 px-4 text-center font-medium text-gray-700">
手机注册
</button>
</div>
<!-- 密码登录表单 -->
<div id="loginFormContainer" class="space-y-6 slide-in">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">电子邮箱</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-envelope text-gray-400"></i>
</div>
<input type="email" id="loginEmail" required
class="pl-10 w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:border-indigo-500 input-focus"
placeholder="请输入您的邮箱">
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">密码</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-lock text-gray-400"></i>
</div>
<input type="password" id="loginPassword" required
class="pl-10 w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:border-indigo-500 input-focus"
placeholder="请输入您的密码">
</div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center">
<input id="rememberMe" type="checkbox"
class="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded">
<label for="rememberMe" class="ml-2 block text-sm text-gray-700">记住我</label>
</div>
<div class="text-sm">
<a href="#" class="font-medium text-indigo-600 hover:text-indigo-500">忘记密码?</a>
</div>
</div>
<button id="loginBtn"
class="w-full bg-indigo-600 text-white py-3 px-4 rounded-lg hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-all">
登录
</button>
</div>
<!-- 验证码登录表单 -->
<div id="smsLoginFormContainer" class="space-y-6 hidden">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">手机号码</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-mobile-alt text-gray-400"></i>
</div>
<input type="tel" id="smsPhone" required
class="pl-10 w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:border-indigo-500 input-focus"
placeholder="请输入11位手机号码" pattern="[0-9]{11}">
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">验证码</label>
<div class="flex space-x-2">
<div class="relative flex-grow">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-shield-alt text-gray-400"></i>
</div>
<input type="text" id="smsCode" required
class="pl-10 w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:border-indigo-500 input-focus"
placeholder="请输入6位验证码" pattern="[0-9]{6}">
</div>
<button id="sendSmsCodeBtn"
class="whitespace-nowrap px-4 py-3 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-all">
获取验证码
</button>
</div>
</div>
<button id="smsLoginBtn"
class="w-full bg-indigo-600 text-white py-3 px-4 rounded-lg hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-all">
验证码登录
</button>
</div>
<!-- 手机注册表单 -->
<div id="registerFormContainer" class="space-y-6 hidden">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">手机号码</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-mobile-alt text-gray-400"></i>
</div>
<input type="tel" id="registerPhone" required
class="pl-10 w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:border-indigo-500 input-focus"
placeholder="请输入11位手机号码" pattern="[0-9]{11}">
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">验证码</label>
<div class="flex space-x-2">
<div class="relative flex-grow">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-shield-alt text-gray-400"></i>
</div>
<input type="text" id="registerCode" required
class="pl-10 w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:border-indigo-500 input-focus"
placeholder="请输入6位验证码" pattern="[0-9]{6}">
</div>
<button id="sendRegisterCodeBtn"
class="whitespace-nowrap px-4 py-3 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-all">
获取验证码
</button>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">设置密码</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-lock text-gray-400"></i>
</div>
<input type="password" id="registerPassword" required
class="pl-10 w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:border-indigo-500 input-focus"
placeholder="请输入6-20位密码" minlength="6" maxlength="20">
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">确认密码</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="fas fa-lock text-gray-400"></i>
</div>
<input type="password" id="confirmPassword" required
class="pl-10 w-full px-4 py-3 rounded-lg border border-gray-300 focus:outline-none focus:border-indigo-500 input-focus"
placeholder="请再次输入密码" minlength="6" maxlength="20">
</div>
</div>
<div class="flex items-center">
<input id="agreeTerms" type="checkbox" required
class="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded">
<label for="agreeTerms" class="ml-2 block text-sm text-gray-700">
我已阅读并同意<a href="#" class="text-indigo-600 hover:text-indigo-500">《用户协议》</a>和<a href="#" class="text-indigo-600 hover:text-indigo-500">《隐私政策》</a>
</label>
</div>
<button id="registerBtn"
class="w-full bg-indigo-600 text-white py-3 px-4 rounded-lg hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-all">
立即注册
</button>
</div>
<!-- 第三方登录 -->
<div class="mt-8">
<div class="relative">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-gray-300"></div>
</div>
<div class="relative flex justify-center text-sm">
<span class="px-2 bg-white text-gray-500">或使用其他方式登录</span>
</div>
</div>
<div class="mt-6 grid grid-cols-3 gap-3">
<button type="button"
class="w-full inline-flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
<i class="fab fa-weixin text-green-500"></i>
</button>
<button type="button"
class="w-full inline-flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
<i class="fab fa-qq text-blue-500"></i>
</button>
<button type="button"
class="w-full inline-flex justify-center py-2 px-4 border border-gray-300 rounded-md shadow-sm bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
<i class="fab fa-weibo text-red-500"></i>
</button>
</div>
</div>
</div>
<script>
// 选项卡切换逻辑
const tabs = {
login: {
tab: document.getElementById('tabLogin'),
form: document.getElementById('loginFormContainer')
},
smsLogin: {
tab: document.getElementById('tabSmsLogin'),
form: document.getElementById('smsLoginFormContainer')
},
register: {
tab: document.getElementById('tabRegister'),
form: document.getElementById('registerFormContainer')
}
};
function switchTab(activeTab) {
Object.values(tabs).forEach(tab => {
tab.tab.classList.remove('tab-active');
tab.form.classList.add('hidden');
tab.form.classList.remove('slide-in');
});
activeTab.tab.classList.add('tab-active');
activeTab.form.classList.remove('hidden');
setTimeout(() => {
activeTab.form.classList.add('slide-in');
}, 10);
}
tabs.login.tab.addEventListener('click', () => switchTab(tabs.login));
tabs.smsLogin.tab.addEventListener('click', () => switchTab(tabs.smsLogin));
tabs.register.tab.addEventListener('click', () => switchTab(tabs.register));
// 验证码发送倒计时逻辑
function startCountdown(button, duration = 60) {
let remaining = duration;
button.disabled = true;
const originalText = button.textContent;
const timer = setInterval(() => {
button.innerHTML = `${remaining}秒后重新获取`;
remaining--;
if (remaining < 0) {
clearInterval(timer);
button.disabled = false;
button.textContent = originalText;
}
}, 1000);
}
document.getElementById('sendSmsCodeBtn').addEventListener('click', function() {
const phone = document.getElementById('smsPhone').value;
if (!/^[0-9]{11}$/.test(phone)) {
alert('请输入正确的11位手机号码');
return;
}
startCountdown(this);
alert(`验证码已发送到手机 ${phone}`);
});
document.getElementById('sendRegisterCodeBtn').addEventListener('click', function() {
const phone = document.getElementById('registerPhone').value;
if (!/^[0-9]{11}$/.test(phone)) {
alert('请输入正确的11位手机号码');
return;
}
startCountdown(this);
alert(`验证码已发送到手机 ${phone}`);
});
// 表单提交逻辑
document.getElementById('loginBtn').addEventListener('click', function() {
const email = document.getElementById('loginEmail').value;
const password = document.getElementById('loginPassword').value;
if (!email || !password) {
alert('请输入邮箱和密码');
return;
}
console.log('密码登录:', { email, password });
alert('登录成功!');
});
document.getElementById('smsLoginBtn').addEventListener('click', function() {
const phone = document.getElementById('smsPhone').value;
const code = document.getElementById('smsCode').value;
if (!/^[0-9]{11}$/.test(phone)) {
alert('请输入正确的11位手机号码');
return;
}
if (!/^[0-9]{6}$/.test(code)) {
alert('请输入正确的6位验证码');
return;
}
console.log('验证码登录:', { phone, code });
alert('登录成功!');
});
document.getElementById('registerBtn').addEventListener('click', function() {
const phone = document.getElementById('registerPhone').value;
const code = document.getElementById('registerCode').value;
const password = document.getElementById('registerPassword').value;
const confirmPass = document.getElementById('confirmPassword').value;
if (!/^[0-9]{11}$/.test(phone)) {
alert('请输入正确的11位手机号码');
return;
}
if (!/^[0-9]{6}$/.test(code)) {
alert('请输入正确的6位验证码');
return;
}
if (password !== confirmPass) {
alert('两次输入的密码不一致');
return;
}
if (!document.getElementById('agreeTerms').checked) {
alert('请阅读并同意用户协议和隐私政策');
return;
}
console.log('注册信息:', { phone, code, password });
alert('注册成功!');
});
</script>
</body>
</html>