用户系统
This commit is contained in:
440
templates/register.html
Normal file
440
templates/register.html
Normal file
@@ -0,0 +1,440 @@
|
||||
{% 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 %}
|
||||
Reference in New Issue
Block a user