Files
yixiaogao/frontend/login.html
2025-11-26 14:32:55 +08:00

724 lines
22 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户登录 - 易搜高</title>
<meta name="keywords" content="用户登录,易搜高,自媒体监控">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.login-container {
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
overflow: hidden;
width: 100%;
max-width: 900px;
min-height: 500px;
display: flex;
animation: slideUp 0.6s ease-out;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.login-left {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 60px 40px;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
overflow: hidden;
}
.login-left::before {
content: '';
position: absolute;
top: -50%;
right: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%);
animation: rotate 30s linear infinite;
}
@keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.login-left h1 {
font-size: 2.5em;
margin-bottom: 20px;
font-weight: 700;
position: relative;
z-index: 1;
}
.login-left p {
font-size: 1.1em;
line-height: 1.6;
opacity: 0.9;
margin-bottom: 30px;
position: relative;
z-index: 1;
}
.feature-list {
list-style: none;
position: relative;
z-index: 1;
}
.feature-list li {
padding: 10px 0;
display: flex;
align-items: center;
gap: 10px;
}
.feature-list li::before {
content: '✓';
background: rgba(255, 255, 255, 0.2);
width: 20px;
height: 20px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
}
.login-right {
flex: 1;
padding: 60px 40px;
display: flex;
flex-direction: column;
justify-content: center;
}
.login-header {
text-align: center;
margin-bottom: 40px;
}
.login-header h2 {
font-size: 2em;
color: #2c3e50;
margin-bottom: 10px;
font-weight: 600;
}
.login-header p {
color: #7f8c8d;
font-size: 1em;
}
.form-group {
margin-bottom: 25px;
}
.form-group label {
display: block;
margin-bottom: 8px;
color: #495057;
font-weight: 500;
font-size: 14px;
}
.form-group input {
width: 100%;
padding: 15px 20px;
border: 2px solid #e9ecef;
border-radius: 10px;
font-size: 16px;
transition: all 0.3s ease;
background: #f8f9fa;
}
.form-group input:focus {
outline: none;
border-color: #667eea;
background: white;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.form-group input::placeholder {
color: #adb5bd;
}
.password-group {
position: relative;
}
.password-toggle {
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: #6c757d;
cursor: pointer;
font-size: 18px;
padding: 5px;
}
.password-toggle:hover {
color: #667eea;
}
.form-options {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30px;
}
.remember-me {
display: flex;
align-items: center;
gap: 8px;
}
.remember-me input[type="checkbox"] {
width: 18px;
height: 18px;
accent-color: #667eea;
}
.remember-me label {
color: #495057;
font-size: 14px;
cursor: pointer;
}
.forgot-password {
color: #667eea;
text-decoration: none;
font-size: 14px;
transition: color 0.3s;
}
.forgot-password:hover {
color: #764ba2;
text-decoration: underline;
}
.login-btn {
width: 100%;
padding: 15px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 10px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.login-btn::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
transition: left 0.5s;
}
.login-btn:hover::before {
left: 100%;
}
.login-btn:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(102, 126, 234, 0.3);
}
.login-btn:active {
transform: translateY(0);
}
.divider {
text-align: center;
margin: 30px 0;
position: relative;
}
.divider::before {
content: '';
position: absolute;
top: 50%;
left: 0;
right: 0;
height: 1px;
background: #e9ecef;
}
.divider span {
background: white;
padding: 0 15px;
color: #6c757d;
font-size: 14px;
position: relative;
}
.social-login {
display: flex;
gap: 15px;
margin-bottom: 20px;
}
.social-btn {
flex: 1;
padding: 12px;
border: 2px solid #e9ecef;
background: white;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
font-size: 14px;
color: #495057;
}
.social-btn:hover {
border-color: #667eea;
background: #f8f9fa;
transform: translateY(-2px);
}
.register-link {
text-align: center;
color: #6c757d;
font-size: 14px;
}
.register-link a {
color: #667eea;
text-decoration: none;
font-weight: 600;
}
.register-link a:hover {
text-decoration: underline;
}
.back-to-home {
position: absolute;
top: 20px;
left: 20px;
background: rgba(255, 255, 255, 0.2);
color: white;
border: 1px solid rgba(255, 255, 255, 0.3);
padding: 10px 20px;
border-radius: 25px;
text-decoration: none;
font-size: 14px;
transition: all 0.3s;
display: flex;
align-items: center;
gap: 8px;
z-index: 10;
}
.back-to-home:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-2px);
text-decoration: none;
color: white;
}
/* 响应式设计 */
@media (max-width: 768px) {
.login-container {
flex-direction: column;
max-width: 400px;
min-height: auto;
}
.login-left {
padding: 40px 30px;
min-height: 200px;
}
.login-left h1 {
font-size: 2em;
}
.login-right {
padding: 40px 30px;
}
.login-header h2 {
font-size: 1.5em;
}
.social-login {
flex-direction: column;
}
}
/* 错误提示样式 */
.error-message {
background: #f8d7da;
color: #721c24;
padding: 12px 16px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #f5c6cb;
font-size: 14px;
display: none;
}
.success-message {
background: #d4edda;
color: #155724;
padding: 12px 16px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #c3e6cb;
font-size: 14px;
display: none;
}
</style>
</head>
<body>
<a href="frontend.html" class="back-to-home">
← 返回首页
</a>
<div class="login-container">
<div class="login-left">
<h1>🔍 易搜高</h1>
<p>专业的自媒体文章监控平台,让您轻松掌握行业动态</p>
<ul class="feature-list">
<li>实时监控多个自媒体平台</li>
<li>智能筛选热门文章</li>
<li>数据可视化分析</li>
<li>个性化推荐系统</li>
</ul>
</div>
<div class="login-right">
<div class="login-header">
<h2>欢迎登录</h2>
<p>请使用您的账号信息登录</p>
</div>
<div class="error-message" id="errorMessage"></div>
<div class="success-message" id="successMessage"></div>
<form id="loginForm">
<div class="form-group">
<label for="username">用户名 / 邮箱</label>
<input type="text" id="username" name="username" placeholder="请输入用户名或邮箱" required>
</div>
<div class="form-group">
<label for="password">密码</label>
<div class="password-group">
<input type="password" id="password" name="password" placeholder="请输入密码" required>
<button type="button" class="password-toggle" onclick="togglePassword()">👁️</button>
</div>
</div>
<div class="form-options">
<div class="remember-me">
<input type="checkbox" id="remember" name="remember">
<label for="remember">记住我</label>
</div>
<a href="#" class="forgot-password">忘记密码?</a>
</div>
<button type="submit" class="login-btn">登录</button>
</form>
<div class="divider">
<span>或使用其他方式登录</span>
</div>
<div class="social-login">
<button class="social-btn" onclick="socialLogin('wechat')">
💬 微信登录
</button>
<button class="social-btn" onclick="socialLogin('qq')">
🐧 QQ登录
</button>
</div>
<div class="register-link">
还没有账号?<a href="#">立即注册</a>
</div>
</div>
</div>
<script>
// 密码显示/隐藏切换
function togglePassword() {
const passwordInput = document.getElementById('password');
const toggleBtn = document.querySelector('.password-toggle');
if (passwordInput.type === 'password') {
passwordInput.type = 'text';
toggleBtn.textContent = '🙈';
} else {
passwordInput.type = 'password';
toggleBtn.textContent = '👁️';
}
}
// 显示错误消息
function showError(message) {
const errorDiv = document.getElementById('errorMessage');
const successDiv = document.getElementById('successMessage');
errorDiv.textContent = message;
errorDiv.style.display = 'block';
successDiv.style.display = 'none';
// 3秒后自动隐藏
setTimeout(() => {
errorDiv.style.display = 'none';
}, 3000);
}
// 显示成功消息
function showSuccess(message) {
const errorDiv = document.getElementById('errorMessage');
const successDiv = document.getElementById('successMessage');
successDiv.textContent = message;
successDiv.style.display = 'block';
errorDiv.style.display = 'none';
// 3秒后自动隐藏
setTimeout(() => {
successDiv.style.display = 'none';
}, 3000);
}
// 登录表单提交
document.getElementById('loginForm').addEventListener('submit', function(e) {
e.preventDefault();
const username = document.getElementById('username').value.trim();
const password = document.getElementById('password').value;
const remember = document.getElementById('remember').checked;
// 简单的验证
if (!username) {
showError('请输入用户名或邮箱');
return;
}
if (!password) {
showError('请输入密码');
return;
}
if (password.length < 6) {
showError('密码长度不能少于6位');
return;
}
// 实际登录请求
const loginBtn = document.querySelector('.login-btn');
loginBtn.textContent = '登录中...';
loginBtn.disabled = true;
// 准备请求数据
const loginData = {
username: username,
password: password
};
// 调用后端登录API
fetch('http://localhost:8000/api/user/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(loginData)
})
.then(response => {
if (!response.ok) {
// 处理HTTP错误状态码
if (response.status === 500) {
throw new Error('服务器内部错误');
} else if (response.status === 401) {
return response.json().then(data => {
throw new Error(data.msg || '用户名或密码错误');
});
} else if (response.status === 400) {
return response.json().then(data => {
throw new Error(data.msg || '请求参数错误');
});
} else {
throw new Error('网络响应异常');
}
}
return response.json();
})
.then(data => {
// 检查响应状态
if (data.code === 200) {
// 登录成功,存储认证信息
const authData = {
token: data.token,
user_id: data.user_id,
user_info: data.user_info,
loginTime: new Date().toISOString(),
remember: remember
};
// 根据记住我选项选择存储方式
if (remember) {
localStorage.setItem('authData', JSON.stringify(authData));
} else {
sessionStorage.setItem('authData', JSON.stringify(authData));
}
showSuccess('登录成功!正在跳转...');
// 延迟跳转,支持重定向
setTimeout(() => {
// 检查URL中是否有重定向参数
const urlParams = new URLSearchParams(window.location.search);
const redirectUrl = urlParams.get('redirect');
// 如果有重定向URL且是本站URL则跳转到该URL否则跳转到用户中心
if (redirectUrl && (redirectUrl.startsWith('/') || redirectUrl.includes(window.location.hostname))) {
window.location.href = decodeURIComponent(redirectUrl);
} else {
window.location.href = 'user-center.html';
}
}, 1500);
} else {
// 登录失败,显示错误信息
let errorMessage = '登录失败';
// 根据错误码显示不同的错误信息
switch(data.code) {
case 401:
errorMessage = data.msg || '用户名或密码错误';
break;
case 400:
errorMessage = data.msg || '请求参数错误,请检查输入';
break;
case 404:
errorMessage = data.msg || '账号不存在';
break;
case 500:
errorMessage = data.msg || '服务器内部错误,请稍后再试';
break;
default:
errorMessage = data.msg || '登录失败,请检查用户名和密码';
}
showError(errorMessage);
loginBtn.textContent = '登录';
loginBtn.disabled = false;
}
})
.catch(error => {
// 捕获网络或其他错误
console.error('登录请求失败:', error);
// 根据错误信息显示具体的错误提示
let errorMessage = '登录失败,请稍后再试';
if (error.message.includes('账号不存在')) {
errorMessage = '账号不存在,请先注册';
} else if (error.message.includes('密码错误')) {
errorMessage = '密码错误,请重新输入';
} else if (error.message.includes('服务器')) {
errorMessage = '服务器内部错误,请稍后再试';
} else if (error.message.includes('网络')) {
errorMessage = '网络连接异常,请检查您的网络';
} else if (error.message.includes('请求参数')) {
errorMessage = '请求参数错误,请检查输入';
}
showError(errorMessage);
loginBtn.textContent = '登录';
loginBtn.disabled = false;
});
});
// 社交登录
function socialLogin(platform) {
showSuccess(`${platform === 'wechat' ? '微信' : 'QQ'}登录功能开发中...`);
}
// 忘记密码
document.querySelector('.forgot-password').addEventListener('click', function(e) {
e.preventDefault();
showError('密码重置功能开发中...');
});
// 注册链接
document.querySelector('.register-link a').addEventListener('click', function(e) {
e.preventDefault();
window.location.href = 'register.html';
});
// 检查是否已登录
window.addEventListener('load', function() {
const authData = localStorage.getItem('authData') || sessionStorage.getItem('authData');
if (authData) {
const auth = JSON.parse(authData);
showSuccess(`欢迎回来,${auth.user_info.username}`);
// 如果已经登录,可以选择直接跳转
setTimeout(() => {
if (confirm('检测到您已登录,是否跳转到首页?')) {
window.location.href = 'frontend.html';
}
}, 1000);
}
});
// Enter键提交表单
document.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
document.getElementById('loginForm').dispatchEvent(new Event('submit'));
}
});
</script>
</body>
</html>