195 lines
8.2 KiB
HTML
195 lines
8.2 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>注册 - RainWeb</title>
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
|
<link rel="stylesheet" href="/css/style.css">
|
|
|
|
<style>
|
|
.register-page { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px; }
|
|
.register-card { width: 100%; max-width: 420px; padding: 40px 32px; }
|
|
.register-card h1 { font-size: 28px; font-weight: 500; text-align: center; margin-bottom: 8px; }
|
|
.register-card .subtitle { text-align: center; color: var(--md-ref-on-surface-variant); margin-bottom: 28px; font-size: 14px; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="register-page">
|
|
<div class="card register-card">
|
|
<h1>创建账户</h1>
|
|
<p class="subtitle">加入 RainWeb</p>
|
|
|
|
<div class="form-group">
|
|
<label>用户名 *</label>
|
|
<input type="text" id="regUsername" placeholder="用户名" autocomplete="username">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>邮箱 *</label>
|
|
<input type="email" id="regEmail" placeholder="your@email.com" autocomplete="email">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>密码 *</label>
|
|
<input type="password" id="regPassword" placeholder="至少6位" autocomplete="new-password">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>确认密码 *</label>
|
|
<input type="password" id="regConfirm" placeholder="再次输入密码" autocomplete="new-password">
|
|
</div>
|
|
|
|
<!-- Verification code input (shown after registration) -->
|
|
<div id="verifySection" style="display:none">
|
|
<div class="card" style="padding:20px;margin-bottom:16px;text-align:center">
|
|
<div class="form-group">
|
|
<label style="font-size:16px;font-weight:600;margin-bottom:8px">邮箱验证码</label>
|
|
<p class="text-muted" style="font-size:14px;margin-bottom:12px">验证码已发送到您的邮箱,请输入 8 位数字验证码</p>
|
|
<input type="text" id="verifyCode" placeholder="输入 8 位验证码" maxlength="8" style="text-align:center;font-size:24px;letter-spacing:8px" inputmode="numeric">
|
|
</div>
|
|
<button class="btn btn-filled w-full" onclick="handleVerify()">验证并完成注册</button>
|
|
<button class="btn btn-text btn-sm mt-16" onclick="resendCode()" style="margin-top:8px">重新发送验证码</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="regError" style="color:var(--md-ref-error);font-size:14px;margin-bottom:12px;display:none"></div>
|
|
<button class="btn w-full" id="capBtn" onclick="doCaptcha()" style="display:none;margin-bottom:8px;background:#fff;color:#333;border:1px solid #333;justify-content:center;height:44px">
|
|
<span class="material-icons" id="capBtnIcon" style="font-size:20px">verified_user</span>
|
|
<span id="capBtnText">点击进行人机验证</span>
|
|
</button>
|
|
<button class="btn btn-filled w-full" onclick="handleRegister()" id="regBtn">注册</button>
|
|
|
|
<div style="text-align:center;margin-top:16px">
|
|
<span class="text-muted">已有账户?</span>
|
|
<a href="/login.html" class="btn-text btn" style="font-size:14px">登录</a>
|
|
</div>
|
|
<div style="text-align:center;margin-top:8px">
|
|
<a href="/" class="btn-text btn" style="font-size:14px">← 返回主页</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="snackbar" class="snackbar"></div>
|
|
|
|
<script src="/js/theme.js"></script>
|
|
<script src="/js/api.js"></script>
|
|
<script src="/js/nav.js"></script>
|
|
<script src="/js/captcha.js"></script>
|
|
<script>
|
|
let captchaNeeded = false;
|
|
const token = localStorage.getItem('token');
|
|
if (token) window.location.href = '/';
|
|
|
|
// First load settings, then check captcha
|
|
API.getPublicSettings().then(s => {
|
|
window._recaptchaSiteKey = s.recaptcha_site_key || '';
|
|
window._turnstileSiteKey = s.turnstile_site_key || '';
|
|
CAPTCHA.checkRequired('register').then(r => {
|
|
if (r.required) {
|
|
captchaNeeded = true;
|
|
document.getElementById('capBtn').style.display = 'inline-flex';
|
|
}
|
|
});
|
|
});
|
|
CAPTCHA.checkRequired('register').then(r => {
|
|
if (r.required) {
|
|
captchaNeeded = true;
|
|
document.getElementById('capBtn').style.display = 'inline-flex';
|
|
}
|
|
});
|
|
|
|
async function doCaptcha() {
|
|
const ok = await CAPTCHA.showModal('register');
|
|
if (ok) {
|
|
document.getElementById('capBtn').style.background = '#e8f5e9';
|
|
document.getElementById('capBtn').style.borderColor = '#4caf50';
|
|
document.getElementById('capBtn').style.color = '#2e7d32';
|
|
document.getElementById('capBtnIcon').textContent = 'check_circle';
|
|
document.getElementById('capBtnText').textContent = '验证通过';
|
|
document.getElementById('capBtn').disabled = true;
|
|
}
|
|
}
|
|
|
|
async function handleRegister() {
|
|
const username = document.getElementById('regUsername').value.trim();
|
|
const email = document.getElementById('regEmail').value.trim();
|
|
const password = document.getElementById('regPassword').value;
|
|
const confirm = document.getElementById('regConfirm').value;
|
|
const errEl = document.getElementById('regError');
|
|
const btn = document.getElementById('regBtn');
|
|
|
|
if (!username || !email || !password) {
|
|
errEl.textContent = '请填写所有必填项';
|
|
errEl.style.display = 'block'; return;
|
|
}
|
|
if (password.length < 6) {
|
|
errEl.textContent = '密码至少6位';
|
|
errEl.style.display = 'block'; return;
|
|
}
|
|
if (password !== confirm) {
|
|
errEl.textContent = '两次密码不一致';
|
|
errEl.style.display = 'block'; return;
|
|
}
|
|
|
|
let captcha_token = '';
|
|
if (captchaNeeded && !CAPTCHA.verified) {
|
|
errEl.textContent = '请先点击验证按钮完成验证';
|
|
errEl.style.display = 'block'; return;
|
|
}
|
|
|
|
errEl.style.display = 'none';
|
|
btn.disabled = true;
|
|
btn.textContent = '注册中...';
|
|
|
|
try {
|
|
const data = await API.register(username, password, email, captcha_token);
|
|
if (data.requires_verification) {
|
|
// Show verification code input
|
|
document.getElementById('verifySection').style.display = 'block';
|
|
document.getElementById('regBtn').style.display = 'none';
|
|
document.querySelectorAll('.form-group:not(#verifySection .form-group)').forEach(el => el.style.display = 'none');
|
|
document.querySelector('.subtitle').textContent = '请输入邮箱中的验证码';
|
|
errEl.style.display = 'none';
|
|
} else {
|
|
showSnackbar('注册成功,请登录');
|
|
setTimeout(() => window.location.href = '/login.html', 1000);
|
|
}
|
|
} catch (e) {
|
|
errEl.style.color = 'var(--md-ref-error)';
|
|
errEl.textContent = e.message;
|
|
errEl.style.display = 'block';
|
|
btn.disabled = false;
|
|
btn.textContent = '注册';
|
|
}
|
|
}
|
|
|
|
async function handleVerify() {
|
|
const code = document.getElementById('verifyCode').value.trim();
|
|
const username = document.getElementById('regUsername').value.trim();
|
|
const password = document.getElementById('regPassword').value;
|
|
const errEl = document.getElementById('regError');
|
|
if (!code || code.length !== 8) {
|
|
errEl.textContent = '请输入完整的 8 位验证码';
|
|
errEl.style.display = 'block'; return;
|
|
}
|
|
errEl.style.display = 'none';
|
|
try {
|
|
const data = await API.completeRegister(code, username, password);
|
|
showSnackbar('注册成功,请登录');
|
|
setTimeout(() => window.location.href = '/login.html', 1000);
|
|
} catch (e) {
|
|
errEl.textContent = e.message;
|
|
errEl.style.display = 'block';
|
|
}
|
|
}
|
|
|
|
async function resendCode() {
|
|
const email = document.getElementById('regEmail').value.trim();
|
|
const username = document.getElementById('regUsername').value.trim();
|
|
try {
|
|
await API.sendVerify(email, username);
|
|
showSnackbar('验证码已重新发送');
|
|
} catch (e) { showSnackbar(e.message); }
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|