Files
ai-web/resources/views/admin/auth/login.blade.php

162 lines
6.3 KiB
PHP
Raw Normal View History

2026-02-11 17:28:36 +08:00
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AIWeb 后台登录</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
<style>
body {
min-height: 100vh;
font-family: Inter, "PingFang SC", "Microsoft YaHei", sans-serif;
background:
radial-gradient(700px 400px at 15% 10%, rgba(37, 99, 235, .22), transparent 70%),
radial-gradient(700px 400px at 85% 90%, rgba(124, 58, 237, .18), transparent 70%),
#f1f5f9;
display: grid;
place-items: center;
padding: 1rem;
}
.login-shell {
width: min(980px, 100%);
display: grid;
grid-template-columns: 1.05fr .95fr;
background: #fff;
border-radius: 1rem;
overflow: hidden;
box-shadow: 0 28px 70px rgba(15, 23, 42, .18);
}
.login-cover {
background: linear-gradient(140deg, #0f172a, #1d4ed8 55%, #7c3aed);
color: #fff;
padding: 2.2rem 2rem;
position: relative;
}
.login-cover::after {
content: "";
position: absolute;
width: 260px;
height: 260px;
border-radius: 50%;
right: -70px;
bottom: -60px;
background: rgba(255, 255, 255, .16);
}
.login-form-wrap { padding: 2rem; }
.brand-pill {
width: 2.25rem;
height: 2.25rem;
border-radius: .7rem;
display: inline-flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #2563eb, #7c3aed);
color: #fff;
font-weight: 700;
}
.captcha-box {
min-width: 120px;
height: 44px;
border-radius: .55rem;
border: 1px solid #cbd5e1;
background: #f8fafc;
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
overflow: hidden;
}
@media (max-width: 900px) {
.login-shell { grid-template-columns: 1fr; }
.login-cover { display: none; }
}
</style>
</head>
<body>
<div class="login-shell">
<aside class="login-cover">
<span class="badge rounded-pill text-bg-light text-dark mb-3">安全后台</span>
<h1 class="h3 fw-bold mb-3">AIWeb 内容运营控制台</h1>
<p class="text-white-50">请输入账号、密码与验证码登录。系统内置失败次数限制与验证码轮换机制,降低暴力破解风险。</p>
<div class="mt-4 small text-white-50">
<div class="mb-2"><i class="bi bi-shield-lock me-1"></i> 登录失败限流IP + 账号)</div>
<div class="mb-2"><i class="bi bi-image me-1"></i> 实时验证码校验</div>
<div><i class="bi bi-arrow-repeat me-1"></i> 验证码单次验证后即失效</div>
</div>
</aside>
<main class="login-form-wrap">
<div class="d-flex align-items-center gap-2 mb-4">
<span class="brand-pill">AI</span>
<div>
<div class="fw-semibold">AIWeb Admin</div>
<div class="text-muted small">后台登录</div>
</div>
</div>
@if(session('status'))
<div class="alert alert-success py-2">{{ session('status') }}</div>
@endif
@if($errors->any())
<div class="alert alert-danger py-2">
<ul class="mb-0 small">
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<form method="post" action="{{ route('admin.login.submit') }}" class="row g-3" autocomplete="off">
@csrf
<div class="col-12">
<label class="form-label">后台账号</label>
<input class="form-control" type="text" name="username" value="{{ old('username') }}" required maxlength="100" placeholder="请输入账号">
</div>
<div class="col-12">
<label class="form-label">后台密码</label>
<input class="form-control" type="password" name="password" required maxlength="255" placeholder="请输入密码">
</div>
<div class="col-7">
<label class="form-label">验证码</label>
<input class="form-control" type="text" name="captcha" required maxlength="5" minlength="5" placeholder="输入右侧验证码">
</div>
<div class="col-5">
<label class="form-label">图形验证码</label>
<button class="captcha-box w-100 p-0" id="refreshCaptcha" type="button" aria-label="点击刷新验证码">
<img id="captchaImage" src="{{ route('admin.captcha') }}" alt="验证码" style="width:100%;height:100%;object-fit:cover;">
</button>
</div>
<div class="col-12 d-grid mt-2">
<button class="btn btn-primary btn-lg" type="submit"><i class="bi bi-box-arrow-in-right me-1"></i>登录后台</button>
</div>
</form>
<div class="text-muted small mt-3">若连续输错多次,将被短时间锁定登录。</div>
</main>
</div>
<script>
(function () {
const button = document.getElementById('refreshCaptcha');
const image = document.getElementById('captchaImage');
const reloadCaptcha = () => {
image.src = '{{ route('admin.captcha') }}?t=' + Date.now();
};
button.addEventListener('click', reloadCaptcha);
window.addEventListener('pageshow', function () {
reloadCaptcha();
});
}());
</script>
</body>
</html>