Files
NetworkAuth/web/template/admin/login.html
2026-03-18 21:51:17 +08:00

280 lines
9.7 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.
{{/* 管理员登录页面模板使用layui构建的登录界面 */}}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{{ .Title }}</title>
<!-- 站点图标 -->
<link rel="icon" type="image/svg+xml" href="/assets/favicon.svg" />
<link rel="shortcut icon" href="/favicon.ico" />
<link href="/static/lib/layui/css/layui.css" rel="stylesheet">
<style>
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
margin: 0;
padding: 0;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.demo-login-container {
width: 400px;
margin: 21px auto 0;
background: #fff;
border-radius: 8px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
overflow: hidden;
}
.login-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 30px 20px;
text-align: center;
color: #fff;
}
.login-header h1 {
margin: 0;
font-size: 24px;
font-weight: 300;
}
.login-header p {
margin: 8px 0 0;
opacity: 0.8;
font-size: 14px;
}
.login-form {
padding: 30px 20px;
}
/* 调整表单项间距 */
.login-form .layui-form-item {
margin-bottom: 20px;
}
/* 最后一个表单项不需要底部边距 */
.login-form .layui-form-item:last-child {
margin-bottom: 0;
}
.demo-login-other .layui-icon {
position: relative;
display: inline-block;
margin: 0 2px;
top: 2px;
font-size: 26px;
}
.login-footer {
text-align: center;
padding: 20px;
color: #999;
font-size: 12px;
border-top: 1px solid #f0f0f0;
}
/* 响应式设计 - 移动端适配 */
@media (max-width: 768px) {
.demo-login-container {
width: 90%;
margin: 10px auto;
border-radius: 4px;
}
.login-header {
padding: 25px 15px;
}
.login-header h1 {
font-size: 20px;
}
.login-form {
padding: 25px 15px;
}
/* 移动端表单项间距调整 */
.login-form .layui-form-item {
margin-bottom: 18px;
}
}
@media (max-width: 480px) {
.demo-login-container {
width: 95%;
margin: 5px auto;
border-radius: 0;
min-height: calc(100vh - 10px);
display: flex;
flex-direction: column;
}
.login-header {
padding: 20px 15px;
}
.login-header h1 {
font-size: 18px;
}
.login-form {
padding: 20px 15px;
}
/* 小屏幕表单项间距调整 */
.login-form .layui-form-item {
margin-bottom: 16px;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
}
}
</style>
</head>
<body>
<form class="layui-form">
<div class="demo-login-container">
<div class="login-header">
<h1>{{ .SystemName }}</h1>
<p>管理员登录</p>
</div>
<div class="login-form">
<!-- CSRF令牌隐藏字段 -->
<input type="hidden" name="csrf_token" value="{{ .CSRFToken }}" id="csrf-token">
<div class="layui-form-item">
<div class="layui-input-wrap">
<div class="layui-input-prefix">
<i class="layui-icon layui-icon-username"></i>
</div>
<input type="text" name="username" value="" lay-verify="required" placeholder="用户名"
lay-reqtext="请填写用户名" autocomplete="off" class="layui-input" lay-affix="clear">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-wrap">
<div class="layui-input-prefix">
<i class="layui-icon layui-icon-password"></i>
</div>
<input type="password" name="password" value="" lay-verify="required" placeholder="密 码"
lay-reqtext="请填写密码" autocomplete="off" class="layui-input" lay-affix="eye">
</div>
</div>
<div class="layui-form-item">
<div class="layui-row">
<div class="layui-col-xs7">
<div class="layui-input-wrap">
<div class="layui-input-prefix">
<i class="layui-icon layui-icon-vercode"></i>
</div>
<input type="text" name="captcha" value="" lay-verify="required" placeholder="验证码"
lay-reqtext="请填写验证码" autocomplete="off" class="layui-input" lay-affix="clear">
</div>
</div>
<div class="layui-col-xs5">
<div style="margin-left: 5px; text-align: right;">
<img id="captcha-img" src="/admin/captcha"
onclick="this.src='/admin/captcha?t='+ new Date().getTime();"
style="cursor: pointer; height: 38px; border-radius: 4px; width: 100%;"
title="点击刷新验证码">
</div>
</div>
</div>
</div>
<div class="layui-form-item">
<button class="layui-btn layui-btn-fluid" lay-submit lay-filter="demo-login">立即登录</button>
</div>
</div>
<div class="login-footer">
<p>{{ .FooterText }}</p>
</div>
</div>
</form>
<script src="/static/lib/layui/layui.js"></script>
<script>
layui.use(function () {
var form = layui.form;
var layer = layui.layer;
// 登录提交回调:向 /admin/login 发送请求,并依据 code===0 判断成功与否
form.on('submit(demo-login)', function (data) {
var loadIndex = layer.msg('登录中...', {
icon: 16,
shade: 0.01,
time: 0
});
// 获取CSRF令牌
var csrfToken = document.getElementById('csrf-token').value;
// 发送登录请求
fetch('/admin/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken
},
body: JSON.stringify(data.field)
})
.then(response => response.text())
.then(text => {
try {
return JSON.parse(text);
} catch (e) {
console.error('Non-JSON response:', text);
throw new Error('服务器响应格式错误');
}
})
.then(result => {
layer.close(loadIndex);
// 根据统一接口code === 0 表示成功
const isOk = result && result.code === 0;
if (isOk) {
layer.msg('登录成功', {
icon: 1,
time: 1500
}, function () {
const redirect = (result.data && result.data.redirect) || '/admin';
window.location.href = redirect;
});
} else {
const msg = (result && (result.msg || result.message)) || '登录失败,请检查用户名和密码';
layer.msg(msg, { icon: 2 });
// 登录失败时刷新验证码
document.getElementById('captcha-img').src = '/admin/captcha?t=' + new Date().getTime();
}
})
.catch(error => {
layer.close(loadIndex);
console.error('登录错误:', error);
var msg = error.message || '网络错误,请稍后重试';
layer.msg(msg, { icon: 2 });
// 网络错误时也刷新验证码
document.getElementById('captcha-img').src = '/admin/captcha?t=' + new Date().getTime();
});
return false; // 阻止表单跳转
});
});
</script>
</body>
</html>