yunzer/app/index/view/user/login.php
2025-06-07 15:30:12 +08:00

646 lines
25 KiB
PHP
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.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="__LAYUI__/css/layui.css">
<script src="__JS__/gt4.js"></script>
<script src="__LAYUI__/layui.js" charset="utf-8"></script>
<title>用户登录</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background: #f5f7fa;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
padding: 20px;
}
.login-container {
width: 420px;
background: #fff;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.05);
overflow: hidden;
}
.login-header {
padding: 40px 40px 20px;
text-align: center;
}
.login-header h2 {
font-size: 28px;
color: #333;
margin: 0;
font-weight: 600;
}
.login-header p {
color: #666;
margin: 10px 0 0;
font-size: 15px;
}
.login-form {
padding: 20px 40px 40px;
}
.layui-form-item {
margin-bottom: 25px;
}
.layui-input {
height: 45px;
line-height: 45px;
border-radius: 8px;
border: 1px solid #e4e7ed;
padding: 0 15px;
transition: all 0.3s;
}
.layui-input:focus {
border-color: #409eff;
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.1);
}
.layui-btn {
height: 45px;
line-height: 45px;
border-radius: 8px;
font-size: 16px;
background: #409eff;
transition: all 0.3s;
}
.layui-btn:hover {
background: #66b1ff;
transform: translateY(-1px);
}
.layui-tab {
margin: 0;
}
.layui-tab-title {
border: none;
padding: 0 40px;
}
.layui-tab-title li {
font-size: 15px;
color: #666;
padding: 0 20px;
}
.layui-tab-title .layui-this {
color: #409eff;
}
.layui-tab-title .layui-this:after {
border-bottom: 2px solid #409eff;
}
.layui-tab-content {
padding: 20px 0 0;
}
.wechat-login {
text-align: center;
padding: 30px 0;
padding-bottom: 60px;
}
.wechat-login img {
width: 200px;
height: 200px;
transition: transform 0.3s;
}
.wechat-login img:hover {
transform: scale(1.1);
}
.wechat-login p {
margin-top: 15px;
color: #666;
}
#qrcode-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#qrcode-loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#qrcode-loading .layui-icon {
font-size: 40px;
color: #409eff;
}
#qrcode-loading p {
margin-top: 10px;
color: #666;
}
.layui-input-inline {
margin-right: 0px !important;
}
#getCode {
height: 45px;
line-height: 45px;
padding: 0 20px;
font-size: 14px;
}
.layui-input-block {
display: flex;
justify-content: space-between;
}
.container {
width: 100%;
max-width: 400px;
/* margin: 50px auto; */
text-align: center;
}
.qrcode-container {
margin: 20px 0;
}
.qrcode-container img {
max-width: 200px;
cursor: pointer;
}
.qrcode-container p {
color: #666;
font-size: 14px;
margin-top: 10px;
}
.status {
color: #666;
margin: 10px 0;
}
.error {
color: #ff4d4f;
margin: 10px 0;
}
</style>
</head>
<body>
<div class="login-container">
<div class="login-header">
<h2>欢迎登录</h2>
<p>请选择登录方式</p>
</div>
<div class="layui-tab">
<ul class="layui-tab-title">
<li lay-id="account">账密登录</li>
<!-- <li lay-id="phone">手机验证码</li> -->
<li class="layui-this" lay-id="wechat">微信登录</li>
</ul>
<div class="layui-tab-content">
<div class="layui-tab-item" id="account">
<form action="#" method="post" class="layui-form login-form">
<div class="layui-form-item">
<div class="layui-input-block" style="margin-left: 0;">
<input type="text" name="account" required lay-verify="required" placeholder="请输入用户名"
autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block" style="margin-left: 0;">
<input type="password" name="password" required lay-verify="required"
placeholder="请输入密码" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div id="gt-captcha" style="width: 100%;"></div>
</div>
<div class="layui-form-item" style="display: flex;flex-direction: column;align-items: center;">
<div class="layui-input-block" style="margin-left: 0;margin-bottom: 10px;">
<button class="layui-btn layui-btn-fluid" lay-submit
lay-filter="accountLogin">登录</button>
</div>
<div style="margin-bottom: 10px;color: #aaa;">or</div>
<div>
<a href="{:url('/index/user/register')}" class="">注册</a>
</div>
</div>
</form>
</div>
<!-- <div class="layui-tab-item" id="phone">
<form action="#" method="post" class="layui-form login-form">
<div class="layui-form-item">
<div class="layui-input-block" style="margin-left: 0;">
<input type="tel" name="phone" required lay-verify="required|phone" placeholder="请输入手机号"
autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block" style="margin-left: 0;">
<div class="layui-input-inline" style="width: calc(100% - 120px);">
<input type="text" name="code" required lay-verify="required" placeholder="请输入验证码"
autocomplete="off" class="layui-input">
</div>
<div class="layui-input-inline" style="width: 110px;">
<button type="button" class="layui-btn" id="getCode">获取验证码</button>
</div>
</div>
</div>
<div class="layui-form-item">
<div id="gt-captcha" style="width: 100%;"></div>
</div>
<div class="layui-form-item">
<div class="layui-input-block" style="margin-left: 0;">
<button class="layui-btn layui-btn-fluid" lay-submit lay-filter="phoneLogin">登录</button>
</div>
</div>
</form>
</div> -->
<div class="layui-tab-item layui-show" id="wechat">
<div class="wechat-login">
<div class="container">
<h2>微信扫码登录</h2>
<div class="qrcode-container">
<img id="qrcode" src="__IMAGES__/loading.gif" alt="微信登录二维码" onclick="reGenerateQrcode()">
<p>点击二维码可刷新</p>
</div>
<div id="status" class="status">正在加载二维码...</div>
<div id="error" class="error"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// 全局变量
var checkLoginTimer = null;
var currentSceneStr = '';
var currentTicket = '';
var qrcodeExpireTime = 0;
var $ = layui.jquery;
// 获取微信登录二维码
function getQrcode() {
$.ajax({
url: '/index/wechat/getLoginTicket',
type: 'GET',
success: function(res) {
if (res.code === 0) {
$('#qrcode').attr('src', res.data.url);
currentSceneStr = res.data.scene_str;
currentTicket = res.data.ticket;
// 设置二维码过期时间5分钟
qrcodeExpireTime = new Date().getTime() + (res.data.expire_seconds * 1000);
$('#status').text('等待扫码...');
$('#error').text('');
// 开始检查登录状态
startCheckLogin();
} else {
$('#error').text('获取二维码失败:' + res.msg);
}
},
error: function() {
$('#error').text('获取二维码失败,请刷新页面重试');
}
});
}
// 开始检查登录状态
function startCheckLogin() {
if (checkLoginTimer) {
clearInterval(checkLoginTimer);
}
checkLoginTimer = setInterval(function() {
// 检查二维码是否过期
if (new Date().getTime() > qrcodeExpireTime) {
clearInterval(checkLoginTimer);
$('#status').text('二维码已过期,请点击刷新');
$('#qrcode').css('opacity', '0.5');
return;
}
$.ajax({
url: '/index/wechat/checkLoginStatus',
type: 'POST',
data: {
scene_str: currentSceneStr,
ticket: currentTicket
},
success: function(res) {
if (res.code === 1) {
// 登录成功
clearInterval(checkLoginTimer);
$('#status').text('登录成功,正在跳转...');
// 保存用户信息到localStorage
if (res.data) {
localStorage.setItem('user_account', res.data.user_account);
localStorage.setItem('expire_time', res.data.expire_time);
localStorage.setItem('is_auto_login', res.data.is_auto_login);
}
// 设置cookie
document.cookie = `user_account=${res.data.user_account}; path=/; max-age=${7*24*3600}`;
document.cookie = `user_avatar=${res.data.avatar}; path=/; max-age=${7*24*3600}`;
document.cookie = `user_name=${res.data.name}; path=/; max-age=${7*24*3600}`;
document.cookie = `open_id=${res.data.openid}; path=/; max-age=${7*24*3600}`;
// 跳转到首页或其他页面
setTimeout(function() {
window.location.href = '/';
}, 1000);
} else if (res.code === 0) {
// 更新状态信息
$('#status').text(res.msg);
}
},
error: function() {
$('#error').text('检查登录状态失败,请重试');
}
});
}, 2000); // 每2秒检查一次
}
// 重新生成二维码的全局函数
function reGenerateQrcode() {
if (!currentSceneStr) {
getQrcode();
return;
}
// 清除之前的定时器
if (checkLoginTimer) {
clearInterval(checkLoginTimer);
checkLoginTimer = null;
}
$.ajax({
url: '/index/wechat/reGenerateQrcode',
type: 'POST',
data: {
scene_str: currentSceneStr
},
success: function(res) {
if (res.code === 0) {
$('#qrcode').attr('src', res.data.url);
currentSceneStr = res.data.scene_str;
currentTicket = res.data.ticket;
// 设置新的二维码过期时间5分钟
qrcodeExpireTime = new Date().getTime() + (res.data.expire_seconds * 1000);
$('#status').text('等待扫码...');
$('#error').text('');
// 开始检查登录状态
startCheckLogin();
} else {
$('#error').text('刷新二维码失败:' + res.msg);
}
},
error: function() {
$('#error').text('刷新二维码失败,请重试');
}
});
}
layui.use(['form', 'element', 'jquery'], function () {
var form = layui.form;
var element = layui.element;
var layer = layui.layer;
// 页面加载完成后获取二维码
$(document).ready(function() {
getQrcode();
});
// 检查极验验证是否开启
<?php if ($config['geetest_open'] == 1): ?>
// 初始化极验验证
var handler = function (captchaObj) {
// 将验证码渲染到指定容器
captchaObj.appendTo('#gt-captcha');
// 账密登录表单提交
form.on('submit(accountLogin)', function (data) {
var validate = captchaObj.getValidate();
if (!validate) {
layer.msg('请完成验证码验证', {
icon: 2,
time: 2000
});
return false;
}
data.field.geetest_challenge = validate.geetest_challenge;
data.field.geetest_validate = validate.geetest_validate;
data.field.geetest_seccode = validate.geetest_seccode;
$.ajax({
url: '{:url("index/user/login")}',
type: 'POST',
data: data.field,
dataType: 'json',
success: function (res) {
if (res.code === 0) {
// 存储登录数据设置7天过期
var expireTime = new Date().getTime() + 7 * 24 * 60 * 60 * 1000;
localStorage.setItem('user_account', data.field.account);
localStorage.setItem('user_password', btoa(data.field.password));
localStorage.setItem('expire_time', expireTime);
// 添加登录状态标记
localStorage.setItem('is_auto_login', 'true');
layer.msg('登录成功', {
icon: 1,
time: 2000,
shade: 0.3
}, function () {
window.location.href = '{:url("/")}';
});
} else {
layer.msg(res.msg, {
icon: 2,
time: 2000
});
}
}
});
return false;
});
// 手机验证码登录表单提交
form.on('submit(phoneLogin)', function (data) {
var validate = captchaObj.getValidate();
if (!validate) {
layer.msg('请完成验证码验证', {
icon: 2,
time: 2000
});
return false;
}
data.field.geetest_challenge = validate.geetest_challenge;
data.field.geetest_validate = validate.geetest_validate;
data.field.geetest_seccode = validate.geetest_seccode;
$.ajax({
url: '{:url("index/user/login")}',
type: 'POST',
data: data.field,
dataType: 'json',
success: function (res) {
if (res.code === 0) {
layer.msg('登录成功', {
icon: 1,
time: 2000,
shade: 0.3
}, function () {
window.location.href = '{:url("/")}';
});
} else {
layer.msg(res.msg, {
icon: 2,
time: 2000
});
}
}
});
return false;
});
// 点击获取验证码按钮时验证
var getCodeBtn = document.getElementById('getCode');
if (getCodeBtn) {
getCodeBtn.addEventListener('click', function () {
console.log('获取验证码');
});
}
};
// 直接使用配置初始化极验验证,并添加错误处理
initGeetest4({
captchaId: '{$config[\'geetest_id\']}',
offline: false,
new_captcha: true
}, handler, function (error) {
console.error('极验验证初始化失败:', error);
layer.msg('验证码初始化失败,请刷新页面重试', {
icon: 2,
time: 2000
});
});
<?php else: ?>
// 极验验证关闭,移除验证码容器
$('#gt-captcha').remove();
// 移除表单提交时的验证码验证逻辑
form.on('submit(accountLogin)', function (data) {
$.ajax({
url: '{:url("index/user/login")}',
type: 'POST',
data: data.field,
dataType: 'json',
success: function (res) {
if (res.code === 0) {
// 存储登录数据设置7天过期
var expireTime = new Date().getTime() + 7 * 24 * 60 * 60 * 1000;
localStorage.setItem('user_account', data.field.account);
localStorage.setItem('user_password', btoa(data.field.password));
localStorage.setItem('expire_time', expireTime);
// 添加登录状态标记
localStorage.setItem('is_auto_login', 'true');
layer.msg('登录成功', {
icon: 1,
time: 2000,
shade: 0.3
}, function () {
window.location.href = '{:url("/")}';
});
} else {
layer.msg(res.msg, {
icon: 2,
time: 2000
});
}
}
});
return false;
});
form.on('submit(phoneLogin)', function (data) {
$.ajax({
url: '{:url("index/user/login")}',
type: 'POST',
data: data.field,
dataType: 'json',
success: function (res) {
if (res.code === 0) {
layer.msg('登录成功', {
icon: 1,
time: 2000,
shade: 0.3
}, function () {
window.location.href = '{:url("/")}';
});
} else {
layer.msg(res.msg, {
icon: 2,
time: 2000
});
}
}
});
return false;
});
// 移除获取验证码按钮的验证码验证逻辑
var getCodeBtn = document.getElementById('getCode');
if (getCodeBtn) {
getCodeBtn.addEventListener('click', function () {
console.log('获取验证码');
});
}
<?php endif; ?>
// 页面加载时检查是否有保存的登录数据
$(function () {
var expireTime = localStorage.getItem('expire_time');
var isAutoLogin = localStorage.getItem('is_auto_login');
if (expireTime && new Date().getTime() < expireTime && isAutoLogin === 'true') {
// 只填充账号,不填充密码
$('input[name="account"]').val(localStorage.getItem('user_account'));
} else {
// 如果过期或未开启自动登录,清除数据
localStorage.removeItem('user_account');
localStorage.removeItem('user_password');
localStorage.removeItem('expire_time');
localStorage.removeItem('is_auto_login');
}
});
});
</script>
<style>
.layui-form-item a {
color: #409eff;
}
.layui-form-item a:hover {
color: rgb(58, 125, 196);
}
</style>
</body>
</html>