262 lines
12 KiB
HTML
262 lines
12 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}注册 - 儿童语言学习系统{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="auth-page-container">
|
|
<div class="container py-4">
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-8 col-lg-7">
|
|
<div class="card kid-auth-card shadow-lg">
|
|
<div class="kid-auth-header">
|
|
<i class="fas fa-star icon"></i>
|
|
<h2 class="fw-bold">加入我们!</h2>
|
|
</div>
|
|
<div class="card-body p-4 p-md-5">
|
|
<p class="text-center text-muted mb-4">开启一段奇妙的语言学习之旅!</p>
|
|
|
|
<form method="POST" id="registerForm">
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label for="name" class="form-label">姓名 <span class="text-danger">*</span></label>
|
|
<input type="text" class="form-control" id="name" name="name"
|
|
placeholder="孩子的姓名" required>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label for="age" class="form-label">年龄 <span class="text-danger">*</span></label>
|
|
<select class="form-select" id="age" name="age" required>
|
|
<option value="">请选择年龄</option>
|
|
<option value="3">3岁</option>
|
|
<option value="4">4岁</option>
|
|
<option value="5">5岁</option>
|
|
<option value="6">6岁</option>
|
|
<option value="7">7岁</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label">性别 <span class="text-danger">*</span></label>
|
|
<div class="d-flex gap-4">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="radio" name="gender" id="gender_male" value="0" required>
|
|
<label class="form-check-label" for="gender_male">
|
|
<i class="fas fa-mars text-primary me-1"></i>小王子
|
|
</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="radio" name="gender" id="gender_female" value="1" required>
|
|
<label class="form-check-label" for="gender_female">
|
|
<i class="fas fa-venus text-pink me-1"></i>小公主
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="email" class="form-label">邮箱地址 <span class="text-danger">*</span></label>
|
|
<div class="input-group">
|
|
<span class="input-group-text"><i class="fas fa-envelope"></i></span>
|
|
<input type="email" class="form-control" id="email" name="email"
|
|
placeholder="请输入邮箱地址" required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="verification_code" class="form-label">邮箱验证码 <span class="text-danger">*</span></label>
|
|
<div class="input-group">
|
|
<input type="text" class="form-control" id="verification_code" name="verification_code"
|
|
placeholder="请输入6位验证码" maxlength="6" required>
|
|
<button type="button" class="btn btn-outline-primary" id="sendCodeBtn">
|
|
发送验证码
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label for="password" class="form-label">密码 <span class="text-danger">*</span></label>
|
|
<div class="input-group">
|
|
<span class="input-group-text">
|
|
<i class="fas fa-lock"></i>
|
|
</span>
|
|
<input type="password" class="form-control" id="password" name="password"
|
|
placeholder="至少6位密码" required minlength="6">
|
|
<button class="btn btn-outline-secondary" type="button" id="togglePassword">
|
|
<i class="fas fa-eye"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label for="confirm_password" class="form-label">确认密码 <span class="text-danger">*</span></label>
|
|
<div class="input-group">
|
|
<span class="input-group-text">
|
|
<i class="fas fa-lock"></i>
|
|
</span>
|
|
<input type="password" class="form-control" id="confirm_password" name="confirm_password"
|
|
placeholder="再次输入密码" required minlength="6">
|
|
<button class="btn btn-outline-secondary" type="button" id="toggleConfirmPassword">
|
|
<i class="fas fa-eye"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="parent_contact" class="form-label">家长联系方式 <span class="text-muted">(可选)</span></label>
|
|
<div class="input-group">
|
|
<span class="input-group-text"><i class="fas fa-phone-alt"></i></span>
|
|
<input type="text" class="form-control" id="parent_contact" name="parent_contact"
|
|
placeholder="手机号或微信号,便于沟通">
|
|
</div>
|
|
</div>
|
|
|
|
<button type="submit" class="btn btn-primary w-100 py-2 my-3" id="submitBtn">
|
|
<i class="fas fa-user-plus me-2"></i>完成注册
|
|
</button>
|
|
</form>
|
|
|
|
<hr class="my-2">
|
|
|
|
<div class="text-center">
|
|
<p class="mb-0">已有账户?
|
|
<a href="{{ url_for('auth.login') }}" class="fw-bold" style="color: var(--kid-accent);">
|
|
马上登录
|
|
</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
let countdownTimer = null;
|
|
|
|
// 密码显示/隐藏切换
|
|
function setupPasswordToggle(toggleId, inputId) {
|
|
const toggle = document.getElementById(toggleId);
|
|
const input = document.getElementById(inputId);
|
|
|
|
toggle.addEventListener('click', function() {
|
|
const type = input.getAttribute('type') === 'password' ? 'text' : 'password';
|
|
input.setAttribute('type', type);
|
|
|
|
const icon = toggle.querySelector('i');
|
|
icon.classList.toggle('fa-eye');
|
|
icon.classList.toggle('fa-eye-slash');
|
|
});
|
|
}
|
|
|
|
setupPasswordToggle('togglePassword', 'password');
|
|
setupPasswordToggle('toggleConfirmPassword', 'confirm_password');
|
|
|
|
// 发送验证码
|
|
const sendCodeBtn = document.getElementById('sendCodeBtn');
|
|
sendCodeBtn.addEventListener('click', function() {
|
|
const email = document.getElementById('email').value.trim();
|
|
|
|
if (!email) {
|
|
alert('请先输入邮箱地址');
|
|
return;
|
|
}
|
|
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
if (!emailRegex.test(email)) {
|
|
alert('请输入有效的邮箱地址');
|
|
return;
|
|
}
|
|
|
|
// 禁用按钮
|
|
sendCodeBtn.disabled = true;
|
|
sendCodeBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>发送中...';
|
|
|
|
// 发送验证码
|
|
fetch('/auth/send-verification-code', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
email: email,
|
|
type: 'register'
|
|
})
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
alert('验证码已发送到您的邮箱!');
|
|
startCountdown();
|
|
} else {
|
|
alert(data.message || '发送失败,请重试');
|
|
sendCodeBtn.disabled = false;
|
|
sendCodeBtn.innerHTML = '发送验证码';
|
|
}
|
|
})
|
|
.catch(error => {
|
|
alert('发送失败,请检查网络连接');
|
|
sendCodeBtn.disabled = false;
|
|
sendCodeBtn.innerHTML = '发送验证码';
|
|
});
|
|
});
|
|
|
|
// 倒计时
|
|
function startCountdown() {
|
|
let count = 60;
|
|
countdownTimer = setInterval(() => {
|
|
sendCodeBtn.innerHTML = `${count}秒后重试`;
|
|
count--;
|
|
|
|
if (count < 0) {
|
|
clearInterval(countdownTimer);
|
|
sendCodeBtn.disabled = false;
|
|
sendCodeBtn.innerHTML = '重新发送';
|
|
}
|
|
}, 1000);
|
|
}
|
|
|
|
// 表单验证
|
|
const registerForm = document.getElementById('registerForm');
|
|
registerForm.addEventListener('submit', function(e) {
|
|
const password = document.getElementById('password').value;
|
|
const confirmPassword = document.getElementById('confirm_password').value;
|
|
const verificationCode = document.getElementById('verification_code').value.trim();
|
|
|
|
if (password !== confirmPassword) {
|
|
e.preventDefault();
|
|
alert('两次输入的密码不一致');
|
|
return;
|
|
}
|
|
|
|
if (password.length < 6) {
|
|
e.preventDefault();
|
|
alert('密码长度至少6位');
|
|
return;
|
|
}
|
|
|
|
if (!verificationCode || verificationCode.length !== 6) {
|
|
e.preventDefault();
|
|
alert('请输入6位验证码');
|
|
return;
|
|
}
|
|
|
|
// 显示提交状态
|
|
const submitBtn = document.getElementById('submitBtn');
|
|
submitBtn.disabled = true;
|
|
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>注册中...';
|
|
});
|
|
|
|
// 验证码输入限制
|
|
const verificationInput = document.getElementById('verification_code');
|
|
verificationInput.addEventListener('input', function(e) {
|
|
e.target.value = e.target.value.replace(/[^0-9]/g, '');
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %}
|