邮件API

This commit is contained in:
2025-11-16 19:58:51 +08:00
parent 9d442b017a
commit 3b3d6dea66
91 changed files with 6017 additions and 413 deletions

View File

@@ -38,71 +38,31 @@
}
.bg-glass {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
background: rgba(255, 255, 255, 0.08);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
}
.bg-glass-hover {
background: rgba(255, 255, 255, 0.12);
transition: background 0.3s ease;
}
.text-shadow {
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}
.cube {
transform-style: preserve-3d;
animation: rotate 15s infinite linear;
}
.float {
animation: float 6s ease-in-out infinite;
}
.pulse {
animation: pulse 4s infinite;
text-shadow: 0 2px 15px rgba(0, 0, 0, 0.3);
}
.modal-backdrop {
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
}
}
/* 动画定义 */
@keyframes rotate {
0% {
transform: rotateX(0deg) rotateY(0deg);
}
100% {
transform: rotateX(360deg) rotateY(360deg);
}
}
@keyframes float {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-20px);
}
100% {
transform: translateY(0px);
}
}
@keyframes pulse {
0% {
opacity: 0.6;
transform: scale(1);
}
50% {
opacity: 1;
transform: scale(1.05);
}
100% {
opacity: 0.6;
transform: scale(1);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
}
.input-focus-ring {
box-shadow: 0 0 0 2px rgba(255, 209, 102, 0.4);
}
}
/* 动画优化 */
@keyframes fadeIn {
from {
opacity: 0;
@@ -125,12 +85,16 @@
}
}
.geo-element {
position: absolute;
border-radius: 8px;
background: rgba(59, 130, 246, 0.15);
backdrop-filter: blur(5px);
border: 1px solid rgba(255, 255, 255, 0.1);
@keyframes float {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-8px);
}
100% {
transform: translateY(0px);
}
}
.error-modal {
@@ -140,31 +104,33 @@
.error-modal.hide {
animation: fadeOut 0.3s ease-in forwards;
}
.feature-card {
animation: float 4s ease-in-out infinite;
}
.feature-card:nth-child(2) {
animation-delay: 1s;
}
.feature-card:nth-child(3) {
animation-delay: 2s;
}
</style>
</head>
<body class="font-inter min-h-screen flex items-center justify-center p-4 md:p-0 overflow-hidden">
<!-- 背景和装饰元素 -->
<body class="font-inter min-h-screen flex items-center justify-center p-4 md:p-0 overflow-x-hidden">
<!-- 背景优化 - 增加渐变叠加层让背景图更协调 -->
<div class="fixed inset-0 bg-gradient-tech z-0"></div>
<div class="geo-element w-32 h-32 top-1/4 left-1/6 float" style="animation-delay: 0s;"></div>
<div class="geo-element w-16 h-16 bottom-1/3 right-1/5 float" style="animation-delay: 1s;"></div>
<div class="geo-element w-24 h-24 top-2/3 left-1/4 float" style="animation-delay: 2s;"></div>
<div class="geo-element w-20 h-20 bottom-1/4 right-1/3 float" style="animation-delay: 1.5s;"></div>
<div class="fixed inset-0 z-0 opacity-30">
<div class="absolute inset-0"
style="background-image: radial-gradient(rgba(255,255,255,0.3) 1px, transparent 1px); background-size: 30px 30px;"></div>
</div>
<div class="fixed top-1/3 right-1/4 w-32 h-32 cube z-0">
<div class="absolute inset-0 bg-primary/20 rounded-lg transform rotate-x-0 rotate-y-0"></div>
<div class="absolute inset-0 bg-accent/20 rounded-lg transform rotate-x-90 rotate-y-0"></div>
<div class="absolute inset-0 bg-secondary/20 rounded-lg transform rotate-x-0 rotate-y-90"></div>
<!-- 科技感装饰元素 -->
<div class="fixed inset-0 z-0 overflow-hidden opacity-20">
<div class="absolute top-1/4 left-1/4 w-96 h-96 rounded-full bg-primary/30 blur-3xl"></div>
<div class="absolute bottom-1/4 right-1/4 w-80 h-80 rounded-full bg-accent/20 blur-3xl"></div>
</div>
<!-- 错误提示弹窗 (默认隐藏) -->
<div id="errorModal" class="fixed inset-0 z-50 flex items-center justify-center hidden">
<!-- 遮罩层 -->
<div class="absolute inset-0 bg-darkBlue/70 modal-backdrop" id="modalBackdrop"></div>
<!-- 弹窗内容 -->
<div class="relative bg-white/10 backdrop-blur-xl border border-white/20 rounded-xl p-6 w-full max-w-md shadow-2xl error-modal">
<div class="absolute inset-0 bg-darkBlue/80 modal-backdrop" id="modalBackdrop"></div>
<div class="relative bg-white/15 backdrop-blur-xl border border-white/25 rounded-xl p-6 w-full max-w-md shadow-2xl error-modal transform transition-all">
<div class="text-center mb-4">
<div class="w-16 h-16 mx-auto bg-red-500/20 rounded-full flex items-center justify-center mb-4">
<i class="fa fa-exclamation-triangle text-red-400 text-2xl"></i>
@@ -173,27 +139,28 @@
<p class="text-white/80" id="modalErrorMessage">账号或密码错误,请重新输入</p>
</div>
<button id="closeModal"
class="w-full mt-4 bg-accent hover:bg-accent/90 text-darkBlue font-medium py-2.5 px-4 rounded-lg transition-all duration-300">
class="w-full mt-4 bg-accent hover:bg-accent/90 text-darkBlue font-medium py-2.5 px-4 rounded-lg transition-all duration-300 shadow-lg shadow-accent/20 hover:shadow-accent/30">
确定
</button>
</div>
</div>
<!-- 登录卡片 -->
<div class="relative w-full max-w-5xl bg-white/10 backdrop-blur-xl rounded-2xl shadow-2xl overflow-hidden flex flex-col md:flex-row z-10 border border-white/20">
<!-- 左侧品牌区域 -->
<div class="p-6 md:p-10 lg:p-12 flex-1 flex flex-col justify-between relative">
<div class="absolute -top-10 -left-10 w-40 h-40 bg-accent/10 rounded-full blur-3xl"></div>
<div class="absolute -bottom-20 -right-10 w-60 h-60 bg-primary/20 rounded-full blur-3xl"></div>
<div class="relative">
<p class="text-white/80 text-base md:text-lg max-w-md">
一站式智能管理平台,融合前沿技术,为您提供高效、安全、便捷的服务体验
<!-- 登录卡片 - 科技感背景图(协调不突兀) -->
<div class="relative w-full max-w-5xl bg-white/10 backdrop-blur-xl rounded-2xl shadow-2xl overflow-hidden flex flex-col md:flex-row z-10 border border-white/20"
style="background-image: url('images/login-brand.png'); background-size: cover; background-position: center; background-blend-mode: overlay;">
<!-- 左侧品牌区域 - 半透明遮罩提升可读性 -->
<div class="p-6 md:p-10 lg:p-12 flex-1 flex flex-col justify-between bg-darkBlue/40 backdrop-blur-sm">
<div>
<h2 class="text-[clamp(1.8rem,4vw,2.5rem)] font-bold text-white text-shadow mb-6">智慧门户</h2>
<p class="text-white/90 text-base md:text-lg max-w-md leading-relaxed">
一站式智能管理平台,融合前沿技术,为您提供高效、安全、便捷的服务体验
助力数字化转型,创造更大价值
</p>
</div>
<div class="mt-10 md:mt-20 space-y-6 relative">
<div class="bg-glass p-4 rounded-xl border border-white/10 hover:border-white/30 transition-all duration-300 transform hover:-translate-y-1">
<div class="mt-10 md:mt-20 space-y-6">
<div class="bg-glass bg-glass-hover p-5 rounded-xl border border-white/10 hover:border-white/30 transition-all duration-300 feature-card">
<div class="flex items-center space-x-4">
<div class="w-12 h-12 rounded-full bg-accent/20 flex items-center justify-center text-accent pulse">
<div class="w-12 h-12 rounded-full bg-accent/20 flex items-center justify-center text-accent">
<i class="fa fa-shield text-xl"></i>
</div>
<div>
@@ -202,9 +169,9 @@
</div>
</div>
</div>
<div class="bg-glass p-4 rounded-xl border border-white/10 hover:border-white/30 transition-all duration-300 transform hover:-translate-y-1">
<div class="bg-glass bg-glass-hover p-5 rounded-xl border border-white/10 hover:border-white/30 transition-all duration-300 feature-card">
<div class="flex items-center space-x-4">
<div class="w-12 h-12 rounded-full bg-secondary/20 flex items-center justify-center text-secondary pulse">
<div class="w-12 h-12 rounded-full bg-secondary/20 flex items-center justify-center text-secondary">
<i class="fa fa-bolt text-xl"></i>
</div>
<div>
@@ -213,9 +180,9 @@
</div>
</div>
</div>
<div class="bg-glass p-4 rounded-xl border border-white/10 hover:border-white/30 transition-all duration-300 transform hover:-translate-y-1">
<div class="bg-glass bg-glass-hover p-5 rounded-xl border border-white/10 hover:border-white/30 transition-all duration-300 feature-card">
<div class="flex items-center space-x-4">
<div class="w-12 h-12 rounded-full bg-primary/20 flex items-center justify-center text-primary pulse">
<div class="w-12 h-12 rounded-full bg-primary/20 flex items-center justify-center text-primary">
<i class="fa fa-cubes text-xl"></i>
</div>
<div>
@@ -225,20 +192,17 @@
</div>
</div>
</div>
<div class="mt-10 md:mt-16 text-center md:text-left text-white/60 text-sm relative">
<p>&copy; 2023 智慧门户 版权所有</p>
<div class="mt-10 md:mt-16 text-center md:text-left text-white/60 text-sm">
<p>&copy; 2025 智慧门户 版权所有</p>
</div>
</div>
<!-- 右侧登录表单区域 -->
<div class="flex-1 p-6 md:p-10 lg:p-12 bg-white/10 backdrop-blur-xl border-l border-white/20 flex flex-col justify-center">
<!-- 右侧登录表单区域 - 增强遮罩确保表单清晰 -->
<div class="flex-1 p-6 md:p-10 lg:p-12 bg-darkBlue/60 backdrop-blur-xl border-l border-white/20 flex flex-col justify-center">
<div class="max-w-md mx-auto w-full">
<div class="text-center md:text-left mb-10 relative">
<div class="absolute top-0 right-0 md:right-0">
<img th:src="@{/images/login-brand.png}" alt="logo">
</div>
<h1 class="text-[clamp(2rem,5vw,3rem)] font-bold mb-4 text-white text-shadow">智慧门户</h1>
<p class="text-white/70">欢迎登录系统</p>
<div class="text-center md:text-left mb-10">
<h1 class="text-[clamp(2rem,5vw,3rem)] font-bold mb-4 text-white text-shadow">账户登录</h1>
<p class="text-white/70">欢迎回来,请输入您的账号信息</p>
</div>
<form id="loginForm" class="space-y-6">
@@ -250,7 +214,7 @@
<i class="fa fa-user text-white/50"></i>
</div>
<input type="text" id="username" name="username"
class="block w-full pl-12 pr-4 py-3 bg-white/10 border border-white/20 rounded-lg focus:ring-2 focus:ring-accent/50 focus:border-accent text-white placeholder-white/40 transition-all duration-300 outline-none"
class="block w-full pl-12 pr-4 py-3 bg-white/10 border border-white/20 rounded-lg focus:border-accent focus:input-focus-ring text-white placeholder-white/40 transition-all duration-300 outline-none"
placeholder="请输入账号" required>
</div>
</div>
@@ -259,14 +223,13 @@
<div class="space-y-3">
<div class="flex items-center justify-between">
<label for="password" class="block text-sm font-medium text-white/80">密码</label>
<a href="#" class="text-sm text-accent hover:text-accent/80 transition-colors">忘记密码?</a>
</div>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
<i class="fa fa-lock text-white/50"></i>
</div>
<input type="password" id="password" name="password"
class="block w-full pl-12 pr-12 py-3 bg-white/10 border border-white/20 rounded-lg focus:ring-2 focus:ring-accent/50 focus:border-accent text-white placeholder-white/40 transition-all duration-300 outline-none"
class="block w-full pl-12 pr-12 py-3 bg-white/10 border border-white/20 rounded-lg focus:border-accent focus:input-focus-ring text-white placeholder-white/40 transition-all duration-300 outline-none"
placeholder="请输入密码" required>
<button type="button" id="togglePassword"
class="absolute inset-y-0 right-0 pr-4 flex items-center text-white/50 hover:text-white transition-colors">
@@ -286,7 +249,7 @@
<!-- 登录按钮 -->
<button type="submit"
class="w-full bg-accent hover:bg-accent/90 text-darkBlue font-medium py-3 px-4 rounded-lg transition-all duration-300 transform hover:scale-[1.02] active:scale-[0.98] focus:outline-none focus:ring-2 focus:ring-accent/50 focus:ring-offset-2 focus:ring-offset-white/10">
class="w-full bg-accent hover:bg-accent/90 text-darkBlue font-medium py-3 px-4 rounded-lg transition-all duration-300 focus:outline-none focus:ring-2 focus:ring-accent/50 focus:ring-offset-2 focus:ring-offset-white/10 shadow-lg shadow-accent/20 hover:shadow-accent/30 transform hover:-translate-y-0.5 active:translate-y-0">
登录
</button>
</form>
@@ -295,6 +258,13 @@
</div>
<script>
if (window.self !== window.top) {
// 跳转到顶层窗口,强制取消嵌套
window.top.location.href = window.self.location.href;
}
// 密码显示/隐藏切换
const togglePassword = document.getElementById('togglePassword');
const password = document.getElementById('password');
@@ -302,13 +272,8 @@
const type = password.getAttribute('type') === 'password' ? 'text' : 'password';
password.setAttribute('type', type);
const icon = togglePassword.querySelector('i');
if (type === 'password') {
icon.classList.remove('fa-eye');
icon.classList.add('fa-eye-slash');
} else {
icon.classList.remove('fa-eye-slash');
icon.classList.add('fa-eye');
}
icon.classList.toggle('fa-eye');
icon.classList.toggle('fa-eye-slash');
});
// 错误弹窗相关元素
@@ -321,25 +286,23 @@
function showErrorModal(message = '账号或密码错误,请重新输入') {
modalErrorMessage.textContent = message;
errorModal.classList.remove('hidden');
// 阻止页面滚动
document.body.style.overflow = 'hidden';
}
// 隐藏错误弹窗
function hideErrorModal() {
errorModal.querySelector('.error-modal').classList.add('hide');
const modal = errorModal.querySelector('.error-modal');
modal.classList.add('hide');
setTimeout(() => {
errorModal.classList.add('hidden');
errorModal.querySelector('.error-modal').classList.remove('hide');
// 恢复页面滚动
modal.classList.remove('hide');
document.body.style.overflow = '';
}, 300);
}
// 关闭弹窗事件
// 关闭弹窗事件绑定
closeModal.addEventListener('click', hideErrorModal);
modalBackdrop.addEventListener('click', hideErrorModal);
// 按ESC键关闭弹窗
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && !errorModal.classList.contains('hidden')) {
hideErrorModal();
@@ -352,10 +315,16 @@
e.preventDefault();
// 获取表单数据
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const username = document.getElementById('username').value.trim();
const password = document.getElementById('password').value.trim();
const remember = document.getElementById('remember').checked;
// 简单表单验证
if (!username || !password) {
showErrorModal('账号和密码不能为空');
return;
}
// 模拟登录加载状态
const submitButton = loginForm.querySelector('button[type="submit"]');
const originalText = submitButton.innerHTML;
@@ -363,34 +332,29 @@
submitButton.innerHTML = '<i class="fa fa-spinner fa-spin mr-2"></i> 登录中...';
try {
// 发送登录请求到后端
const response = await fetch('userLogin', { // 替换为实际后端登录接口
// 发送登录请求到后端(替换为实际接口地址)
const response = await fetch('biz/userLogin', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username,
password,
remember
}),
body: JSON.stringify({username, password, remember}),
credentials: 'include'
});
const result = await response.json();
console.log(result)
if (response.ok && result.success) {
// 登录成功,跳转到首页
window.location.href = '/index'; // 替换为实际首页路径
// 登录成功,跳转到首页(替换为实际首页路径)
window.location.href = 'biz/index';
} else {
// 登录失败,显示错误弹窗
const errorMsg = result.message || '账号或密码错误,请重新输入';
showErrorModal(errorMsg);
// 登录失败,显示错误信息
showErrorModal(result.message || '账号或密码错误,请重新输入');
}
} catch (error) {
// 网络错误等异常情况
// 网络错误处理
console.error('登录请求失败:', error);
showErrorModal('网络异常,请后重试');
showErrorModal('网络异常,请检查网络连接后重试');
} finally {
// 恢复按钮状态
submitButton.disabled = false;
@@ -398,11 +362,11 @@
}
});
// 输入框交互效果
// 输入框交互优化(聚焦时轻微上浮效果
const inputs = document.querySelectorAll('input');
inputs.forEach(input => {
input.addEventListener('focus', () => {
input.parentElement.classList.add('scale-[1.02]');
input.parentElement.classList.add('scale-[1.02]', 'transition-transform', 'duration-300');
});
input.addEventListener('blur', () => {
input.parentElement.classList.remove('scale-[1.02]');