456 lines
16 KiB
HTML
456 lines
16 KiB
HTML
<!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; }
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', sans-serif;
|
||
display: flex;
|
||
min-height: 100vh;
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
|
||
background-size: 400% 400%;
|
||
animation: gradientShift 15s ease infinite;
|
||
}
|
||
|
||
@keyframes gradientShift {
|
||
0% { background-position: 0% 50%; }
|
||
50% { background-position: 100% 50%; }
|
||
100% { background-position: 0% 50%; }
|
||
}
|
||
|
||
/* ===== 左侧品牌区 ===== */
|
||
.brand-side {
|
||
width: 50%;
|
||
min-width: 420px;
|
||
position: relative;
|
||
background: linear-gradient(155deg, rgba(30,64,175,0.85) 0%, rgba(37,99,235,0.75) 40%, rgba(59,130,246,0.65) 100%);
|
||
backdrop-filter: blur(20px);
|
||
-webkit-backdrop-filter: blur(20px);
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 浮动装饰圆圈 */
|
||
.brand-side::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: -20%; right: -20%;
|
||
width: 80%; height: 80%;
|
||
background: radial-gradient(ellipse, rgba(255,255,255,.2) 0%, transparent 70%);
|
||
animation: float1 8s ease-in-out infinite;
|
||
pointer-events: none;
|
||
}
|
||
.brand-side::after {
|
||
content: '';
|
||
position: absolute;
|
||
bottom: -15%; left: -15%;
|
||
width: 70%; height: 70%;
|
||
background: radial-gradient(ellipse, rgba(147,197,253,.3) 0%, transparent 65%);
|
||
animation: float2 10s ease-in-out infinite;
|
||
pointer-events: none;
|
||
}
|
||
|
||
@keyframes float1 {
|
||
0%, 100% { transform: translate(0, 0) scale(1); }
|
||
50% { transform: translate(-30px, 30px) scale(1.05); }
|
||
}
|
||
@keyframes float2 {
|
||
0%, 100% { transform: translate(0, 0) scale(1); }
|
||
50% { transform: translate(20px, -20px) scale(1.1); }
|
||
}
|
||
|
||
.brand-content {
|
||
position: relative;
|
||
z-index: 1;
|
||
text-align: center;
|
||
padding: 40px;
|
||
animation: fadeInUp 0.8s ease-out;
|
||
}
|
||
|
||
@keyframes fadeInUp {
|
||
from { opacity: 0; transform: translateY(30px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
.logo-wrap {
|
||
width: 100px; height: 100px;
|
||
margin: 0 auto 24px;
|
||
border-radius: 26px;
|
||
overflow: hidden;
|
||
background: rgba(255,255,255,.95);
|
||
padding: 12px;
|
||
box-shadow: 0 12px 40px rgba(0,0,0,.15), 0 0 0 1px rgba(255,255,255,.5) inset;
|
||
animation: logoFloat 3s ease-in-out infinite;
|
||
}
|
||
@keyframes logoFloat {
|
||
0%, 100% { transform: translateY(0); }
|
||
50% { transform: translateY(-8px); }
|
||
}
|
||
.logo-wrap img { width: 100%; height: 100%; object-fit: contain; }
|
||
|
||
.brand-title { font-size: 36px; font-weight: 800; color: #fff; letter-spacing: 4px; text-shadow: 0 4px 20px rgba(0,0,0,.15); }
|
||
.brand-subtitle { font-size: 15px; color: rgba(255,255,255,.88); margin-top: 12px; letter-spacing: 2px; }
|
||
|
||
.feature-list { margin-top: 56px; text-align: left; display: inline-block; }
|
||
.feature-item {
|
||
color: rgba(255,255,255,.9);
|
||
font-size: 15px;
|
||
line-height: 2.6;
|
||
padding-left: 24px;
|
||
position: relative;
|
||
opacity: 0;
|
||
animation: fadeInLeft 0.6s ease-out forwards;
|
||
}
|
||
.feature-item:nth-child(1) { animation-delay: 0.2s; }
|
||
.feature-item:nth-child(2) { animation-delay: 0.4s; }
|
||
.feature-item:nth-child(3) { animation-delay: 0.6s; }
|
||
@keyframes fadeInLeft {
|
||
from { opacity: 0; transform: translateX(-20px); }
|
||
to { opacity: 1; transform: translateX(0); }
|
||
}
|
||
.feature-item::before {
|
||
content: '✓';
|
||
position: absolute;
|
||
left: 0; top: 2px;
|
||
width: 18px; height: 18px;
|
||
border-radius: 50%;
|
||
background: rgba(255,255,255,.25);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 11px;
|
||
font-weight: 700;
|
||
}
|
||
|
||
/* ===== 右侧登录区 ===== */
|
||
.login-side {
|
||
flex: 1;
|
||
min-width: 400px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 40px;
|
||
}
|
||
|
||
.login-card {
|
||
width: 100%;
|
||
max-width: 420px;
|
||
padding: 52px 44px;
|
||
background: rgba(255, 255, 255, 0.95);
|
||
backdrop-filter: blur(20px);
|
||
-webkit-backdrop-filter: blur(20px);
|
||
border-radius: 24px;
|
||
box-shadow: 0 25px 80px rgba(0,0,0,.15), 0 0 0 1px rgba(255,255,255,.5) inset;
|
||
animation: cardFloat 0.8s ease-out;
|
||
}
|
||
@keyframes cardFloat {
|
||
from { opacity: 0; transform: translateY(40px) scale(0.95); }
|
||
to { opacity: 1; transform: translateY(0) scale(1); }
|
||
}
|
||
|
||
/* 标题区 */
|
||
.card-header { margin-bottom: 36px; }
|
||
.card-title {
|
||
font-size: 30px;
|
||
font-weight: 800;
|
||
background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
background-clip: text;
|
||
letter-spacing: 1px;
|
||
}
|
||
.card-desc {
|
||
font-size: 15px;
|
||
color: #64748b;
|
||
margin-top: 10px;
|
||
}
|
||
|
||
/* 表单 */
|
||
.form-group { margin-bottom: 22px; }
|
||
.form-input {
|
||
width: 100%;
|
||
height: 52px;
|
||
border: 2px solid #e2e8f0;
|
||
border-radius: 14px;
|
||
padding: 0 18px;
|
||
font-size: 15px;
|
||
color: #1e293b;
|
||
outline: none;
|
||
transition: all .3s cubic-bezier(0.4, 0, 0.2, 1);
|
||
background: #f8fafc;
|
||
}
|
||
.form-input:focus {
|
||
border-color: #667eea;
|
||
background: #fff;
|
||
box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1);
|
||
transform: translateY(-2px);
|
||
}
|
||
.form-input::placeholder { color: #94a3b8; }
|
||
|
||
/* 密码框 */
|
||
.password-wrap { position: relative; }
|
||
.password-toggle {
|
||
position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
|
||
border: none; background: none; cursor: pointer;
|
||
padding: 6px; color: #64748b; font-size: 18px; line-height: 1;
|
||
transition: all .2s;
|
||
}
|
||
.password-toggle:hover { color: #667eea; transform: translateY(-50%) scale(1.1); }
|
||
|
||
/* 验证码 */
|
||
.captcha-row {
|
||
display: flex;
|
||
gap: 14px;
|
||
align-items: center;
|
||
}
|
||
.captcha-row .form-input { flex: 1; }
|
||
.captcha-img {
|
||
width: 120px; height: 52px;
|
||
border: 2px solid #e2e8f0;
|
||
border-radius: 12px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
cursor: pointer;
|
||
user-select: none;
|
||
font-size: 22px;
|
||
font-weight: 700;
|
||
letter-spacing: 6px;
|
||
transition: all .3s cubic-bezier(0.4, 0, 0.2, 1);
|
||
flex-shrink: 0;
|
||
background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
|
||
}
|
||
.captcha-img:hover {
|
||
border-color: #667eea;
|
||
transform: scale(1.05);
|
||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
|
||
}
|
||
|
||
/* 按钮 */
|
||
.submit-btn {
|
||
width: 100%;
|
||
height: 54px;
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%);
|
||
background-size: 200% 200%;
|
||
color: #fff;
|
||
border: none;
|
||
border-radius: 14px;
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
cursor: pointer;
|
||
transition: all .3s cubic-bezier(0.4, 0, 0.2, 1);
|
||
letter-spacing: 4px;
|
||
box-shadow: 0 8px 24px rgba(102, 126, 234, 0.4);
|
||
}
|
||
.submit-btn:hover {
|
||
background-position: 100% 0;
|
||
transform: translateY(-3px);
|
||
box-shadow: 0 12px 32px rgba(102, 126, 234, 0.5);
|
||
}
|
||
.submit-btn:active { transform: translateY(-1px); }
|
||
|
||
/* 底部辅助行 */
|
||
.form-options {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 28px;
|
||
}
|
||
.remember-me {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
font-size: 14px;
|
||
color: #64748b;
|
||
cursor: pointer;
|
||
user-select: none;
|
||
transition: color .2s;
|
||
}
|
||
.remember-me:hover { color: #475569; }
|
||
.remember-me input { accent-color: #667eea; width: 18px; height: 18px; cursor: pointer; }
|
||
.forgot-link {
|
||
font-size: 14px;
|
||
color: #667eea;
|
||
text-decoration: none;
|
||
font-weight: 500;
|
||
transition: all .2s;
|
||
}
|
||
.forgot-link:hover { color: #764ba2; text-decoration: underline; }
|
||
|
||
/* 底部注册链接 */
|
||
.register-tip {
|
||
text-align: center;
|
||
margin-top: 28px;
|
||
font-size: 14px;
|
||
color: #94a3b8;
|
||
}
|
||
.register-tip a {
|
||
color: #667eea;
|
||
text-decoration: none;
|
||
font-weight: 600;
|
||
transition: all .2s;
|
||
}
|
||
.register-tip a:hover { color: #764ba2; text-decoration: underline; }
|
||
|
||
/* 错误提示 */
|
||
.error-msg {
|
||
font-size: 13px;
|
||
color: #ef4444;
|
||
margin-top: 6px;
|
||
display: none;
|
||
padding-left: 4px;
|
||
animation: shake 0.3s ease-out;
|
||
}
|
||
.error-msg.show { display: block; }
|
||
@keyframes shake {
|
||
0%, 100% { transform: translateX(0); }
|
||
25% { transform: translateX(-4px); }
|
||
75% { transform: translateX(4px); }
|
||
}
|
||
|
||
/* 响应式 */
|
||
@media (max-width: 900px) {
|
||
body { flex-direction: column; }
|
||
.brand-side { min-width: auto; min-height: 240px; width: 100%; }
|
||
.brand-content { padding: 32px; }
|
||
.feature-list { display: none; }
|
||
.login-side { min-width: auto; padding: 24px 16px; }
|
||
.login-card { max-width: 420px; padding: 40px 28px; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- 左侧品牌 -->
|
||
<div class="brand-side">
|
||
<div class="brand-content">
|
||
<div class="logo-wrap">
|
||
<img src="logo.png" alt="Logo">
|
||
</div>
|
||
<h1 class="brand-title">虫虫出海</h1>
|
||
<p class="brand-subtitle">一站式跨境物流服务平台</p>
|
||
|
||
<div class="feature-list">
|
||
<div class="feature-item">安全可靠 · 全程可追踪</div>
|
||
<div class="feature-item">专业团队 · 快速响应</div>
|
||
<div class="feature-item">透明报价 · 无隐藏费用</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右侧登录 -->
|
||
<div class="login-side">
|
||
<div class="login-card">
|
||
<div class="card-header">
|
||
<h2 class="card-title">欢迎回来</h2>
|
||
<p class="card-desc">请登录您的账户以继续</p>
|
||
</div>
|
||
|
||
<form id="loginForm" autocomplete="off">
|
||
<div class="form-group">
|
||
<input type="text" class="form-input" id="loginUsername" placeholder="用户名">
|
||
<div class="error-msg" id="loginUserError">请输入用户名</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<div class="password-wrap">
|
||
<input type="password" class="form-input" id="loginPassword" placeholder="密码">
|
||
<button type="button" class="password-toggle" onclick="togglePassword()">👁</button>
|
||
</div>
|
||
<div class="error-msg" id="loginPassError">请输入密码</div>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<div class="captcha-row">
|
||
<input type="text" class="form-input" id="loginCaptcha" placeholder="验证码" maxlength="4">
|
||
<div class="captcha-img" id="loginCaptchaImg" onclick="refreshCaptcha('login')"></div>
|
||
</div>
|
||
<div class="error-msg" id="loginCaptchaError">验证码错误</div>
|
||
</div>
|
||
|
||
<div class="form-options">
|
||
<label class="remember-me">
|
||
<input type="checkbox"> 记住我
|
||
</label>
|
||
<a href="javascript:void(0)" class="forgot-link">忘记密码?</a>
|
||
</div>
|
||
|
||
<button type="submit" class="submit-btn">登 录</button>
|
||
</form>
|
||
|
||
<div class="register-tip">没有账号?<a href="register.html">立即注册</a></div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// 验证码
|
||
let currentCaptcha = {};
|
||
|
||
function generateCaptcha() {
|
||
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789';
|
||
let c = '';
|
||
for (let i = 0; i < 4; i++) c += chars.charAt(Math.floor(Math.random() * chars.length));
|
||
return c;
|
||
}
|
||
|
||
function refreshCaptcha(type) {
|
||
const c = generateCaptcha();
|
||
currentCaptcha[type] = c;
|
||
const el = document.getElementById(type + 'CaptchaImg');
|
||
if (!el) return;
|
||
el.textContent = c;
|
||
el.style.transform = 'rotate(' + (Math.random() * 8 - 4) + 'deg)';
|
||
el.style.color = ['#2563eb','#3b82f6','#1d4ed8','#1e40af'][Math.floor(Math.random()*4)];
|
||
}
|
||
|
||
refreshCaptcha('login');
|
||
|
||
// 密码显隐
|
||
function togglePassword() {
|
||
const pw = document.getElementById('loginPassword');
|
||
pw.type = pw.type === 'password' ? 'text' : 'password';
|
||
}
|
||
|
||
// 表单提交
|
||
document.getElementById('loginForm').addEventListener('submit', function(e) {
|
||
e.preventDefault();
|
||
|
||
var username = document.getElementById('loginUsername').value.trim();
|
||
var password = document.getElementById('loginPassword').value;
|
||
var captcha = document.getElementById('loginCaptcha').value.trim();
|
||
|
||
document.querySelectorAll('#loginForm .error-msg').forEach(function(el) { el.classList.remove('show'); });
|
||
var hasError = false;
|
||
|
||
if (!username) { document.getElementById('loginUserError').classList.add('show'); hasError = true; }
|
||
if (!password) { document.getElementById('loginPassError').classList.add('show'); hasError = true; }
|
||
if (captcha.toUpperCase() !== currentCaptcha['login'].toUpperCase()) {
|
||
document.getElementById('loginCaptchaError').classList.add('show');
|
||
refreshCaptcha('login');
|
||
hasError = true;
|
||
}
|
||
|
||
if (hasError) return;
|
||
alert('登录成功!欢迎回来,' + username + '!');
|
||
});
|
||
|
||
// 实时清除错误
|
||
document.querySelectorAll('.form-input').forEach(function(input) {
|
||
input.addEventListener('input', function() {
|
||
var group = this.closest('.form-group');
|
||
if (!group) return;
|
||
var err = group.querySelector('.error-msg');
|
||
if (err) err.classList.remove('show');
|
||
});
|
||
});
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|