Files
Achievement_Inputing/templates/register.html
2025-10-14 14:46:38 +08:00

440 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block title %}注册新用户{% endblock %}
{% block content %}
<div class="register-container">
<div class="register-card">
<div class="register-header">
<h1>注册新用户</h1>
<p>创建新的系统用户账户</p>
</div>
<form method="POST" class="register-form">
<div class="form-group">
<label for="username">
<i class="fas fa-user"></i>
用户名
</label>
<input type="text"
id="username"
name="username"
required
minlength="3"
maxlength="20"
placeholder="请输入用户名3-20个字符">
<small class="form-text">用户名长度为3-20个字符只能包含字母、数字和下划线</small>
</div>
<div class="form-group">
<label for="password">
<i class="fas fa-lock"></i>
密码
</label>
<input type="password"
id="password"
name="password"
required
minlength="6"
placeholder="请输入密码至少6位">
<small class="form-text">密码长度至少6位建议包含字母和数字</small>
</div>
<div class="form-group">
<label for="confirm_password">
<i class="fas fa-lock"></i>
确认密码
</label>
<input type="password"
id="confirm_password"
name="confirm_password"
required
minlength="6"
placeholder="请再次输入密码">
<small class="form-text">请再次输入相同的密码进行确认</small>
</div>
<div class="form-group">
<label for="permission">
<i class="fas fa-user-cog"></i>
权限级别
</label>
<select id="permission" name="permission" required>
<option value="">请选择权限级别</option>
<option value="1">普通用户 - 可以录入和查询数据</option>
<option value="0">管理员 - 拥有所有权限</option>
</select>
<small class="form-text">
<strong>普通用户:</strong>可以上传图片、录入数据、查询数据<br>
<strong>管理员:</strong>拥有所有权限,包括用户管理和数据管理
</small>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">
<i class="fas fa-user-plus"></i>
创建用户
</button>
<a href="{{ url_for('user_management') }}" class="btn btn-secondary">
<i class="fas fa-arrow-left"></i>
返回用户管理
</a>
</div>
</form>
</div>
</div>
<style>
.register-container {
display: flex;
justify-content: center;
align-items: center;
min-height: calc(100vh - 200px);
padding: 20px;
}
.register-card {
background: white;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0,0,0,0.1);
padding: 40px;
width: 100%;
max-width: 500px;
}
.register-header {
text-align: center;
margin-bottom: 30px;
}
.register-header h1 {
color: #333;
margin-bottom: 10px;
font-size: 28px;
}
.register-header p {
color: #666;
font-size: 16px;
margin: 0;
}
.register-form {
width: 100%;
}
.form-group {
margin-bottom: 25px;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: #333;
font-size: 14px;
}
.form-group label i {
margin-right: 8px;
color: #007bff;
width: 16px;
}
.form-group input,
.form-group select {
width: 100%;
padding: 12px 16px;
border: 2px solid #e0e0e0;
border-radius: 8px;
font-size: 14px;
transition: all 0.3s ease;
box-sizing: border-box;
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: #007bff;
box-shadow: 0 0 0 3px rgba(0,123,255,0.1);
}
.form-group input:invalid {
border-color: #dc3545;
}
.form-group input:valid {
border-color: #28a745;
}
.form-text {
display: block;
margin-top: 5px;
font-size: 12px;
color: #666;
line-height: 1.4;
}
.form-actions {
display: flex;
gap: 15px;
margin-top: 30px;
}
.btn {
padding: 12px 24px;
border: none;
border-radius: 8px;
cursor: pointer;
text-decoration: none;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 600;
transition: all 0.3s ease;
flex: 1;
}
.btn i {
margin-right: 8px;
}
.btn-primary {
background-color: #007bff;
color: white;
}
.btn-primary:hover {
background-color: #0056b3;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,123,255,0.3);
}
.btn-secondary {
background-color: #6c757d;
color: white;
}
.btn-secondary:hover {
background-color: #545b62;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(108,117,125,0.3);
}
/* 响应式设计 */
@media (max-width: 768px) {
.register-container {
padding: 10px;
}
.register-card {
padding: 30px 20px;
}
.form-actions {
flex-direction: column;
}
.btn {
width: 100%;
}
}
/* 密码强度指示器 */
.password-strength {
margin-top: 5px;
height: 4px;
background-color: #e0e0e0;
border-radius: 2px;
overflow: hidden;
}
.password-strength-bar {
height: 100%;
width: 0%;
transition: all 0.3s ease;
}
.strength-weak {
background-color: #dc3545;
width: 33%;
}
.strength-medium {
background-color: #ffc107;
width: 66%;
}
.strength-strong {
background-color: #28a745;
width: 100%;
}
/* 表单验证样式 */
.form-group.error input,
.form-group.error select {
border-color: #dc3545;
box-shadow: 0 0 0 3px rgba(220,53,69,0.1);
}
.form-group.success input,
.form-group.success select {
border-color: #28a745;
box-shadow: 0 0 0 3px rgba(40,167,69,0.1);
}
.error-message {
color: #dc3545;
font-size: 12px;
margin-top: 5px;
display: none;
}
.success-message {
color: #28a745;
font-size: 12px;
margin-top: 5px;
display: none;
}
</style>
<script>
// 表单验证
document.addEventListener('DOMContentLoaded', function() {
const form = document.querySelector('.register-form');
const username = document.getElementById('username');
const password = document.getElementById('password');
const confirmPassword = document.getElementById('confirm_password');
const permission = document.getElementById('permission');
// 用户名验证
username.addEventListener('input', function() {
const value = this.value;
const formGroup = this.closest('.form-group');
if (value.length < 3) {
setFieldError(formGroup, '用户名至少需要3个字符');
} else if (value.length > 20) {
setFieldError(formGroup, '用户名不能超过20个字符');
} else if (!/^[a-zA-Z0-9_]+$/.test(value)) {
setFieldError(formGroup, '用户名只能包含字母、数字和下划线');
} else {
setFieldSuccess(formGroup, '用户名格式正确');
}
});
// 密码验证
password.addEventListener('input', function() {
const value = this.value;
const formGroup = this.closest('.form-group');
if (value.length < 6) {
setFieldError(formGroup, '密码至少需要6个字符');
} else {
setFieldSuccess(formGroup, '密码长度符合要求');
}
// 检查确认密码
if (confirmPassword.value) {
validateConfirmPassword();
}
});
// 确认密码验证
confirmPassword.addEventListener('input', validateConfirmPassword);
function validateConfirmPassword() {
const formGroup = confirmPassword.closest('.form-group');
if (confirmPassword.value !== password.value) {
setFieldError(formGroup, '两次输入的密码不一致');
} else if (confirmPassword.value.length >= 6) {
setFieldSuccess(formGroup, '密码确认正确');
}
}
// 权限选择验证
permission.addEventListener('change', function() {
const formGroup = this.closest('.form-group');
if (this.value === '') {
setFieldError(formGroup, '请选择权限级别');
} else {
setFieldSuccess(formGroup, '权限级别已选择');
}
});
// 表单提交验证
form.addEventListener('submit', function(e) {
let isValid = true;
// 验证用户名
if (username.value.length < 3 || username.value.length > 20 || !/^[a-zA-Z0-9_]+$/.test(username.value)) {
isValid = false;
setFieldError(username.closest('.form-group'), '用户名格式不正确');
}
// 验证密码
if (password.value.length < 6) {
isValid = false;
setFieldError(password.closest('.form-group'), '密码长度至少6位');
}
// 验证确认密码
if (password.value !== confirmPassword.value) {
isValid = false;
setFieldError(confirmPassword.closest('.form-group'), '两次输入的密码不一致');
}
// 验证权限选择
if (permission.value === '') {
isValid = false;
setFieldError(permission.closest('.form-group'), '请选择权限级别');
}
if (!isValid) {
e.preventDefault();
}
});
function setFieldError(formGroup, message) {
formGroup.classList.remove('success');
formGroup.classList.add('error');
let errorMsg = formGroup.querySelector('.error-message');
if (!errorMsg) {
errorMsg = document.createElement('div');
errorMsg.className = 'error-message';
formGroup.appendChild(errorMsg);
}
errorMsg.textContent = message;
errorMsg.style.display = 'block';
const successMsg = formGroup.querySelector('.success-message');
if (successMsg) {
successMsg.style.display = 'none';
}
}
function setFieldSuccess(formGroup, message) {
formGroup.classList.remove('error');
formGroup.classList.add('success');
let successMsg = formGroup.querySelector('.success-message');
if (!successMsg) {
successMsg = document.createElement('div');
successMsg.className = 'success-message';
formGroup.appendChild(successMsg);
}
successMsg.textContent = message;
successMsg.style.display = 'block';
const errorMsg = formGroup.querySelector('.error-message');
if (errorMsg) {
errorMsg.style.display = 'none';
}
}
});
</script>
{% endblock %}