444 lines
18 KiB
HTML
Executable File
444 lines
18 KiB
HTML
Executable File
{% load socialaccount %}
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>登录与注册</title>
|
|
<link rel="stylesheet" href="https://file.guimiaokeji.com/layui/css/layui.css">
|
|
<style>
|
|
body {
|
|
background: linear-gradient(to right, #1e3c72, #2a5298);
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
height: 100vh;
|
|
margin: 0;
|
|
font-family: 'Arial', sans-serif;
|
|
color: #fff;
|
|
}
|
|
.container {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
padding: 30px;
|
|
border-radius: 10px;
|
|
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
|
width: 90%;
|
|
max-width: 400px;
|
|
animation: fadeIn 1s ease-in-out;
|
|
backdrop-filter: blur(10px);
|
|
}
|
|
.layui-form-item {
|
|
margin-bottom: 20px;
|
|
}
|
|
.layui-btn {
|
|
width: 100%;
|
|
}
|
|
.tab-buttons {
|
|
display: flex;
|
|
justify-content: space-around;
|
|
margin-bottom: 20px;
|
|
}
|
|
.tab-buttons button {
|
|
flex: 1;
|
|
margin: 0 5px;
|
|
}
|
|
.login-options {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
}
|
|
.login-options button {
|
|
width: 48%;
|
|
}
|
|
.input-with-button {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.input-with-button input {
|
|
flex: 3;
|
|
}
|
|
.input-with-button button {
|
|
flex: 1;
|
|
margin-left: 10px;
|
|
padding: 9px 12px;
|
|
}
|
|
@keyframes fadeIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
.tab-buttons button.active {
|
|
background: linear-gradient(45deg, #3b82ec, #2196f3);
|
|
color: #fff;
|
|
}
|
|
.tab-buttons button {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
color: #fff;
|
|
border: none;
|
|
transition: all 0.3s;
|
|
}
|
|
.tab-buttons button:hover {
|
|
background: linear-gradient(45deg, #3b82ec, #2196f3);
|
|
}
|
|
input::-webkit-input-placeholder {
|
|
color: rgba(255, 255, 255, 0.7);
|
|
}
|
|
input:-ms-input-placeholder {
|
|
color: rgba(255, 255, 255, 0.7);
|
|
}
|
|
input::-ms-input-placeholder {
|
|
color: rgba(255, 255, 255, 0.7);
|
|
}
|
|
input::placeholder {
|
|
color: rgba(255, 255, 255, 0.7);
|
|
}
|
|
.layui-form-item .layui-input {
|
|
background: rgba(255, 255, 255, 0.2);
|
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
color: #fff;
|
|
}
|
|
.layui-form-item .layui-input:focus {
|
|
border-color: #3b82ec;
|
|
}
|
|
.layui-form-label {
|
|
color: #fff;
|
|
}
|
|
.loading-spinner {
|
|
display: none;
|
|
border: 4px solid rgba(0, 0, 0, 0.1);
|
|
border-radius: 50%;
|
|
border-top: 4px solid #fff;
|
|
width: 40px;
|
|
height: 40px;
|
|
animation: spin 1s linear infinite;
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
}
|
|
@keyframes spin {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="loading-spinner" id="loadingSpinner"></div>
|
|
<div class="tab-buttons">
|
|
<button class="layui-btn" id="loginTab">登录</button>
|
|
<button class="layui-btn" id="registerTab">注册</button>
|
|
</div>
|
|
<form class="layui-form" id="loginForm">
|
|
{% csrf_token %}
|
|
<div class="layui-form-item" id="loginFields">
|
|
<input type="text" name="login_type" value="password" style="display: none">
|
|
|
|
<label class="layui-form-label">用户名</label>
|
|
<div class="layui-input-block">
|
|
<input type="text" name="login_username" required lay-verify="required" placeholder="用户名 (邮箱或手机)" class="layui-input" style="margin-bottom: 20px;">
|
|
</div>
|
|
<label class="layui-form-label">密码</label>
|
|
<div class="layui-input-block">
|
|
<input type="password" name="login_password" required lay-verify="required" placeholder="密码" class="layui-input" style="margin-bottom: 20px;">
|
|
</div>
|
|
</div>
|
|
<div class="layui-form-item" id="codeLoginFields" style="display: none;">
|
|
<input type="text" name="login_type" value="code" style="display: none">
|
|
<label class="layui-form-label">手机号</label>
|
|
<div class="layui-input-block input-with-button" style="margin-bottom: 20px;">
|
|
<input type="text" name="phone" required lay-verify="required|phone" placeholder="手机号" class="layui-input">
|
|
<button type="button" class="layui-btn layui-btn-normal" style="line-height: 10px;" id="sendLoginCode">发送验证码</button>
|
|
</div>
|
|
<label class="layui-form-label">验证码</label>
|
|
<div class="layui-input-block">
|
|
<input type="text" name="login_code" required lay-verify="required" placeholder="验证码" class="layui-input" style="margin-bottom: 20px;">
|
|
</div>
|
|
</div>
|
|
<div class="layui-form-item">
|
|
<button class="layui-btn" type="button" id="loginButton">登录</button>
|
|
</div>
|
|
<div class="layui-form-item login-options">
|
|
<a href="{% provider_login_url 'google' %}" style="width: 48%;"><button type="button" class="layui-btn layui-btn-danger" style="width: 100%;">使用 Google 登录</button></a>
|
|
<button type="button" class="layui-btn layui-btn-warm" id="codeLoginButton">验证码登录</button>
|
|
</div>
|
|
<p><a href="/user/re_password/">忘记密码?</a> </p>
|
|
</form>
|
|
|
|
<form class="layui-form" id="registerForm" style="display: none;">
|
|
{% csrf_token %}
|
|
<div class="layui-form-item">
|
|
<label class="layui-form-label">选择注册方式</label>
|
|
<div class="layui-input-block">
|
|
<input type="radio" name="registerMethod" value="phone" lay-filter="registerMethod" title="手机号注册" checked>
|
|
<input type="radio" name="registerMethod" value="email" lay-filter="registerMethod" title="邮箱注册">
|
|
</div>
|
|
</div>
|
|
<div class="layui-form-item" id="phoneRegister">
|
|
<label class="layui-form-label">手机号</label>
|
|
<div class="layui-input-block input-with-button">
|
|
<input type="text" name="register_phone" id="registerPhoneInput" required lay-verify="required|phone" placeholder="手机号" class="layui-input">
|
|
<button type="button" class="layui-btn layui-btn-normal" style="line-height: 10px;" id="sendRegisterPhoneCode">发送验证码</button>
|
|
</div>
|
|
</div>
|
|
<div class="layui-form-item" id="emailRegister" style="display: none;">
|
|
<label class="layui-form-label">邮箱</label>
|
|
<div class="layui-input-block input-with-button">
|
|
<input type="email" name="register_email" id="registerEmailInput" required lay-verify="required|email" placeholder="邮箱" class="layui-input">
|
|
<button type="button" class="layui-btn layui-btn-normal" style="line-height: 10px;" id="sendRegisterEmailCode">发送验证码</button>
|
|
</div>
|
|
</div>
|
|
<div class="layui-form-item" id="codeRegister">
|
|
<label class="layui-form-label">验证码</label>
|
|
<div class="layui-input-block">
|
|
<input type="text" name="register_code" required lay-verify="required" placeholder="验证码" class="layui-input" style="margin-bottom: 20px;">
|
|
</div>
|
|
</div>
|
|
<div class="layui-form-item">
|
|
<label class="layui-form-label">用户名</label>
|
|
<div class="layui-input-block">
|
|
<input type="text" name="register_username" required lay-verify="required" placeholder="用户名" class="layui-input" style="margin-bottom: 20px;">
|
|
</div>
|
|
</div>
|
|
<div class="layui-form-item">
|
|
<label class="layui-form-label">密码</label>
|
|
<div class="layui-input-block">
|
|
<input type="password" name="register_password" required lay-verify="required" placeholder="密码" class="layui-input" style="margin-bottom: 20px;">
|
|
</div>
|
|
</div>
|
|
<div class="layui-form-item">
|
|
<label class="layui-form-label">确认密码</label>
|
|
<div class="layui-input-block">
|
|
<input type="password" name="register_confirm_password" required lay-verify="required" placeholder="确认密码" class="layui-input" style="margin-bottom: 20px;">
|
|
</div>
|
|
</div>
|
|
<div class="layui-form-item">
|
|
<input type="checkbox" name="agree" lay-skin="primary" title="我已阅读并同意用户注册条款" lay-verify="required">
|
|
</div>
|
|
<div class="layui-form-item">
|
|
<button class="layui-btn" type="button" id="registerButton">注册</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<script src="https://file.guimiaokeji.com/layui/jquery-3.6.0.min.js"></script>
|
|
<script src="https://file.guimiaokeji.com/layui/layui.js"></script>
|
|
|
|
<script>
|
|
layui.use(['form', 'layer'], function() {
|
|
var form = layui.form;
|
|
var $ = layui.jquery;
|
|
var layer = layui.layer;
|
|
var countdown = 60;
|
|
var emailTimer, phoneTimer, loginCodeTimer;
|
|
|
|
// 切换到登录表单
|
|
$('#loginTab').on('click', function() {
|
|
$('#loginForm').show();
|
|
$('#registerForm').hide();
|
|
$(this).addClass('active');
|
|
$('#registerTab').removeClass('active');
|
|
});
|
|
|
|
// 切换到注册表单
|
|
$('#registerTab').on('click', function() {
|
|
$('#registerForm').show();
|
|
$('#loginForm').hide();
|
|
$(this).addClass('active');
|
|
$('#loginTab').removeClass('active');
|
|
});
|
|
|
|
// 切换到验证码登录表单
|
|
$('#codeLoginButton').on('click', function() {
|
|
if ($(this).text() === '验证码登录') {
|
|
$('#loginFields').hide();
|
|
$('#codeLoginFields').show();
|
|
$(this).text('密码登录');
|
|
} else {
|
|
$('#loginFields').show();
|
|
$('#codeLoginFields').hide();
|
|
$(this).text('验证码登录');
|
|
}
|
|
});
|
|
|
|
// 选择注册方式时切换输入框
|
|
form.on('radio(registerMethod)', function(data) {
|
|
if (data.value === 'email') {
|
|
$('#emailRegister').show();
|
|
$('#phoneRegister').hide();
|
|
$('#codeRegister').show();
|
|
} else {
|
|
$('#emailRegister').hide();
|
|
$('#phoneRegister').show();
|
|
$('#codeRegister').show();
|
|
}
|
|
});
|
|
|
|
// 设置验证码按钮倒计时
|
|
function setCountdown(button, timer) {
|
|
button.prop('disabled', true);
|
|
button.text(countdown + 's');
|
|
timer = setInterval(function() {
|
|
countdown--;
|
|
if (countdown <= 0) {
|
|
clearInterval(timer);
|
|
button.prop('disabled', false);
|
|
button.text('发送验证码');
|
|
countdown = 60;
|
|
} else {
|
|
button.text(countdown + 's');
|
|
}
|
|
}, 1000);
|
|
}
|
|
|
|
// 发送验证码逻辑
|
|
function sendCode(button, timer, inputSelector, url) {
|
|
var inputValue = $(inputSelector).val();
|
|
if (!inputValue) {
|
|
layer.msg('请输入正确的' + (inputSelector === '#emailInput' || inputSelector === '#registerEmailInput' ? '邮箱' : '手机号'));
|
|
return;
|
|
}
|
|
setCountdown(button, timer);
|
|
console.log("发送验证码到: " + inputValue); // 控制台打印验证码发送信息
|
|
$.ajax({
|
|
type: 'POST',
|
|
url: url,
|
|
contentType: 'application/json',
|
|
data: JSON.stringify({phone_number: inputValue}),
|
|
success: function(response) {
|
|
console.log("验证码发送成功", response);
|
|
layer.msg('验证码发送成功');
|
|
},
|
|
error: function(xhr, status, error) {
|
|
console.error("验证码发送失败", error);
|
|
layer.msg('验证码发送失败');
|
|
}
|
|
});
|
|
}
|
|
|
|
$('#sendRegisterEmailCode').on('click', function() {
|
|
sendCode($(this), emailTimer, '#registerEmailInput', '/api/send-verification-email/');
|
|
});
|
|
|
|
$('#sendRegisterPhoneCode').on('click', function() {
|
|
sendCode($(this), phoneTimer, '#registerPhoneInput', '/api/send-verification-sms/');
|
|
});
|
|
|
|
$('#sendLoginCode').on('click', function() {
|
|
sendCode($(this), loginCodeTimer, 'input[name="phone"]', '/api/send-verification-sms/');
|
|
});
|
|
|
|
// 显示加载动画
|
|
function showLoading() {
|
|
$('#loadingSpinner').show();
|
|
}
|
|
|
|
// 隐藏加载动画
|
|
function hideLoading() {
|
|
$('#loadingSpinner').hide();
|
|
}
|
|
|
|
// 处理登录表单提交逻辑
|
|
$('#loginButton').on('click', function() {
|
|
var loginData = {
|
|
login_type:null,
|
|
username: $('input[name="login_username"]').val(),
|
|
password: $('input[name="login_password"]').val(),
|
|
phone: $('input[name="phone"]').val(),
|
|
code: $('input[name="login_code"]').val()
|
|
};
|
|
console.log(loginData)
|
|
if (loginData.username && loginData.password) {
|
|
loginData.login_type = 'password'
|
|
}
|
|
|
|
if (loginData.phone && loginData.code) {
|
|
loginData.login_type = 'code'
|
|
}
|
|
|
|
showLoading();
|
|
$.ajax({
|
|
type: 'POST',
|
|
url: '/api/login/',
|
|
contentType: 'application/json',
|
|
data: JSON.stringify(loginData),
|
|
success: function(response) {
|
|
hideLoading();
|
|
console.log("登录成功", response);
|
|
if (response.code === 200) {
|
|
layer.msg('登录成功,正在跳转', function() {
|
|
hideLoading();
|
|
window.location.href = '/user/userinfo/';
|
|
});
|
|
} else {
|
|
layer.msg(response.message);
|
|
console.error("登录失败", response.message);
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
hideLoading();
|
|
console.error("登录失败", error);
|
|
layer.msg('登录失败', error);
|
|
}
|
|
});
|
|
});
|
|
|
|
// 处理注册表单提交逻辑
|
|
$('#registerButton').on('click', function() {
|
|
var registerData = {
|
|
username: $('input[name="register_username"]').val(),
|
|
password: $('input[name="register_password"]').val(),
|
|
confirm_password: $('input[name="register_confirm_password"]').val(),
|
|
email: $('input[name="register_email"]').val(),
|
|
phone: $('input[name="register_phone"]').val(),
|
|
code: $('input[name="register_code"]').val(),
|
|
registerMethod: $('input[name="registerMethod"]:checked').val()
|
|
};
|
|
|
|
if (!registerData.username || !registerData.password || !registerData.confirm_password || !registerData.code) {
|
|
layer.msg('请填写所有必填字段');
|
|
return;
|
|
}
|
|
|
|
if (registerData.password !== registerData.confirm_password) {
|
|
layer.msg('两次密码输入不一致');
|
|
return;
|
|
}
|
|
|
|
showLoading();
|
|
$.ajax({
|
|
type: 'POST',
|
|
url: '/api/register/',
|
|
contentType: 'application/json',
|
|
data: JSON.stringify(registerData),
|
|
success: function(response) {
|
|
hideLoading();
|
|
console.log("注册成功", response);
|
|
if (response.code === 200) {
|
|
layer.msg('注册成功,正在登录', function() {
|
|
hideLoading();
|
|
window.location.href = '/user/userinfo/';
|
|
});
|
|
} else {
|
|
layer.msg(response.message);
|
|
console.error(response.message);
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
hideLoading();
|
|
layer.msg('注册失败', error);
|
|
console.error("注册失败", error);
|
|
}
|
|
});
|
|
});
|
|
|
|
// 默认显示登录表单
|
|
$('#loginTab').click();
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|