<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SecureAuth - 多主题账号管理系统</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
:root {
/* 默认主题 */
--primary: #6366f1;
--primary-dark: #4f46e5;
--secondary: #8b5cf6;
--success: #10b981;
--danger: #ef4444;
--warning: #f59e0b;
--info: #3b82f6;
--light: #f8fafc;
--dark: #0f172a;
--gray: #94a3b8;
--border: #e2e8f0;
--card-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
--transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 紫色主题 */
.theme-purple {
--primary: #8b5cf6;
--primary-dark: #7c3aed;
--secondary: #a855f7;
--success: #86efac;
--danger: #f87171;
--warning: #fbbf24;
--info: #60a5fa;
--light: #f5f3ff;
--dark: #1c1917;
--gray: #a8a29e;
--border: #e9d5ff;
}
/* 绿色主题 */
.theme-green {
--primary: #10b981;
--primary-dark: #059669;
--secondary: #34d399;
--success: #60a5fa;
--danger: #f87171;
--warning: #fbbf24;
--info: #93c5fd;
--light: #ecfdf5;
--dark: #064e3b;
--gray: #64748b;
--border: #a7f3d0;
}
/* 橙色主题 */
.theme-orange {
--primary: #f97316;
--primary-dark: #ea580c;
--secondary: #fb923c;
--success: #4ade80;
--danger: #f87171;
--warning: #fde047;
--info: #93c5fd;
--light: #fff7ed;
--dark: #7c2d12;
--gray: #78716c;
--border: #fed7aa;
}
/* 蓝色主题 */
.theme-blue {
--primary: #3b82f6;
--primary-dark: #2563eb;
--secondary: #60a5fa;
--success: #4ade80;
--danger: #f87171;
--warning: #fbbf24;
--info: #818cf8;
--light: #eff6ff;
--dark: #1e3a8a;
--gray: #6b7280;
--border: #bfdbfe;
}
/* 粉色主题 */
.theme-pink {
--primary: #ec4899;
--primary-dark: #db2777;
--secondary: #f472b6;
--success: #86efac;
--danger: #f87171;
--warning: #fbbf24;
--info: #93c5fd;
--light: #fdf2f8;
--dark: #831843;
--gray: #78716c;
--border: #fbcfe8;
}
body {
background: linear-gradient(135deg, var(--light) 0%, #e0f2fe 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
position: relative;
overflow-x: hidden;
transition: var(--transition);
}
body.dark-theme {
background: linear-gradient(135deg, var(--dark) 0%, #1e293b 100%);
color: #e2e8f0;
}
body::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(99, 102, 241, 0.05) 0%, transparent 70%);
z-index: -1;
}
body.dark-theme::before {
background: radial-gradient(circle, rgba(99, 102, 241, 0.1) 0%, transparent 70%);
}
.container {
width: 100%;
max-width: 1200px;
display: flex;
flex-direction: column;
gap: 30px;
}
.header {
text-align: center;
padding: 20px;
animation: fadeInDown 0.8s ease;
}
.header h1 {
font-size: 2.8rem;
background: linear-gradient(135deg, var(--primary), var(--secondary));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
margin-bottom: 10px;
font-weight: 800;
}
.header.dark-theme h1 {
background: linear-gradient(135deg, #818cf8, #a78bfa);
-webkit-background-clip: text;
background-clip: text;
}
.header p {
color: var(--gray);
font-size: 1.2rem;
max-width: 600px;
margin: 0 auto;
}
.header.dark-theme p {
color: #94a3b8;
}
.main-content {
display: flex;
gap: 30px;
flex-wrap: wrap;
}
.card {
background: white;
border-radius: 20px;
box-shadow: var(--card-shadow);
padding: 30px;
transition: var(--transition);
position: relative;
overflow: hidden;
}
.card.dark-theme {
background: #1e293b;
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3), 0 8px 10px -6px rgba(0, 0, 0, 0.3);
}
.card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 4px;
background: linear-gradient(90deg, var(--primary), var(--secondary));
}
.card.dark-theme::before {
background: linear-gradient(90deg, #818cf8, #a78bfa);
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 20px 30px -10px rgba(0, 0, 0, 0.15);
}
.card.dark-theme:hover {
box-shadow: 0 20px 30px -10px rgba(0, 0, 0, 0.3);
}
.auth-section {
flex: 1;
min-width: 400px;
animation: slideInLeft 0.6s ease;
}
.features-section {
width: 350px;
animation: slideInRight 0.6s ease;
}
.form-container {
display: none;
}
.form-container.active {
display: block;
animation: fadeIn 0.5s ease;
}
.form-header {
text-align: center;
margin-bottom: 30px;
}
.form-header h2 {
font-size: 1.8rem;
color: var(--dark);
margin-bottom: 10px;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.form-header.dark-theme h2 {
color: #e2e8f0;
}
.form-header p {
color: var(--gray);
font-size: 1rem;
}
.form-header.dark-theme p {
color: #94a3b8;
}
.form-group {
margin-bottom: 20px;
position: relative;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-weight: 500;
color: var(--dark);
font-size: 0.95rem;
}
.form-group.dark-theme label {
color: #e2e8f0;
}
.input-wrapper {
position: relative;
}
.input-wrapper i {
position: absolute;
left: 15px;
top: 50%;
transform: translateY(-50%);
color: var(--gray);
transition: var(--transition);
}
.input-wrapper.dark-theme i {
color: #94a3b8;
}
.form-control {
width: 100%;
padding: 14px 14px 14px 45px;
border: 2px solid var(--border);
border-radius: 12px;
font-size: 1rem;
transition: var(--transition);
background: #f8fafc;
}
.form-control.dark-theme {
background: #334155;
border-color: #475569;
color: #e2e8f0;
}
.form-control:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1);
background: white;
}
.form-control.dark-theme:focus {
background: #1e293b;
border-color: #818cf8;
box-shadow: 0 0 0 4px rgba(129, 140, 248, 0.2);
}
.form-control:focus + i {
color: var(--primary);
}
.form-control.dark-theme:focus + i {
color: #818cf8;
}
.password-toggle {
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
color: var(--gray);
transition: var(--transition);
}
.password-toggle.dark-theme {
color: #94a3b8;
}
.password-toggle:hover {
color: var(--primary);
}
.password-toggle.dark-theme:hover {
color: #818cf8;
}
.btn {
width: 100%;
padding: 14px;
border: none;
border-radius: 12px;
font-size: 1.1rem;
font-weight: 600;
cursor: pointer;
transition: var(--transition);
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.btn-primary {
background: linear-gradient(135deg, var(--primary), var(--secondary));
color: white;
box-shadow: 0 4px 15px rgba(99, 102, 241, 0.3);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(99, 102, 241, 0.4);
}
.btn-primary:active {
transform: translateY(0);
}
.btn-outline {
background: transparent;
border: 2px solid var(--primary);
color: var(--primary);
}
.btn-outline:hover {
background: var(--primary);
color: white;
}
.form-footer {
text-align: center;
margin-top: 20px;
color: var(--gray);
font-size: 0.95rem;
}
.form-footer.dark-theme {
color: #94a3b8;
}
.form-footer a {
color: var(--primary);
text-decoration: none;
font-weight: 500;
transition: var(--transition);
}
.form-footer.dark-theme a {
color: #818cf8;
}
.form-footer a:hover {
color: var(--primary-dark);
text-decoration: underline;
}
.form-footer.dark-theme a:hover {
color: #a78bfa;
}
.message {
padding: 15px 20px;
border-radius: 12px;
margin-bottom: 20px;
display: none;
animation: slideInUp 0.3s ease;
font-size: 0.95rem;
font-weight: 500;
}
.message.success {
background: rgba(16, 185, 129, 0.1);
border: 1px solid var(--success);
color: var(--success);
}
.message.error {
background: rgba(239, 68, 68, 0.1);
border: 1px solid var(--danger);
color: var(--danger);
}
.message.info {
background: rgba(59, 130, 246, 0.1);
border: 1px solid var(--info);
color: var(--info);
}
.password-strength {
height: 6px;
background: var(--border);
border-radius: 3px;
margin-top: 8px;
overflow: hidden;
}
.password-strength.dark-theme {
background: #475569;
}
.strength-bar {
height: 100%;
width: 0%;
border-radius: 3px;
transition: var(--transition);
}
.strength-weak { background: var(--danger); width: 33%; }
.strength-medium { background: var(--warning); width: 66%; }
.strength-strong { background: var(--success); width: 100%; }
.strength-text {
font-size: 0.85rem;
margin-top: 5px;
color: var(--gray);
}
.strength-text.dark-theme {
color: #94a3b8;
}
.features-list h3 {
font-size: 1.5rem;
color: var(--dark);
margin-bottom: 20px;
display: flex;
align-items: center;
gap: 10px;
}
.features-list.dark-theme h3 {
color: #e2e8f0;
}
.feature-item {
display: flex;
align-items: flex-start;
gap: 15px;
padding: 15px;
border-radius: 12px;
margin-bottom: 15px;
transition: var(--transition);
background: #f8fafc;
}
.feature-item.dark-theme {
background: #334155;
}
.feature-item:hover {
background: white;
transform: translateX(5px);
}
.feature-item.dark-theme:hover {
background: #475569;
}
.feature-icon {
width: 40px;
height: 40px;
border-radius: 10px;
background: linear-gradient(135deg, var(--primary), var(--secondary));
display: flex;
align-items: center;
justify-content: center;
color: white;
flex-shrink: 0;
}
.feature-icon.dark-theme {
background: linear-gradient(135deg, #818cf8, #a78bfa);
}
.feature-content h4 {
font-size: 1.1rem;
color: var(--dark);
margin-bottom: 5px;
}
.feature-content.dark-theme h4 {
color: #e2e8f0;
}
.feature-content p {
color: var(--gray);
font-size: 0.9rem;
line-height: 1.5;
}
.feature-content.dark-theme p {
color: #94a3b8;
}
.user-dashboard {
display: none;
width: 100%;
animation: fadeIn 0.5s ease;
}
.dashboard-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30px;
padding-bottom: 20px;
border-bottom: 1px solid var(--border);
}
.dashboard-header.dark-theme {
border-color: #475569;
}
.user-info {
display: flex;
align-items: center;
gap: 15px;
}
.avatar {
width: 60px;
height: 60px;
border-radius: 50%;
background: linear-gradient(135deg, var(--primary), var(--secondary));
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 1.5rem;
font-weight: bold;
}
.avatar.dark-theme {
background: linear-gradient(135deg, #818cf8, #a78bfa);
}
.user-details h2 {
font-size: 1.8rem;
color: var(--dark);
margin-bottom: 5px;
}
.user-details.dark-theme h2 {
color: #e2e8f0;
}
.user-details p {
color: var(--gray);
font-size: 1rem;
}
.user-details.dark-theme p {
color: #94a3b8;
}
.logout-btn {
background: rgba(239, 68, 68, 0.1);
color: var(--danger);
border: 1px solid var(--danger);
padding: 10px 20px;
border-radius: 10px;
cursor: pointer;
transition: var(--transition);
font-weight: 500;
}
.logout-btn.dark-theme {
background: rgba(239, 68, 68, 0.2);
color: #f87171;
border-color: #f87171;
}
.logout-btn:hover {
background: var(--danger);
color: white;
}
.logout-btn.dark-theme:hover {
background: #f87171;
color: #1e293b;
}
.dashboard-content {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 25px;
margin-bottom: 30px;
}
.info-card {
background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
border-radius: 15px;
padding: 25px;
transition: var(--transition);
}
.info-card.dark-theme {
background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
}
.info-card:hover {
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.08);
}
.info-card.dark-theme:hover {
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
}
.info-card h3 {
font-size: 1.2rem;
color: var(--dark);
margin-bottom: 15px;
display: flex;
align-items: center;
gap: 10px;
}
.info-card.dark-theme h3 {
color: #e2e8f0;
}
.info-card p {
color: var(--gray);
font-size: 1rem;
line-height: 1.6;
}
.info-card.dark-theme p {
color: #94a3b8;
}
.dashboard-actions {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
}
.action-card {
background: white;
border-radius: 15px;
padding: 25px;
text-align: center;
transition: var(--transition);
border: 1px solid var(--border);
cursor: pointer;
}
.action-card.dark-theme {
background: #1e293b;
border-color: #475569;
}
.action-card:hover {
transform: translateY(-5px);
box-shadow: var(--card-shadow);
border-color: var(--primary);
}
.action-card.dark-theme:hover {
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3), 0 8px 10px -6px rgba(0, 0, 0, 0.3);
border-color: #818cf8;
}
.action-icon {
width: 60px;
height: 60px;
border-radius: 15px;
background: rgba(99, 102, 241, 0.1);
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 15px;
color: var(--primary);
font-size: 1.5rem;
}
.action-icon.dark-theme {
background: rgba(129, 140, 248, 0.2);
color: #818cf8;
}
.action-card:hover .action-icon {
background: var(--primary);
color: white;
}
.action-card.dark-theme:hover .action-icon {
background: #818cf8;
color: #1e293b;
}
.action-card h4 {
font-size: 1.1rem;
color: var(--dark);
margin-bottom: 10px;
}
.action-card.dark-theme h4 {
color: #e2e8f0;
}
.action-card p {
color: var(--gray);
font-size: 0.9rem;
}
.action-card.dark-theme p {
color: #94a3b8;
}
.loading {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid rgba(255,255,255,.3);
border-radius: 50%;
border-top-color: #fff;
animation: spin 1s ease-in-out infinite;
}
.theme-selector {
position: fixed;
top: 20px;
right: 20px;
z-index: 100;
display: flex;
gap: 10px;
flex-direction: column;
}
.theme-btn {
width: 40px;
height: 40px;
border-radius: 50%;
border: 2px solid white;
cursor: pointer;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
transition: var(--transition);
}
.theme-btn:hover {
transform: scale(1.1);
}
.theme-light {
background: linear-gradient(135deg, #6366f1, #8b5cf6);
}
.theme-dark {
background: linear-gradient(135deg, #1e293b, #0f172a);
}
.theme-auto {
background: linear-gradient(135deg, #6366f1, #1e293b);
}
.theme-purple-btn {
background: linear-gradient(135deg, #8b5cf6, #a855f7);
}
.theme-green-btn {
background: linear-gradient(135deg, #10b981, #34d399);
}
.theme-orange-btn {
background: linear-gradient(135deg, #f97316, #fb923c);
}
.theme-blue-btn {
background: linear-gradient(135deg, #3b82f6, #60a5fa);
}
.theme-pink-btn {
background: linear-gradient(135deg, #ec4899, #f472b6);
}
.weather-widget {
background: linear-gradient(135deg, var(--primary), var(--secondary));
color: white;
border-radius: 15px;
padding: 20px;
margin-top: 20px;
text-align: center;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}
.weather-widget.dark-theme {
background: linear-gradient(135deg, var(--primary-dark), var(--primary));
}
.weather-icon {
font-size: 3rem;
margin-bottom: 10px;
}
.weather-temp {
font-size: 2.5rem;
font-weight: bold;
margin: 10px 0;
}
.weather-location {
font-size: 1.1rem;
opacity: 0.9;
}
.weather-desc {
font-size: 1rem;
opacity: 0.8;
margin-top: 5px;
}
.location-info {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
margin-top: 15px;
font-size: 0.9rem;
opacity: 0.8;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fadeInDown {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideInLeft {
from {
opacity: 0;
transform: translateX(-30px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideInRight {
from {
opacity: 0;
transform: translateX(30px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes spin {
to { transform: rotate(360deg); }
}
@media (max-width: 900px) {
.main-content {
flex-direction: column;
}
.auth-section, .features-section {
min-width: 100%;
}
}
@media (max-width: 768px) {
.dashboard-header {
flex-direction: column;
gap: 20px;
align-items: flex-start;
}
.user-info {
width: 100%;
}
.logout-btn {
width: 100%;
}
.theme-selector {
flex-direction: row;
top: 10px;
right: 10px;
}
.theme-btn {
width: 30px;
height: 30px;
}
}
@media (max-width: 480px) {
.card {
padding: 20px;
}
.header h1 {
font-size: 2.2rem;
}
.dashboard-content, .dashboard-actions {
grid-template-columns: 1fr;
}
.theme-selector {
top: 10px;
right: 10px;
}
.theme-btn {
width: 25px;
height: 25px;
}
}
</style>
</head>
<body>
<!-- 主题选择器 -->
<div class="theme-selector">
<div class="theme-btn theme-light" title="浅色主题" onclick="setTheme('light')"></div>
<div class="theme-btn theme-dark" title="深色主题" onclick="setTheme('dark')"></div>
<div class="theme-btn theme-auto" title="自动主题" onclick="setTheme('auto')"></div>
<div class="theme-btn theme-purple-btn" title="紫色主题" onclick="setTheme('purple')"></div>
<div class="theme-btn theme-green-btn" title="绿色主题" onclick="setTheme('green')"></div>
<div class="theme-btn theme-orange-btn" title="橙色主题" onclick="setTheme('orange')"></div>
<div class="theme-btn theme-blue-btn" title="蓝色主题" onclick="setTheme('blue')"></div>
<div class="theme-btn theme-pink-btn" title="粉色主题" onclick="setTheme('pink')"></div>
</div>
<div class="container">
<div class="header">
<h1><i class="fas fa-shield-alt"></i> SecureAuth 系统</h1>
<p>现代化的账号管理系统,为您提供安全可靠的用户认证服务</p>
</div>
<div class="main-content">
<div class="auth-section">
<div class="card">
<!-- 注册表单 -->
<div id="registerForm" class="form-container active">
<div class="form-header">
<h2><i class="fas fa-user-plus"></i> 创建账户</h2>
<p>填写信息创建您的新账户</p>
</div>
<div id="registerMessage" class="message"></div>
<form id="register">
<div class="form-group">
<label for="regUsername">用户名</label>
<div class="input-wrapper">
<i class="fas fa-user"></i>
<input type="text" id="regUsername" class="form-control" required minlength="3" maxlength="20" placeholder="输入用户名">
</div>
</div>
<div class="form-group">
<label for="regEmail">邮箱地址</label>
<div class="input-wrapper">
<i class="fas fa-envelope"></i>
<input type="email" id="regEmail" class="form-control" required placeholder="输入邮箱地址">
</div>
</div>
<div class="form-group">
<label for="regPassword">密码</label>
<div class="input-wrapper">
<i class="fas fa-lock"></i>
<input type="password" id="regPassword" class="form-control" required minlength="6" maxlength="20" placeholder="输入密码">
<span class="password-toggle" onclick="togglePassword('regPassword')">
<i class="fas fa-eye"></i>
</span>
</div>
<div class="password-strength">
<div class="strength-bar" id="passwordStrength"></div>
</div>
<div class="strength-text" id="strengthText">请输入密码</div>
</div>
<div class="form-group">
<label for="confirmPassword">确认密码</label>
<div class="input-wrapper">
<i class="fas fa-lock"></i>
<input type="password" id="confirmPassword" class="form-control" required placeholder="再次输入密码">
<span class="password-toggle" onclick="togglePassword('confirmPassword')">
<i class="fas fa-eye"></i>
</span>
</div>
</div>
<button type="submit" class="btn btn-primary" id="registerBtn">
<span id="registerBtnText"><i class="fas fa-user-plus"></i> 注册账户</span>
</button>
</form>
<div class="form-footer">
已有账户? <a href="#" onclick="showLoginForm()">立即登录</a>
</div>
</div>
<!-- 登录表单 -->
<div id="loginForm" class="form-container">
<div class="form-header">
<h2><i class="fas fa-sign-in-alt"></i> 用户登录</h2>
<p>使用您的账户信息登录系统</p>
</div>
<div id="loginMessage" class="message"></div>
<form id="login">
<div class="form-group">
<label for="loginUsername">用户名或邮箱</label>
<div class="input-wrapper">
<i class="fas fa-user"></i>
<input type="text" id="loginUsername" class="form-control" required placeholder="输入用户名或邮箱">
</div>
</div>
<div class="form-group">
<label for="loginPassword">密码</label>
<div class="input-wrapper">
<i class="fas fa-lock"></i>
<input type="password" id="loginPassword" class="form-control" required placeholder="输入密码">
<span class="password-toggle" onclick="togglePassword('loginPassword')">
<i class="fas fa-eye"></i>
</span>
</div>
</div>
<div class="form-group">
<div style="display: flex; justify-content: space-between; align-items: center;">
<label style="display: flex; align-items: center; gap: 8px;">
<input type="checkbox" id="rememberMe">
<span>记住我</span>
</label>
<a href="#" onclick="showForgotPasswordForm()" style="color: var(--primary); text-decoration: none;">忘记密码?</a>
</div>
</div>
<button type="submit" class="btn btn-primary" id="loginBtn">
<span id="loginBtnText"><i class="fas fa-sign-in-alt"></i> 登录账户</span>
</button>
</form>
<div class="form-footer">
没有账户? <a href="#" onclick="showRegisterForm()">立即注册</a>
</div>
</div>
<!-- 忘记密码表单 -->
<div id="forgotPasswordForm" class="form-container">
<div class="form-header">
<h2><i class="fas fa-key"></i> 找回密码</h2>
<p>输入邮箱地址重置您的密码</p>
</div>
<div id="forgotPasswordMessage" class="message"></div>
<form id="forgotPassword">
<div class="form-group">
<label for="forgotEmail">邮箱地址</label>
<div class="input-wrapper">
<i class="fas fa-envelope"></i>
<input type="email" id="forgotEmail" class="form-control" required placeholder="输入注册邮箱">
</div>
</div>
<button type="submit" class="btn btn-primary">
<i class="fas fa-paper-plane"></i> 发送重置链接
</button>
</form>
<div class="form-footer">
<a href="#" onclick="showLoginForm()"><i class="fas fa-arrow-left"></i> 返回登录</a>
</div>
</div>
<!-- 天气小部件 -->
<div class="weather-widget" id="weatherWidget">
<div class="weather-icon">
<i class="fas fa-cloud-sun"></i>
</div>
<div class="weather-temp">22°C</div>
<div class="weather-location">正在获取位置...</div>
<div class="weather-desc">晴朗</div>
<div class="location-info">
<i class="fas fa-map-marker-alt"></i>
<span id="locationText">定位中...</span>
</div>
</div>
</div>
</div>
<div class="features-section">
<div class="card">
<div class="features-list">
<h3><i class="fas fa-star"></i> 系统特性</h3>
<div class="feature-item">
<div class="feature-icon">
<i class="fas fa-shield-alt"></i>
</div>
<div class="feature-content">
<h4>安全保障</h4>
<p>采用先进的加密技术保护您的账户安全</p>
</div>
</div>
<div class="feature-item">
<div class="feature-icon">
<i class="fas fa-lock"></i>
</div>
<div class="feature-content">
<h4>密码强度</h4>
<p>实时检测密码强度,确保账户安全</p>
</div>
</div>
<div class="feature-item">
<div class="feature-icon">
<i class="fas fa-eye"></i>
</div>
<div class="feature-content">
<h4>密码可见</h4>
<p>一键切换密码可见性,输入更方便</p>
</div>
</div>
<div class="feature-item">
<div class="feature-icon">
<i class="fas fa-mobile-alt"></i>
</div>
<div class="feature-content">
<h4>响应式设计</h4>
<p>完美适配各种设备,随时随地使用</p>
</div>
</div>
<div class="feature-item">
<div class="feature-icon">
<i class="fas fa-bolt"></i>
</div>
<div class="feature-content">
<h4>快速验证</h4>
<p>智能表单验证,提升用户体验</p>
</div>
</div>
<div class="feature-item">
<div class="feature-icon">
<i class="fas fa-map-marker-alt"></i>
</div>
<div class="feature-content">
<h4>位置服务</h4>
<p>自动获取当前位置信息</p>
</div>
</div>
<div class="feature-item">
<div class="feature-icon">
<i class="fas fa-cloud-sun"></i>
</div>
<div class="feature-content">
<h4>天气信息</h4>
<p>显示当前位置天气状况</p>
</div>
</div>
<div class="feature-item">
<div class="feature-icon">
<i class="fas fa-palette"></i>
</div>
<div class="feature-content">
<h4>主题切换</h4>
<p>支持多种颜色主题和深色模式</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 用户仪表板 -->
<div id="userDashboard" class="user-dashboard">
<div class="card">
<div class="dashboard-header">
<div class="user-info">
<div class="avatar" id="userAvatar">U</div>
<div class="user-details">
<h2 id="dashboardUsername">用户名</h2>
<p id="dashboardEmail">user@example.com</p>
</div>
</div>
<button class="logout-btn" onclick="logout()">
<i class="fas fa-sign-out-alt"></i> 退出登录
</button>
</div>
<div class="dashboard-content">
<div class="info-card">
<h3><i class="fas fa-user-circle"></i> 账户信息</h3>
<p><strong>注册时间:</strong><span id="registerDate">2023-01-01</span></p>
<p><strong>最后登录:</strong><span id="lastLogin">2023-01-01</span></p>
<p><strong>账户状态:</strong><span class="success">正常</span></p>
</div>
<div class="info-card">
<h3><i class="fas fa-chart-line"></i> 使用统计</h3>
<p><strong>登录次数:</strong><span id="loginCount">0</span> 次</p>
<p><strong>在线时长:</strong><span id="onlineTime">0</span> 分钟</p>
<p><strong>安全等级:</strong><span class="warning">中等</span></p>
</div>
</div>
<div class="dashboard-actions">
<div class="action-card" onclick="showEditProfileModal()">
<div class="action-icon">
<i class="fas fa-user-edit"></i>
</div>
<h4>编辑资料</h4>
<p>更新个人信息</p>
</div>
<div class="action-card" onclick="showChangePasswordModal()">
<div class="action-icon">
<i class="fas fa-key"></i>
</div>
<h4>修改密码</h4>
<p>设置新密码</p>
</div>
<div class="action-card" onclick="showSecuritySettingsModal()">
<div class="action-icon">
<i class="fas fa-shield-alt"></i>
</div>
<h4>安全设置</h4>
<p>增强账户安全</p>
</div>
<div class="action-card" onclick="showActivityLogModal()">
<div class="action-icon">
<i class="fas fa-history"></i>
</div>
<h4>活动记录</h4>
<p>查看登录历史</p>
</div>
</div>
</div>
</div>
</div>
<script>
// 存储用户数据
let users = JSON.parse(localStorage.getItem('users')) || {};
let currentUser = localStorage.getItem('currentUser') || null;
let loginCount = parseInt(localStorage.getItem('loginCount')) || 0;
let onlineTime = parseInt(localStorage.getItem('onlineTime')) || 0;
let startTime = Date.now();
let activityLog = JSON.parse(localStorage.getItem('activityLog')) || [];
let currentTheme = localStorage.getItem('theme') || 'auto';
let currentLocation = null;
// 页面加载时初始化
document.addEventListener('DOMContentLoaded', function() {
// 设置主题
setTheme(currentTheme);
// 获取位置和天气
getLocationAndWeather();
// 检查登录状态
if (currentUser && users[currentUser]) {
showDashboard();
updateOnlineTime();
updateActivityLog();
} else {
showRegisterForm();
}
// 添加密码强度检测
document.getElementById('regPassword').addEventListener('input', function() {
checkPasswordStrength(this.value, 'passwordStrength', 'strengthText');
});
// 添加示例用户
addSampleUsers();
// 绑定表单提交事件
document.getElementById('register').addEventListener('submit', handleRegister);
document.getElementById('login').addEventListener('submit', handleLogin);
document.getElementById('forgotPassword').addEventListener('submit', handleForgotPassword);
});
// 设置主题
function setTheme(theme) {
currentTheme = theme;
localStorage.setItem('theme', theme);
// 移除所有主题类
document.body.classList.remove('dark-theme', 'theme-purple', 'theme-green', 'theme-orange', 'theme-blue', 'theme-pink');
// 根据主题添加相应类
if (theme === 'dark' || (theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.body.classList.add('dark-theme');
} else if (theme !== 'light' && theme !== 'auto') {
document.body.classList.add(`theme-${theme}`);
}
// 为所有元素添加/移除dark-theme类
const elements = document.querySelectorAll('.card, .form-header, .form-group, .input-wrapper, .form-control, .form-footer, .features-list, .feature-item, .feature-content, .dashboard-header, .user-details, .info-card, .action-card, .action-icon, .avatar, .logout-btn, .password-strength, .strength-text');
if (theme === 'dark' || (theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
elements.forEach(el => el.classList.add('dark-theme'));
} else {
elements.forEach(el => el.classList.remove('dark-theme'));
}
// 更新天气小部件主题
const weatherWidget = document.getElementById('weatherWidget');
if (weatherWidget) {
if (theme === 'dark' || (theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
weatherWidget.classList.add('dark-theme');
} else {
weatherWidget.classList.remove('dark-theme');
}
}
}
// 获取位置和天气信息
function getLocationAndWeather() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function(position) {
currentLocation = {
lat: position.coords.latitude,
lon: position.coords.longitude
};
// 更新位置显示
document.getElementById('locationText').textContent = `纬度: ${currentLocation.lat.toFixed(4)}, 经度: ${currentLocation.lon.toFixed(4)}`;
// 模拟天气数据(实际项目中应调用天气API)
const weatherConditions = [
{ temp: Math.floor(Math.random() * 15) + 15, condition: '晴朗', icon: 'fa-sun' },
{ temp: Math.floor(Math.random() * 10) + 10, condition: '多云', icon: 'fa-cloud' },
{ temp: Math.floor(Math.random() * 8) + 8, condition: '阴天', icon: 'fa-cloud-sun' },
{ temp: Math.floor(Math.random() * 5) + 5, condition: '小雨', icon: 'fa-cloud-rain' },
{ temp: Math.floor(Math.random() * 3) + 3, condition: '雷雨', icon: 'fa-bolt' }
];
const weatherData = weatherConditions[Math.floor(Math.random() * weatherConditions.length)];
// 更新天气显示
document.querySelector('.weather-icon i').className = `fas ${weatherData.icon}`;
document.querySelector('.weather-temp').textContent = `${weatherData.temp}°C`;
document.querySelector('.weather-desc').textContent = weatherData.condition;
document.querySelector('.weather-location').textContent = '当前位置';
},
function(error) {
console.error('获取位置失败:', error);
document.getElementById('locationText').textContent = '位置获取失败';
document.querySelector('.weather-location').textContent = '位置未知';
// 默认天气数据
document.querySelector('.weather-icon i').className = 'fas fa-cloud-sun';
document.querySelector('.weather-temp').textContent = '22°C';
document.querySelector('.weather-desc').textContent = '晴朗';
}
);
} else {
document.getElementById('locationText').textContent = '浏览器不支持定位';
document.querySelector('.weather-location').textContent = '位置未知';
// 默认天气数据
document.querySelector('.weather-icon i').className = 'fas fa-cloud-sun';
document.querySelector('.weather-temp').textContent = '22°C';
document.querySelector('.weather-desc').textContent = '晴朗';
}
}
// 更新在线时长
function updateOnlineTime() {
setInterval(() => {
if (currentUser) {
const elapsed = Math.floor((Date.now() - startTime) / 60000);
onlineTime += elapsed;
localStorage.setItem('onlineTime', onlineTime);
startTime = Date.now();
if (document.getElementById('onlineTime')) {
document.getElementById('onlineTime').textContent = onlineTime;
}
}
}, 60000);
}
// 更新活动日志
function updateActivityLog() {
if (currentUser) {
const now = new Date();
const activity = {
id: Date.now(),
user: currentUser,
action: '登录',
timestamp: now.toLocaleString(),
ip: '192.168.1.100',
location: currentLocation ? `${currentLocation.lat.toFixed(4)}, ${currentLocation.lon.toFixed(4)}` : '未知'
};
activityLog.push(activity);
localStorage.setItem('activityLog', JSON.stringify(activityLog));
}
}
// 密码强度检测
function checkPasswordStrength(password, barId, textId) {
const strengthBar = document.getElementById(barId);
const strengthText = document.getElementById(textId);
if (password.length === 0) {
strengthBar.className = 'strength-bar';
strengthText.textContent = '请输入密码';
strengthText.style.color = currentTheme === 'dark' ? '#94a3b8' : 'var(--gray)';
return;
}
let strength = 0;
let text = '';
let color = '';
// 长度检查
if (password.length >= 6) strength += 1;
if (password.length >= 10) strength += 1;
// 复杂度检查
if (/[a-z]/.test(password)) strength += 1;
if (/[A-Z]/.test(password)) strength += 1;
if (/[0-9]/.test(password)) strength += 1;
if (/[^A-Za-z0-9]/.test(password)) strength += 1;
if (strength <= 2) {
strengthBar.className = 'strength-bar strength-weak';
text = '密码强度:弱';
color = 'var(--danger)';
} else if (strength <= 4) {
strengthBar.className = 'strength-bar strength-medium';
text = '密码强度:中等';
color = 'var(--warning)';
} else {
strengthBar.className = 'strength-bar strength-strong';
text = '密码强度:强';
color = 'var(--success)';
}
strengthText.textContent = text;
strengthText.style.color = color;
}
// 切换密码可见性
function togglePassword(inputId) {
const input = document.getElementById(inputId);
const icon = input.nextElementSibling.querySelector('i');
if (input.type === 'password') {
input.type = 'text';
icon.className = 'fas fa-eye-slash';
} else {
input.type = 'password';
icon.className = 'fas fa-eye';
}
}
// 显示注册表单
function showRegisterForm() {
hideAllForms();
document.getElementById('registerForm').classList.add('active');
hideMessage('registerMessage');
}
// 显示登录表单
function showLoginForm() {
hideAllForms();
document.getElementById('loginForm').classList.add('active');
hideMessage('loginMessage');
}
// 显示忘记密码表单
function showForgotPasswordForm() {
hideAllForms();
document.getElementById('forgotPasswordForm').classList.add('active');
hideMessage('forgotPasswordMessage');
}
// 显示用户仪表板
function showDashboard() {
if (!currentUser || !users[currentUser]) {
showLoginForm();
return;
}
document.querySelector('.main-content').style.display = 'none';
document.getElementById('userDashboard').style.display = 'block';
// 更新仪表板信息
const user = users[currentUser];
document.getElementById('dashboardUsername').textContent = currentUser;
document.getElementById('dashboardEmail').textContent = user.email || '未设置';
document.getElementById('userAvatar').textContent = currentUser.charAt(0).toUpperCase();
document.getElementById('registerDate').textContent = user.registerDate || '未知';
document.getElementById('lastLogin').textContent = user.lastLogin || '首次登录';
document.getElementById('loginCount').textContent = user.loginCount || 0;
document.getElementById('onlineTime').textContent = onlineTime;
}
// 隐藏所有表单
function hideAllForms() {
const forms = document.querySelectorAll('.form-container');
forms.forEach(form => {
form.classList.remove('active');
});
document.querySelector('.main-content').style.display = 'flex';
document.getElementById('userDashboard').style.display = 'none';
}
// 隐藏消息
function hideMessage(elementId) {
const messageElement = document.getElementById(elementId);
if (messageElement) {
messageElement.style.display = 'none';
}
}
// 显示消息
function showMessage(elementId, message, type) {
const messageElement = document.getElementById(elementId);
if (messageElement) {
messageElement.textContent = message;
messageElement.className = 'message ' + type;
messageElement.style.display = 'block';
// 3秒后自动隐藏消息
setTimeout(() => {
messageElement.style.display = 'none';
}, 3000);
}
}
// 显示加载状态
function showLoading(buttonId, buttonTextId) {
const button = document.getElementById(buttonId);
const text = document.getElementById(buttonTextId);
if (button && text) {
button.disabled = true;
text.innerHTML = '<span class="loading"></span> 处理中...';
}
}
// 隐藏加载状态
function hideLoading(buttonId, buttonTextId, originalText) {
const button = document.getElementById(buttonId);
const text = document.getElementById(buttonTextId);
if (button && text) {
button.disabled = false;
text.innerHTML = originalText;
}
}
// 退出登录
function logout() {
localStorage.removeItem('currentUser');
currentUser = null;
showLoginForm();
showMessage('loginMessage', '已成功退出登录', 'success');
}
// 显示模态框
function showModal(modalId) {
document.getElementById(modalId).style.display = 'flex';
// 如果是编辑资料模态框,填充用户信息
if (modalId === 'editProfileModal' && currentUser && users[currentUser]) {
const user = users[currentUser];
document.getElementById('editUsername').value = currentUser;
document.getElementById('editEmail').value = user.email || '';
document.getElementById('editFirstName').value = user.firstName || '';
document.getElementById('editLastName').value = user.lastName || '';
document.getElementById('editPhone').value = user.phone || '';
document.getElementById('editBio').value = user.bio || '';
}
}
// 关闭模态框
function closeModal(modalId) {
document.getElementById(modalId).style.display = 'none';
}
// 显示编辑资料模态框
function showEditProfileModal() {
alert('编辑资料功能正在开发中...');
}
// 显示修改密码模态框
function showChangePasswordModal() {
alert('修改密码功能正在开发中...');
}
// 显示安全设置模态框
function showSecuritySettingsModal() {
alert('安全设置功能正在开发中...');
}
// 显示活动记录模态框
function showActivityLogModal() {
alert('活动记录功能正在开发中...');
}
// 注册表单处理
function handleRegister(e) {
e.preventDefault();
showLoading('registerBtn', 'registerBtnText');
setTimeout(() => {
const username = document.getElementById('regUsername').value.trim();
const email = document.getElementById('regEmail').value.trim();
const password = document.getElementById('regPassword').value;
const confirmPassword = document.getElementById('confirmPassword').value;
try {
// 验证输入
if (username.length < 3) {
throw new Error('用户名至少需要3个字符');
}
if (!isValidEmail(email)) {
throw new Error('请输入有效的邮箱地址');
}
if (password.length < 6) {
throw new Error('密码至少需要6个字符');
}
if (password !== confirmPassword) {
throw new Error('两次输入的密码不一致');
}
// 检查用户名是否已存在
if (users[username]) {
throw new Error('该用户名已存在');
}
// 检查邮箱是否已存在
for (let user in users) {
if (users[user].email === email) {
throw new Error('该邮箱已被注册');
}
}
// 注册用户
users[username] = {
password: password,
email: email,
registerDate: new Date().toLocaleString(),
loginCount: 0
};
// 保存到本地存储
localStorage.setItem('users', JSON.stringify(users));
showMessage('registerMessage', '注册成功!请登录', 'success');
// 清空表单
document.getElementById('register').reset();
document.getElementById('passwordStrength').className = 'strength-bar';
document.getElementById('strengthText').textContent = '请输入密码';
// 2秒后自动跳转到登录页面
setTimeout(() => {
showLoginForm();
}, 2000);
} catch (error) {
showMessage('registerMessage', error.message, 'error');
} finally {
hideLoading('registerBtn', 'registerBtnText', '<i class="fas fa-user-plus"></i> 注册账户');
}
}, 1000);
}
// 登录表单处理
function handleLogin(e) {
e.preventDefault();
showLoading('loginBtn', 'loginBtnText');
setTimeout(() => {
const loginInput = document.getElementById('loginUsername').value.trim();
const password = document.getElementById('loginPassword').value;
const rememberMe = document.getElementById('rememberMe').checked;
try {
// 验证输入
if (!loginInput || !password) {
throw new Error('请输入用户名/邮箱和密码');
}
let username = loginInput;
let userFound = false;
// 如果输入的是邮箱,查找对应的用户名
if (isValidEmail(loginInput)) {
for (let user in users) {
if (users[user].email === loginInput) {
username = user;
userFound = true;
break;
}
}
if (!userFound) {
throw new Error('邮箱不存在');
}
} else {
// 检查用户名是否存在
if (!users[username]) {
throw new Error('用户不存在');
}
}
// 验证密码
if (users[username].password !== password) {
throw new Error('密码错误');
}
// 更新最后登录时间
users[username].lastLogin = new Date().toLocaleString();
users[username].loginCount = (users[username].loginCount || 0) + 1;
loginCount++;
localStorage.setItem('users', JSON.stringify(users));
localStorage.setItem('loginCount', loginCount);
// 登录成功
localStorage.setItem('currentUser', username);
if (rememberMe) {
localStorage.setItem('rememberMe', username);
}
currentUser = username;
startTime = Date.now();
showMessage('loginMessage', '登录成功!', 'success');
// 更新活动日志
updateActivityLog();
// 显示仪表板
setTimeout(() => {
showDashboard();
}, 1000);
} catch (error) {
showMessage('loginMessage', error.message, 'error');
} finally {
hideLoading('loginBtn', 'loginBtnText', '<i class="fas fa-sign-in-alt"></i> 登录账户');
}
}, 1000);
}
// 忘记密码表单处理
function handleForgotPassword(e) {
e.preventDefault();
const email = document.getElementById('forgotEmail').value.trim();
try {
if (!isValidEmail(email)) {
throw new Error('请输入有效的邮箱地址');
}
// 查找邮箱对应的用户
let userFound = false;
for (let username in users) {
if (users[username].email === email) {
userFound = true;
break;
}
}
if (!userFound) {
throw new Error('该邮箱未注册');
}
showMessage('forgotPasswordMessage', '重置链接已发送到您的邮箱', 'success');
// 3秒后返回登录页面
setTimeout(() => {
showLoginForm();
}, 3000);
} catch (error) {
showMessage('forgotPasswordMessage', error.message, 'error');
}
}
// 邮箱验证
function isValidEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
// 添加示例用户
function addSampleUsers() {
if (Object.keys(users).length === 0) {
users = {
'admin': {
password: 'admin123',
email: 'admin@example.com',
firstName: '系统',
lastName: '管理员',
phone: '13800138000',
bio: '系统管理员账户',
registerDate: new Date().toLocaleString(),
loginCount: 5,
lastLogin: new Date().toLocaleString()
},
'user': {
password: 'user123',
email: 'user@example.com',
firstName: '普通',
lastName: '用户',
phone: '13900139000',
bio: '普通用户账户',
registerDate: new Date().toLocaleString(),
loginCount: 3,
lastLogin: new Date().toLocaleString()
}
};
localStorage.setItem('users', JSON.stringify(users));
// 添加示例活动记录
activityLog = [
{
id: 1,
user: 'admin',
action: '登录',
timestamp: '2023-06-15 14:30',
ip: '192.168.1.100',
location: '39.9042, 116.4074'
},
{
id: 2,
user: 'user',
action: '登录',
timestamp: '2023-06-15 15:45',
ip: '192.168.1.101',
location: '31.2304, 121.4737'
},
{
id: 3,
user: 'admin',
action: '修改密码',
timestamp: '2023-06-16 09:15',
ip: '192.168.1.100',
location: '39.9042, 116.4074'
}
];
localStorage.setItem('activityLog', JSON.stringify(activityLog));
}
}
// 点击模态框外部关闭模态框
window.onclick = function(event) {
const modals = document.querySelectorAll('.modal');
modals.forEach(modal => {
if (event.target === modal) {
modal.style.display = 'none';
}
});
}
</script>
</body>
</html>
index.html
index.html