140 lines
7.3 KiB
HTML
140 lines
7.3 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}用户注册{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="row justify-content-center mt-5">
|
|
<div class="col-md-6 col-lg-5">
|
|
<div class="card border-0 shadow-sm">
|
|
<div class="card-header bg-light">
|
|
<h4 class="card-title mb-0">
|
|
<i class="fas fa-user-plus text-primary me-2"></i>用户注册
|
|
</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<form method="POST" action="{{ url_for('register') }}" id="registerForm">
|
|
<div class="mb-3">
|
|
<label for="username" class="form-label">
|
|
<i class="fas fa-user me-1 text-muted"></i>用户名
|
|
</label>
|
|
<input type="text" class="form-control" id="username" name="username" required
|
|
pattern="[a-zA-Z0-9_]{4,20}"
|
|
title="4-20位字母、数字或下划线">
|
|
<small class="form-text text-muted">4-20位字母、数字或下划线</small>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="password" class="form-label">
|
|
<i class="fas fa-lock me-1 text-muted"></i>密码
|
|
</label>
|
|
<input type="password" class="form-control" id="password" name="password" required
|
|
minlength="{{ config.PASSWORD_POLICY.min_length }}"
|
|
pattern="{% if config.PASSWORD_POLICY.require_uppercase %}(?=.*[A-Z]){% endif %}
|
|
{% if config.PASSWORD_POLICY.require_lowercase %}(?=.*[a-z]){% endif %}
|
|
{% if config.PASSWORD_POLICY.require_digits %}(?=.*\d]){% endif %}
|
|
{% if config.PASSWORD_POLICY.require_special_chars %}(?=.*[!@#$%^&*]){% endif %}.*"
|
|
title="{% if config.PASSWORD_POLICY.require_uppercase %}必须包含大写字母{% endif %}
|
|
{% if config.PASSWORD_POLICY.require_lowercase %}必须包含小写字母{% endif %}
|
|
{% if config.PASSWORD_POLICY.require_digits %}必须包含数字{% endif %}
|
|
{% if config.PASSWORD_POLICY.require_special_chars %}必须包含特殊字符{% endif %}">
|
|
<small class="form-text text-muted">
|
|
密码要求:至少{{ config.PASSWORD_POLICY.min_length }}位
|
|
{% if config.PASSWORD_POLICY.require_uppercase %},包含大写字母{% endif %}
|
|
{% if config.PASSWORD_POLICY.require_lowercase %},包含小写字母{% endif %}
|
|
{% if config.PASSWORD_POLICY.require_digits %},包含数字{% endif %}
|
|
{% if config.PASSWORD_POLICY.require_special_chars %},包含特殊字符(!@#$%^&*){% endif %}
|
|
</small>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="confirm_password" class="form-label">
|
|
<i class="fas fa-lock me-1 text-muted"></i>确认密码
|
|
</label>
|
|
<input type="password" class="form-control" id="confirm_password"
|
|
name="confirm_password" required
|
|
oninput="checkPasswordMatch()">
|
|
<small id="passwordMatchError" class="text-danger d-none">两次输入的密码不一致</small>
|
|
</div>
|
|
|
|
{% if config.EMAIL_VERIFICATION_REQUIRED %}
|
|
<div class="mb-3">
|
|
<label for="email" class="form-label">
|
|
<i class="fas fa-envelope me-1 text-muted"></i>邮箱
|
|
</label>
|
|
<input type="email" class="form-control" id="email" name="email" required
|
|
placeholder="example@domain.com">
|
|
<small class="form-text text-muted">用于接收验证邮件</small>
|
|
</div>
|
|
{% else %}
|
|
<div class="mb-3">
|
|
<label for="email" class="form-label">
|
|
<i class="fas fa-envelope me-1 text-muted"></i>邮箱(可选)
|
|
</label>
|
|
<input type="email" class="form-control" id="email" name="email"
|
|
placeholder="example@domain.com">
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="mb-4">
|
|
<label for="captcha" class="form-label">
|
|
<i class="fas fa-shield-alt me-1 text-muted"></i>验证码
|
|
</label>
|
|
<div class="input-group">
|
|
<input type="text" class="form-control" id="captcha" name="captcha" required
|
|
placeholder="请输入验证码">
|
|
<img src="{{ url_for('captcha') }}" id="captcha-image"
|
|
class="img-thumbnail bg-light"
|
|
style="cursor: pointer; width: 100px; height: 38px;"
|
|
onclick="refreshCaptcha()"
|
|
title="点击刷新验证码">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-grid gap-2">
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fas fa-user-plus me-1"></i> 注册
|
|
</button>
|
|
<a href="{{ url_for('login') }}" class="btn btn-link text-decoration-none">
|
|
已有账号?去登录
|
|
</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function refreshCaptcha() {
|
|
document.getElementById('captcha-image').src = "{{ url_for('captcha') }}?" + Date.now();
|
|
}
|
|
|
|
function checkPasswordMatch() {
|
|
const password = document.getElementById('password');
|
|
const confirmPassword = document.getElementById('confirm_password');
|
|
const errorElement = document.getElementById('passwordMatchError');
|
|
|
|
if (password.value !== confirmPassword.value) {
|
|
errorElement.classList.remove('d-none');
|
|
confirmPassword.setCustomValidity("密码不匹配");
|
|
} else {
|
|
errorElement.classList.add('d-none');
|
|
confirmPassword.setCustomValidity("");
|
|
}
|
|
}
|
|
|
|
// 实时验证密码复杂度
|
|
document.getElementById('password').addEventListener('input', function() {
|
|
const password = this.value;
|
|
const policy = {
|
|
minLength: {{ config.PASSWORD_POLICY.min_length }},
|
|
requireUpper: {{ config.PASSWORD_POLICY.require_uppercase|lower }},
|
|
requireLower: {{ config.PASSWORD_POLICY.require_lowercase|lower }},
|
|
requireDigit: {{ config.PASSWORD_POLICY.require_digits|lower }},
|
|
requireSpecial: {{ config.PASSWORD_POLICY.require_special_chars|lower }}
|
|
};
|
|
|
|
// 可以在这里添加更复杂的实时验证逻辑
|
|
});
|
|
</script>
|
|
{% endblock %} |