Files
youwei-business-school/有维项目/login.html
2026-04-01 12:02:58 +08:00

606 lines
20 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>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--primary-color: #4F46E5;
--primary-light: #818CF8;
--primary-dark: #3730A3;
--secondary-color: #10B981;
--accent-color: #F59E0B;
--bg-color: #F8FAFC;
--card-bg: #FFFFFF;
--text-primary: #1E293B;
--text-secondary: #64748B;
--border-color: #E2E8F0;
--gradient-1: linear-gradient(135deg, #4F46E5 0%, #7C3AED 100%);
--gradient-2: linear-gradient(135deg, #10B981 0%, #059669 100%);
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background-color: var(--bg-color);
color: var(--text-primary);
line-height: 1.6;
}
/* 登录加载遮罩 */
.login-loading {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: var(--gradient-1);
z-index: 9999;
justify-content: center;
align-items: center;
flex-direction: column;
gap: 24px;
}
.login-loading.active {
display: flex;
}
.loading-spinner {
width: 50px;
height: 50px;
border: 4px solid rgba(255,255,255,0.3);
border-top-color: white;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.loading-text {
color: white;
font-size: 18px;
font-weight: 500;
}
/* 登录页面 */
.login-page {
background: var(--gradient-1);
display: flex;
flex-direction: column;
min-height: 100vh;
}
.login-header {
padding: 20px 40px;
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
display: flex;
align-items: center;
gap: 12px;
color: white;
font-size: 24px;
font-weight: 700;
}
.logo-icon {
width: 44px;
height: 44px;
background: white;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
padding: 4px;
}
.logo-icon img {
width: 100%;
height: 100%;
object-fit: contain;
}
.login-content {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 40px;
gap: 80px;
}
.login-info {
max-width: 500px;
color: white;
}
.login-info h1 {
font-size: 48px;
font-weight: 800;
margin-bottom: 20px;
line-height: 1.2;
}
.login-info p {
font-size: 18px;
opacity: 0.9;
margin-bottom: 40px;
}
.feature-cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
.feature-card {
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(10px);
border-radius: 16px;
padding: 24px;
transition: transform 0.3s, background 0.3s;
}
.feature-card:hover {
transform: translateY(-5px);
background: rgba(255, 255, 255, 0.25);
}
.feature-card-icon {
width: 48px;
height: 48px;
background: white;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 16px;
font-size: 24px;
}
.feature-card h3 {
font-size: 16px;
margin-bottom: 8px;
}
.feature-card p {
font-size: 13px;
opacity: 0.8;
margin: 0;
}
.login-form-container {
background: white;
border-radius: 24px;
padding: 48px;
width: 420px;
box-shadow: var(--shadow-xl);
}
.login-form-container h2 {
font-size: 28px;
margin-bottom: 8px;
color: var(--text-primary);
}
.login-form-container .subtitle {
color: var(--text-secondary);
margin-bottom: 32px;
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
font-weight: 500;
margin-bottom: 8px;
color: var(--text-primary);
}
.form-group input {
width: 100%;
padding: 14px 16px;
border: 2px solid var(--border-color);
border-radius: 12px;
font-size: 15px;
transition: border-color 0.3s, box-shadow 0.3s;
}
.form-group input:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
}
.form-options {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24px;
}
.remember-me {
display: flex;
align-items: center;
gap: 8px;
cursor: pointer;
}
.remember-me input {
width: 18px;
height: 18px;
accent-color: var(--primary-color);
}
.forgot-password {
color: var(--primary-color);
text-decoration: none;
font-weight: 500;
}
.login-btn {
width: 100%;
padding: 16px;
background: var(--gradient-1);
color: white;
border: none;
border-radius: 12px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
}
.login-btn:hover {
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.divider {
display: flex;
align-items: center;
margin: 24px 0;
color: var(--text-secondary);
}
.divider::before,
.divider::after {
content: '';
flex: 1;
height: 1px;
background: var(--border-color);
}
.divider span {
padding: 0 16px;
font-size: 14px;
}
.social-login {
display: flex;
gap: 12px;
}
.social-btn {
flex: 1;
padding: 12px;
border: 2px solid var(--border-color);
border-radius: 12px;
background: white;
cursor: pointer;
transition: border-color 0.3s, background 0.3s;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
font-weight: 500;
}
.social-btn:hover {
border-color: var(--primary-color);
background: #F8FAFC;
}
.register-link {
text-align: center;
margin-top: 24px;
color: var(--text-secondary);
}
.register-link a {
color: var(--primary-color);
text-decoration: none;
font-weight: 600;
}
/* 响应式设计 */
@media (max-width: 1024px) {
.login-content {
flex-direction: column;
gap: 40px;
padding: 20px;
}
.login-info {
text-align: center;
}
.login-info h1 {
font-size: 36px;
}
.feature-cards {
display: none;
}
.login-form-container {
width: 100%;
max-width: 420px;
}
}
</style>
</head>
<body>
<!-- 登录加载遮罩 -->
<div class="login-loading" id="loginLoading">
<div class="loading-spinner"></div>
<div class="loading-text">正在登录,请稍候...</div>
</div>
<!-- 登录页面 -->
<div class="login-page">
<div class="login-header">
<div class="logo">
<div class="logo-icon"><img src="LatestLogo.png" alt="有维商学"></div>
有维商学
</div>
</div>
<div class="login-content">
<div class="login-info">
<h1>OPC创业者<br>赋能平台</h1>
<p>基于"有维教育+AI工具+有维校友"三位一体的商业模式为OPC创业者提供全方位的成长支持</p>
<div class="feature-cards">
<div class="feature-card">
<div class="feature-card-icon">📚</div>
<h3>有维教育</h3>
<p>系统化商业课程,知行合一</p>
</div>
<div class="feature-card">
<div class="feature-card-icon">🤖</div>
<h3>AI工具</h3>
<p>智能体赋能,数字员工</p>
</div>
<div class="feature-card">
<div class="feature-card-icon">👥</div>
<h3>有维校友</h3>
<p>创业者社群,互助共赢</p>
</div>
</div>
</div>
<div class="login-form-container">
<h2 id="formTitle">欢迎回来</h2>
<p class="subtitle" id="formSubtitle">登录您的有维商学账户</p>
<form id="loginForm" onsubmit="handleLogin(event)">
<div class="form-group">
<label>邮箱</label>
<input type="email" id="loginEmail" placeholder="请输入邮箱" required>
</div>
<div class="form-group">
<label>密码</label>
<input type="password" id="loginPassword" placeholder="请输入密码" required>
</div>
<div class="form-options">
<label class="remember-me">
<input type="checkbox" id="rememberMe">
<span>记住我</span>
</label>
<a href="#" class="forgot-password">忘记密码?</a>
</div>
<button type="submit" class="login-btn">登 录</button>
</form>
<form id="registerForm" onsubmit="handleRegister(event)" style="display: none;">
<div class="form-group">
<label>邮箱</label>
<input type="email" id="registerEmail" placeholder="请输入邮箱" required>
</div>
<div class="form-group">
<label>密码</label>
<input type="password" id="registerPassword" placeholder="请输入密码至少6位" required>
</div>
<div class="form-group">
<label>确认密码</label>
<input type="password" id="registerConfirmPassword" placeholder="请再次输入密码" required>
</div>
<button type="submit" class="login-btn">注 册</button>
</form>
<div class="divider"><span>或使用以下方式登录</span></div>
<div class="social-login">
<button class="social-btn">💬 微信</button>
<button class="social-btn">📱 手机验证码</button>
</div>
<p class="register-link" id="switchToRegisterText">
还没有账户?<a href="#" onclick="switchToRegister(event)">立即注册</a>
</p>
<p class="register-link" id="switchToLoginText" style="display: none;">
已有账户?<a href="#" onclick="switchToLogin(event)">返回登录</a>
</p>
</div>
</div>
</div>
<script>
const API_BASE_URL = 'http://localhost:3010/api';
const REGISTER_API_URL = '/api/passport/web/email/register/v2/';
// 页面加载时检查是否已登录
document.addEventListener('DOMContentLoaded', function() {
const savedUser = localStorage.getItem('currentUser') || sessionStorage.getItem('currentUser');
if (savedUser) {
// 已登录,直接跳转到首页
window.location.href = 'index.html';
}
});
function switchToRegister(event) {
event.preventDefault();
document.getElementById('formTitle').textContent = '创建账户';
document.getElementById('formSubtitle').textContent = '仅需邮箱和密码即可注册';
document.getElementById('loginForm').style.display = 'none';
document.getElementById('registerForm').style.display = 'block';
document.getElementById('switchToRegisterText').style.display = 'none';
document.getElementById('switchToLoginText').style.display = 'block';
}
function switchToLogin(event) {
if (event) {
event.preventDefault();
}
document.getElementById('formTitle').textContent = '欢迎回来';
document.getElementById('formSubtitle').textContent = '登录您的有维商学账户';
document.getElementById('loginForm').style.display = 'block';
document.getElementById('registerForm').style.display = 'none';
document.getElementById('switchToRegisterText').style.display = 'block';
document.getElementById('switchToLoginText').style.display = 'none';
}
function showLoading(isLoading, text) {
const loadingNode = document.getElementById('loginLoading');
const textNode = document.querySelector('#loginLoading .loading-text');
if (text) {
textNode.textContent = text;
}
loadingNode.classList.toggle('active', isLoading);
}
async function handleRegister(event) {
event.preventDefault();
const email = document.getElementById('registerEmail').value.trim();
const password = document.getElementById('registerPassword').value.trim();
const confirmPassword = document.getElementById('registerConfirmPassword').value.trim();
if (!email || !password || !confirmPassword) {
alert('请填写邮箱、密码和确认密码');
return;
}
if (password !== confirmPassword) {
alert('两次输入的密码不一致');
return;
}
showLoading(true, '正在注册,请稍候...');
try {
const parseJsonSafe = async (res) => {
try {
return await res.json();
} catch (_error) {
return {};
}
};
let response = await fetch(REGISTER_API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password })
});
let result = await parseJsonSafe(response);
// Local development fallback when deployed register API is unavailable
// or returns unsupported status (404/405, etc.).
if (!response.ok) {
response = await fetch(`${API_BASE_URL}/register`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password, confirmPassword })
});
result = await parseJsonSafe(response);
}
if (!response.ok) {
throw new Error(result.message || '注册失败');
}
alert('注册成功,请登录');
document.getElementById('loginEmail').value = email;
document.getElementById('registerPassword').value = '';
document.getElementById('registerConfirmPassword').value = '';
switchToLogin();
} catch (error) {
alert(error.message || '注册失败,请稍后重试');
} finally {
showLoading(false);
}
}
// 登录处理
async function handleLogin(event) {
event.preventDefault();
const email = document.getElementById('loginEmail').value.trim();
const password = document.getElementById('loginPassword').value.trim();
const rememberMe = document.getElementById('rememberMe').checked;
if (!email || !password) {
alert('请输入邮箱和密码');
return;
}
showLoading(true, '正在登录,请稍候...');
try {
const response = await fetch(`${API_BASE_URL}/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password })
});
const result = await response.json();
if (!response.ok) {
throw new Error(result.message || '登录失败');
}
const userEmail = result?.user?.email || email;
if (rememberMe) {
localStorage.setItem('currentUser', userEmail);
sessionStorage.removeItem('currentUser');
} else {
sessionStorage.setItem('currentUser', userEmail);
localStorage.removeItem('currentUser');
}
window.location.href = 'index.html';
} catch (error) {
alert(error.message || '登录失败,请稍后重试');
showLoading(false);
}
}
</script>
</body>
</html>