first commit

This commit is contained in:
闫旭隆
2025-10-17 09:31:28 +08:00
commit 4698145045
589 changed files with 196795 additions and 0 deletions

View File

@ -0,0 +1,231 @@
/* 认证表单专用样式 */
.auth-container {
animation: slideInUp 0.6s ease-out;
}
.auth-form-wrapper {
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(20px);
box-shadow:
0 20px 25px -5px rgba(0, 0, 0, 0.1),
0 10px 10px -5px rgba(0, 0, 0, 0.04),
inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
.form-group {
position: relative;
}
.form-group input {
transition: all 0.3s ease;
}
.form-group input:focus {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(37, 99, 235, 0.15);
}
.form-group input:valid {
border-color: #10b981;
}
.form-group input.error {
border-color: #ef4444;
background-color: rgba(239, 68, 68, 0.05);
}
.error-message {
animation: slideDown 0.3s ease-out;
font-size: 0.875rem;
}
.error-message.show {
display: block !important;
}
/* 发送验证码按钮状态 */
#sendCodeBtn:disabled {
background-color: #9ca3af;
cursor: not-allowed;
}
#sendCodeBtn.countdown {
background-color: #6b7280;
}
/* 登录/注册按钮动画 */
#loginBtn, #registerBtn {
position: relative;
overflow: hidden;
transform: translateZ(0);
}
#loginBtn:hover, #registerBtn:hover {
transform: translateY(-1px);
box-shadow: 0 10px 20px rgba(37, 99, 235, 0.3);
}
#loginBtn:active, #registerBtn:active {
transform: translateY(0);
}
/* 状态消息样式 */
#statusMessage {
border-left: 4px solid currentColor;
animation: slideInLeft 0.4s ease-out;
}
#statusMessage.success {
background-color: rgba(16, 185, 129, 0.1);
color: #059669;
border-color: #10b981;
}
#statusMessage.error {
background-color: rgba(239, 68, 68, 0.1);
color: #dc2626;
border-color: #ef4444;
}
#statusMessage.info {
background-color: rgba(59, 130, 246, 0.1);
color: #2563eb;
border-color: #3b82f6;
}
#statusMessage.warning {
background-color: rgba(245, 158, 11, 0.1);
color: #d97706;
border-color: #f59e0b;
}
/* 动画定义 */
@keyframes slideInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
max-height: 0;
}
to {
opacity: 1;
transform: translateY(0);
max-height: 50px;
}
}
@keyframes slideInLeft {
from {
opacity: 0;
transform: translateX(-20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
/* 输入框聚焦效果 */
.form-group label {
transition: all 0.3s ease;
}
.form-group input:focus + .absolute i {
color: #2563eb;
transform: scale(1.1);
}
/* 响应式设计 */
@media (max-width: 640px) {
.auth-form-wrapper {
margin: 1rem;
padding: 1.5rem;
}
.form-group {
margin-bottom: 1rem;
}
#sendCodeBtn {
padding: 0.75rem 1rem;
font-size: 0.875rem;
}
}
/* 加载状态 */
.loading {
position: relative;
pointer-events: none;
}
.loading::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 20px;
height: 20px;
margin: -10px 0 0 -10px;
border: 2px solid #ffffff;
border-top: 2px solid transparent;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* 表单验证提示 */
.form-group .valid-feedback {
color: #10b981;
font-size: 0.875rem;
margin-top: 0.25rem;
}
.form-group .valid-feedback::before {
content: '✓ ';
font-weight: bold;
}
/* 密码强度指示器(预留) */
.password-strength {
height: 4px;
background-color: #e5e7eb;
border-radius: 2px;
margin-top: 0.5rem;
overflow: hidden;
}
.password-strength-bar {
height: 100%;
transition: all 0.3s ease;
border-radius: 2px;
}
.password-strength.weak .password-strength-bar {
width: 33%;
background-color: #ef4444;
}
.password-strength.medium .password-strength-bar {
width: 66%;
background-color: #f59e0b;
}
.password-strength.strong .password-strength-bar {
width: 100%;
background-color: #10b981;
}

View File

@ -0,0 +1,2 @@
[ZoneTransfer]
ZoneId=3

View File

@ -0,0 +1,404 @@
/**
* 认证处理器 - 处理登录/注册页面的交互逻辑
*/
class AuthHandler {
constructor() {
this.countdownTimer = null;
this.countdownSeconds = 60;
this.init();
}
/**
* 初始化
*/
init() {
this.setupEventListeners();
this.setupFormValidation();
this.checkPageType();
}
/**
* 检查页面类型并设置相应逻辑
*/
checkPageType() {
const loginForm = document.getElementById('loginForm');
const registerForm = document.getElementById('registerForm');
if (loginForm) {
this.setupLoginForm();
}
if (registerForm) {
this.setupRegisterForm();
}
}
/**
* 设置事件监听器
*/
setupEventListeners() {
// 发送验证码按钮
const sendCodeBtn = document.getElementById('sendCodeBtn');
if (sendCodeBtn) {
sendCodeBtn.addEventListener('click', (e) => {
e.preventDefault();
this.handleSendCode();
});
}
// 页面加载时检查登录状态
this.checkAuthStatus();
}
/**
* 设置表单验证
*/
setupFormValidation() {
// 账号字段实时验证
FormValidator.setupRealTimeValidation('account', (value) => FormValidator.validateAccount(value));
// 验证码字段实时验证
FormValidator.setupRealTimeValidation('verifyCode', (value) => FormValidator.validateVerifyCode(value));
// 用户名字段实时验证(仅注册页面)
const usernameField = document.getElementById('username');
if (usernameField) {
FormValidator.setupRealTimeValidation('username', (value) => FormValidator.validateUsername(value));
}
}
/**
* 设置登录表单
*/
setupLoginForm() {
const loginForm = document.getElementById('loginForm');
loginForm.addEventListener('submit', async (e) => {
e.preventDefault();
await this.handleLogin();
});
}
/**
* 设置注册表单
*/
setupRegisterForm() {
const registerForm = document.getElementById('registerForm');
registerForm.addEventListener('submit', async (e) => {
e.preventDefault();
await this.handleRegister();
});
}
/**
* 处理发送验证码
*/
async handleSendCode() {
const accountField = document.getElementById('account');
const sendCodeBtn = document.getElementById('sendCodeBtn');
if (!accountField || !sendCodeBtn) return;
const account = accountField.value.trim();
// 验证账号格式
const accountValidation = FormValidator.validateAccount(account);
if (!accountValidation.valid) {
FormValidator.showError('account', accountValidation.message);
this.showStatus('error', accountValidation.message);
return;
}
// 清除账号错误信息
FormValidator.clearError('account');
// 禁用按钮并显示加载状态
sendCodeBtn.disabled = true;
sendCodeBtn.classList.add('loading');
sendCodeBtn.textContent = '发送中...';
try {
// 判断是登录还是注册页面
const isRegisterPage = window.location.pathname.includes('register');
const type = isRegisterPage ? 'register' : 'login';
const result = await AuthService.sendVerifyCode(account, type);
if (result.success) {
this.showStatus('success', result.message);
this.startCountdown();
} else {
this.showStatus('error', result.message);
// 恢复按钮状态
sendCodeBtn.disabled = false;
sendCodeBtn.classList.remove('loading');
sendCodeBtn.textContent = '发送验证码';
}
} catch (error) {
console.error('Send code error:', error);
this.showStatus('error', '发送失败,请稍后重试');
// 恢复按钮状态
sendCodeBtn.disabled = false;
sendCodeBtn.classList.remove('loading');
sendCodeBtn.textContent = '发送验证码';
}
}
/**
* 处理登录
*/
async handleLogin() {
const accountField = document.getElementById('account');
const codeField = document.getElementById('verifyCode');
const loginBtn = document.getElementById('loginBtn');
if (!accountField || !codeField || !loginBtn) return;
const account = accountField.value.trim();
const verifyCode = codeField.value.trim();
// 验证表单
const accountValidation = FormValidator.validateAccount(account);
const codeValidation = FormValidator.validateVerifyCode(verifyCode);
let hasError = false;
if (!accountValidation.valid) {
FormValidator.showError('account', accountValidation.message);
hasError = true;
} else {
FormValidator.clearError('account');
}
if (!codeValidation.valid) {
FormValidator.showError('verifyCode', codeValidation.message);
hasError = true;
} else {
FormValidator.clearError('verifyCode');
}
if (hasError) {
this.showStatus('error', '请检查输入信息');
return;
}
// 显示加载状态
loginBtn.disabled = true;
loginBtn.classList.add('loading');
loginBtn.textContent = '登录中...';
try {
const result = await AuthService.login(account, verifyCode);
if (result.success) {
this.showStatus('success', result.message);
// 登录成功,延迟跳转
setTimeout(() => {
this.redirectAfterLogin();
}, 1000);
} else {
this.showStatus('error', result.message);
// 恢复按钮状态
loginBtn.disabled = false;
loginBtn.classList.remove('loading');
loginBtn.textContent = '登录';
}
} catch (error) {
console.error('Login error:', error);
this.showStatus('error', '登录失败,请稍后重试');
// 恢复按钮状态
loginBtn.disabled = false;
loginBtn.classList.remove('loading');
loginBtn.textContent = '登录';
}
}
/**
* 处理注册
*/
async handleRegister() {
const usernameField = document.getElementById('username');
const accountField = document.getElementById('account');
const codeField = document.getElementById('verifyCode');
const registerBtn = document.getElementById('registerBtn');
if (!usernameField || !accountField || !codeField || !registerBtn) return;
const username = usernameField.value.trim();
const account = accountField.value.trim();
const verifyCode = codeField.value.trim();
// 验证表单
const usernameValidation = FormValidator.validateUsername(username);
const accountValidation = FormValidator.validateAccount(account);
const codeValidation = FormValidator.validateVerifyCode(verifyCode);
let hasError = false;
if (!usernameValidation.valid) {
FormValidator.showError('username', usernameValidation.message);
hasError = true;
} else {
FormValidator.clearError('username');
}
if (!accountValidation.valid) {
FormValidator.showError('account', accountValidation.message);
hasError = true;
} else {
FormValidator.clearError('account');
}
if (!codeValidation.valid) {
FormValidator.showError('verifyCode', codeValidation.message);
hasError = true;
} else {
FormValidator.clearError('verifyCode');
}
if (hasError) {
this.showStatus('error', '请检查输入信息');
return;
}
// 显示加载状态
registerBtn.disabled = true;
registerBtn.classList.add('loading');
registerBtn.textContent = '注册中...';
try {
const result = await AuthService.register(username, account, verifyCode);
if (result.success) {
this.showStatus('success', result.message);
// 注册成功,延迟跳转
setTimeout(() => {
this.redirectAfterLogin();
}, 1000);
} else {
this.showStatus('error', result.message);
// 恢复按钮状态
registerBtn.disabled = false;
registerBtn.classList.remove('loading');
registerBtn.textContent = '注册';
}
} catch (error) {
console.error('Register error:', error);
this.showStatus('error', '注册失败,请稍后重试');
// 恢复按钮状态
registerBtn.disabled = false;
registerBtn.classList.remove('loading');
registerBtn.textContent = '注册';
}
}
/**
* 开始倒计时
*/
startCountdown() {
const sendCodeBtn = document.getElementById('sendCodeBtn');
if (!sendCodeBtn) return;
let seconds = this.countdownSeconds;
const updateButton = () => {
sendCodeBtn.textContent = `${seconds}秒后重试`;
sendCodeBtn.disabled = true;
sendCodeBtn.classList.add('countdown');
};
updateButton();
this.countdownTimer = setInterval(() => {
seconds--;
if (seconds > 0) {
updateButton();
} else {
// 倒计时结束
clearInterval(this.countdownTimer);
sendCodeBtn.textContent = '发送验证码';
sendCodeBtn.disabled = false;
sendCodeBtn.classList.remove('loading', 'countdown');
}
}, 1000);
}
/**
* 显示状态消息
* @param {string} type - 消息类型success/error/info/warning
* @param {string} message - 消息内容
*/
showStatus(type, message) {
const statusElement = document.getElementById('statusMessage');
const statusText = document.getElementById('statusText');
if (!statusElement || !statusText) return;
// 清除之前的类
statusElement.className = 'mt-4 p-3 rounded-lg';
statusElement.classList.add(type);
statusText.textContent = message;
statusElement.classList.remove('hidden');
// 成功消息3秒后自动隐藏
if (type === 'success') {
setTimeout(() => {
statusElement.classList.add('hidden');
}, 3000);
}
}
/**
* 检查认证状态
*/
async checkAuthStatus() {
try {
const authStatus = await AuthService.checkAuthStatus();
if (authStatus.isAuthenticated) {
// 已登录,重定向到首页
this.redirectAfterLogin();
}
} catch (error) {
console.error('Check auth status error:', error);
}
}
/**
* 登录后重定向
*/
redirectAfterLogin() {
// 获取跳转目标,默认为首页
const urlParams = new URLSearchParams(window.location.search);
const redirectUrl = urlParams.get('redirect') || '../../index.html';
window.location.href = redirectUrl;
}
/**
* 销毁实例
*/
destroy() {
if (this.countdownTimer) {
clearInterval(this.countdownTimer);
}
}
}
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', () => {
window.authHandler = new AuthHandler();
});
// 页面卸载时清理
window.addEventListener('beforeunload', () => {
if (window.authHandler) {
window.authHandler.destroy();
}
});

View File

@ -0,0 +1,2 @@
[ZoneTransfer]
ZoneId=3

View File

@ -0,0 +1,138 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>云大阁 - 登录</title>
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css?family=Work+Sans:400,600,800" rel="stylesheet">
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#2563eb'
},
fontFamily: {
'work': ['Work Sans', 'sans-serif']
}
}
}
}
</script>
<!-- FontAwesome 6 Free CDN -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" crossorigin="anonymous">
<!-- 自定义样式 -->
<link rel="stylesheet" href="../../css/style.css">
<link rel="stylesheet" href="../components/auth-form.css">
</head>
<body class="bg-gray-50 font-work min-h-screen flex items-center justify-center">
<!-- 动态背景 -->
<div class="background-container" style="position: fixed; inset: 0; z-index: 1; overflow: hidden;">
<div class="animated-gradient" id="animatedGradient" style="position: absolute; inset: 0; filter: blur(40px) saturate(1.2); transition: background 0.5s ease-out;"></div>
<div class="backdrop-overlay" style="position: absolute; inset: 0; background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(2px);"></div>
</div>
<!-- 返回首页按钮 -->
<div class="fixed top-4 left-4 z-50">
<a href="../../index.html" class="w-10 h-10 rounded-full bg-white/80 backdrop-blur-sm border border-white/40 flex items-center justify-center hover:bg-white/90 transition-all duration-200 shadow-lg">
<i class="fas fa-arrow-left text-gray-600"></i>
</a>
</div>
<!-- Logo -->
<div class="fixed top-4 left-1/2 transform -translate-x-1/2 z-50">
<img src="../../images/logo.png" alt="云大阁" class="w-12 h-12">
</div>
<!-- 登录表单容器 -->
<div class="auth-container relative z-10 w-full max-w-md mx-4">
<div class="auth-form-wrapper bg-white/70 backdrop-blur-md rounded-2xl p-8 shadow-xl border border-white/40">
<!-- 标题 -->
<div class="text-center mb-8">
<h1 class="text-3xl font-bold text-gray-800 mb-2">欢迎回来</h1>
<p class="text-gray-600">登录您的云大阁账户</p>
</div>
<!-- 登录表单 -->
<form id="loginForm" class="space-y-6">
<!-- 手机号/邮箱输入 -->
<div class="form-group">
<label for="account" class="block text-sm font-medium text-gray-700 mb-2">手机号/邮箱</label>
<div class="relative">
<input type="text" id="account" name="account"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200"
placeholder="请输入手机号或邮箱">
<div class="absolute inset-y-0 right-0 pr-3 flex items-center">
<i class="fas fa-user text-gray-400"></i>
</div>
</div>
<div class="error-message text-red-500 text-sm mt-1 hidden" id="accountError"></div>
</div>
<!-- 验证码输入 -->
<div class="form-group">
<label for="verifyCode" class="block text-sm font-medium text-gray-700 mb-2">验证码</label>
<div class="flex space-x-3">
<div class="flex-1 relative">
<input type="text" id="verifyCode" name="verifyCode"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200"
placeholder="请输入6位验证码" maxlength="6">
<div class="absolute inset-y-0 right-0 pr-3 flex items-center">
<i class="fas fa-shield-alt text-gray-400"></i>
</div>
</div>
<button type="button" id="sendCodeBtn"
class="px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors duration-200 whitespace-nowrap font-medium">
发送验证码
</button>
</div>
<div class="error-message text-red-500 text-sm mt-1 hidden" id="codeError"></div>
</div>
<!-- 登录按钮 -->
<button type="submit" id="loginBtn"
class="w-full py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors duration-200 font-medium text-lg">
登录
</button>
</form>
<!-- 分割线 -->
<div class="my-8 flex items-center">
<div class="flex-1 border-t border-gray-300"></div>
<span class="px-4 text-gray-500 text-sm"></span>
<div class="flex-1 border-t border-gray-300"></div>
</div>
<!-- 注册链接 -->
<div class="text-center">
<p class="text-gray-600">
还没有账户?
<a href="register.html" class="text-blue-500 hover:text-blue-600 font-medium">立即注册</a>
</p>
</div>
<!-- 状态提示 -->
<div id="statusMessage" class="mt-4 p-3 rounded-lg hidden">
<div class="flex items-center">
<i class="fas fa-info-circle mr-2"></i>
<span id="statusText"></span>
</div>
</div>
</div>
</div>
<!-- JavaScript -->
<script src="../../utils/token/token-manager.js"></script>
<script src="../../utils/validation/form-validator.js"></script>
<script src="../../services/api/auth-service.js"></script>
<script src="../components/auth-handler.js"></script>
</body>
</html>

View File

@ -0,0 +1,2 @@
[ZoneTransfer]
ZoneId=3

View File

@ -0,0 +1,163 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>云大阁 - 注册</title>
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css?family=Work+Sans:400,600,800" rel="stylesheet">
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#2563eb'
},
fontFamily: {
'work': ['Work Sans', 'sans-serif']
}
}
}
}
</script>
<!-- FontAwesome 6 Free CDN -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" crossorigin="anonymous">
<!-- 自定义样式 -->
<link rel="stylesheet" href="../../css/style.css">
<link rel="stylesheet" href="../components/auth-form.css">
</head>
<body class="bg-gray-50 font-work min-h-screen flex items-center justify-center">
<!-- 动态背景 -->
<div class="background-container" style="position: fixed; inset: 0; z-index: 1; overflow: hidden;">
<div class="animated-gradient" id="animatedGradient" style="position: absolute; inset: 0; filter: blur(40px) saturate(1.2); transition: background 0.5s ease-out;"></div>
<div class="backdrop-overlay" style="position: absolute; inset: 0; background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(2px);"></div>
</div>
<!-- 返回首页按钮 -->
<div class="fixed top-4 left-4 z-50">
<a href="../../index.html" class="w-10 h-10 rounded-full bg-white/80 backdrop-blur-sm border border-white/40 flex items-center justify-center hover:bg-white/90 transition-all duration-200 shadow-lg">
<i class="fas fa-arrow-left text-gray-600"></i>
</a>
</div>
<!-- Logo -->
<div class="fixed top-4 left-1/2 transform -translate-x-1/2 z-50">
<img src="../../images/logo.png" alt="云大阁" class="w-12 h-12">
</div>
<!-- 注册表单容器 -->
<div class="auth-container relative z-10 w-full max-w-md mx-4">
<div class="auth-form-wrapper bg-white/70 backdrop-blur-md rounded-2xl p-8 shadow-xl border border-white/40">
<!-- 标题 -->
<div class="text-center mb-8">
<h1 class="text-3xl font-bold text-gray-800 mb-2">加入云大阁</h1>
<p class="text-gray-600">创建您的新账户</p>
</div>
<!-- 注册表单 -->
<form id="registerForm" class="space-y-6">
<!-- 用户名输入 -->
<div class="form-group">
<label for="username" class="block text-sm font-medium text-gray-700 mb-2">用户名</label>
<div class="relative">
<input type="text" id="username" name="username"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200"
placeholder="请输入用户名">
<div class="absolute inset-y-0 right-0 pr-3 flex items-center">
<i class="fas fa-user text-gray-400"></i>
</div>
</div>
<div class="error-message text-red-500 text-sm mt-1 hidden" id="usernameError"></div>
</div>
<!-- 手机号/邮箱输入 -->
<div class="form-group">
<label for="account" class="block text-sm font-medium text-gray-700 mb-2">手机号/邮箱</label>
<div class="relative">
<input type="text" id="account" name="account"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200"
placeholder="请输入手机号或邮箱">
<div class="absolute inset-y-0 right-0 pr-3 flex items-center">
<i class="fas fa-envelope text-gray-400"></i>
</div>
</div>
<div class="error-message text-red-500 text-sm mt-1 hidden" id="accountError"></div>
</div>
<!-- 验证码输入 -->
<div class="form-group">
<label for="verifyCode" class="block text-sm font-medium text-gray-700 mb-2">验证码</label>
<div class="flex space-x-3">
<div class="flex-1 relative">
<input type="text" id="verifyCode" name="verifyCode"
class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200"
placeholder="请输入6位验证码" maxlength="6">
<div class="absolute inset-y-0 right-0 pr-3 flex items-center">
<i class="fas fa-shield-alt text-gray-400"></i>
</div>
</div>
<button type="button" id="sendCodeBtn"
class="px-6 py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors duration-200 whitespace-nowrap font-medium">
发送验证码
</button>
</div>
<div class="error-message text-red-500 text-sm mt-1 hidden" id="codeError"></div>
</div>
<!-- 注册按钮 -->
<button type="submit" id="registerBtn"
class="w-full py-3 bg-blue-500 text-white rounded-lg hover:bg-blue-600 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors duration-200 font-medium text-lg">
注册
</button>
</form>
<!-- 用户协议 -->
<div class="mt-6 text-center">
<p class="text-sm text-gray-500">
注册即表示您同意我们的
<a href="#" class="text-blue-500 hover:text-blue-600">用户协议</a>
<a href="#" class="text-blue-500 hover:text-blue-600">隐私政策</a>
</p>
</div>
<!-- 分割线 -->
<div class="my-8 flex items-center">
<div class="flex-1 border-t border-gray-300"></div>
<span class="px-4 text-gray-500 text-sm"></span>
<div class="flex-1 border-t border-gray-300"></div>
</div>
<!-- 登录链接 -->
<div class="text-center">
<p class="text-gray-600">
已有账户?
<a href="login.html" class="text-blue-500 hover:text-blue-600 font-medium">立即登录</a>
</p>
</div>
<!-- 状态提示 -->
<div id="statusMessage" class="mt-4 p-3 rounded-lg hidden">
<div class="flex items-center">
<i class="fas fa-info-circle mr-2"></i>
<span id="statusText"></span>
</div>
</div>
</div>
</div>
<!-- JavaScript -->
<script src="../../js/main.js"></script>
<script src="../../utils/validation/form-validator.js"></script>
<script src="../../utils/token/token-manager.js"></script>
<script src="../../services/api/auth-service.js"></script>
<script src="../components/auth-handler.js"></script>
</body>
</html>

View File

@ -0,0 +1,2 @@
[ZoneTransfer]
ZoneId=3