Files
AIGC/demo/src/main/resources/templates/login.html
AIGC Developer dbd06435cb feat: 完成管理员密码登录修复和项目清理
- 修复BCryptPasswordEncoder密码验证问题
- 实现密码设置提示弹窗功能(仅对无密码用户显示一次)
- 优化修改密码逻辑和验证流程
- 更新Welcome页面背景样式
- 清理临时SQL文件和测试代码
- 移动数据库备份文件到database/backups目录
- 删除不必要的MD文档和临时文件
2025-11-21 16:10:00 +08:00

300 lines
9.6 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用户登录 - AIGC Demo</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<style>
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.login-container {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
padding: 3rem;
width: 100%;
max-width: 450px;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.login-header {
text-align: center;
margin-bottom: 2rem;
}
.login-header h2 {
color: #333;
font-weight: 600;
margin-bottom: 0.5rem;
}
.login-header p {
color: #666;
font-size: 0.9rem;
}
.form-floating {
margin-bottom: 1rem;
}
.form-control {
border: 2px solid #e9ecef;
border-radius: 10px;
padding: 1rem 0.75rem;
font-size: 1rem;
transition: all 0.3s ease;
}
.form-control:focus {
border-color: #667eea;
box-shadow: 0 0 0 0.2rem rgba(102, 126, 234, 0.25);
}
.btn-login {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
border-radius: 10px;
padding: 0.75rem 2rem;
font-weight: 600;
font-size: 1rem;
color: white;
width: 100%;
transition: all 0.3s ease;
margin-bottom: 1rem;
}
.btn-login:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3);
color: white;
}
.form-check-input:checked {
background-color: #667eea;
border-color: #667eea;
}
.alert {
border: none;
border-radius: 10px;
margin-bottom: 1rem;
}
.alert-success {
background: linear-gradient(135deg, #d4edda, #c3e6cb);
color: #155724;
}
.alert-danger {
background: linear-gradient(135deg, #f8d7da, #f5c6cb);
color: #721c24;
}
.login-footer {
text-align: center;
margin-top: 2rem;
padding-top: 1rem;
border-top: 1px solid #e9ecef;
}
.login-footer a {
color: #667eea;
text-decoration: none;
font-weight: 500;
transition: color 0.3s ease;
}
.login-footer a:hover {
color: #764ba2;
}
.language-switcher {
margin-top: 1rem;
}
.language-switcher a {
color: #666;
text-decoration: none;
margin: 0 0.5rem;
font-size: 0.9rem;
}
.language-switcher a:hover {
color: #667eea;
}
.demo-info {
background: rgba(102, 126, 234, 0.1);
border-radius: 10px;
padding: 1rem;
margin-top: 1rem;
font-size: 0.85rem;
color: #666;
}
.loading {
display: none;
}
.loading.show {
display: inline-block;
}
</style>
</head>
<body>
<div class="login-container">
<div class="login-header">
<h2><i class="fas fa-rocket me-2"></i>AIGC Demo</h2>
<p>欢迎回来,请登录您的账户</p>
</div>
<!-- Success Message -->
<div id="msg" class="alert alert-success" style="display: none;"></div>
<!-- Error Message -->
<div th:if="${param.error}" class="alert alert-danger">
<i class="fas fa-exclamation-triangle me-2"></i>
<span th:text="#{msg.login.error}">用户名或密码错误</span>
</div>
<!-- Logout Message -->
<div th:if="${param.logout}" class="alert alert-success">
<i class="fas fa-check-circle me-2"></i>
<span th:text="#{msg.logout.success}">您已退出登录</span>
</div>
<form th:action="@{/login}" method="post" id="loginForm">
<div class="form-floating">
<input type="email" class="form-control" id="email" name="email"
placeholder="邮箱" required autocomplete="email">
<label for="email">
<i class="fas fa-envelope me-2"></i>邮箱
</label>
</div>
<div class="form-floating">
<input type="password" class="form-control" id="password" name="password"
placeholder="密码" required autocomplete="current-password">
<label for="password">
<i class="fas fa-lock me-2"></i>密码
</label>
</div>
<div class="form-check mb-3">
<input type="checkbox" class="form-check-input" id="remember-me" name="remember-me">
<label class="form-check-label" for="remember-me">
<i class="fas fa-clock me-2"></i>记住我
</label>
</div>
<button type="submit" class="btn btn-login" id="loginBtn">
<span class="loading">
<i class="fas fa-spinner fa-spin me-2"></i>登录中...
</span>
<span class="login-text">
<i class="fas fa-sign-in-alt me-2"></i>登录
</span>
</button>
</form>
<div class="login-footer">
<p class="mb-2">
<span th:text="#{hint.noaccount}">还没有账号?</span>
<a th:href="@{/register}">立即注册</a>
</p>
<div class="language-switcher">
<a th:href="@{|?lang=zh_CN|}">中文</a> |
<a th:href="@{|?lang=en|}">English</a>
</div>
<div class="demo-info">
<i class="fas fa-info-circle me-2"></i>
<strong>演示账户:</strong><br>
请使用注册时的邮箱登录<br>
或使用演示邮箱(如已配置)
</div>
</div>
</div>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Show registration success message
function fromQuery(name) {
const url = new URL(window.location.href);
return url.searchParams.get(name);
}
window.addEventListener('DOMContentLoaded', function() {
const registered = fromQuery('registered');
if (registered) {
const msgDiv = document.getElementById('msg');
msgDiv.textContent = '注册成功,请登录';
msgDiv.style.display = 'block';
}
});
// Form submission with loading state
document.getElementById('loginForm').addEventListener('submit', function(e) {
const loginBtn = document.getElementById('loginBtn');
const loading = loginBtn.querySelector('.loading');
const loginText = loginBtn.querySelector('.login-text');
// Show loading state
loading.classList.add('show');
loginText.style.display = 'none';
loginBtn.disabled = true;
});
// Auto-hide alerts after 5 seconds
setTimeout(function() {
const alerts = document.querySelectorAll('.alert');
alerts.forEach(function(alert) {
alert.style.transition = 'opacity 0.5s ease';
alert.style.opacity = '0';
setTimeout(function() {
alert.style.display = 'none';
}, 500);
});
}, 5000);
// Form validation
document.getElementById('loginForm').addEventListener('submit', function(e) {
const email = document.getElementById('email').value.trim();
const password = document.getElementById('password').value.trim();
if (!email || !password) {
e.preventDefault();
alert('请填写邮箱和密码');
return false;
}
// 验证邮箱格式
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
e.preventDefault();
alert('请输入有效的邮箱地址');
return false;
}
});
</script>
</body>
</html>