feat(login): 添加登录页面功能

- 新增登录页面,包含用户登录、注册和忘记密码功能
- 集成数据库连接和查询功能
- 添加验证码系统
- 实现用户协议和隐私协议弹窗
- 优化页面样式和交互效果
This commit is contained in:
2024-12-22 11:49:15 +08:00
parent 362adff98b
commit 8b7f93988f

727
login.php Normal file
View File

@@ -0,0 +1,727 @@
<!--
* 冰雪传奇H5
* 2022 XX信息科技有限公司
*
* @author 123456
* @wx 123456
* @qq 123456
-->
<?php
include 'config.php';
// 连接数据库
$mySQLi = new mysqli($_CONFIG_DB['db_host'], $_CONFIG_DB['db_user'], $_CONFIG_DB['db_password'], $_CONFIG_DB['db_name'], $_CONFIG_DB['db_port']);
if($mySQLi->connect_errno) returnJson(['code' => 1, 'msg' => $mySQLi->connect_error]);
$mySQLi->set_charset($_CONFIG_DB['db_charset']);
// 查询
$status = 1;
$stmt = $mySQLi->prepare('select server_id from server where status >= ? order by server_id asc limit 1000');
$stmt->bind_param('d', $status);
$stmt->bind_result($server_id);
$stmt->execute();
$stmt->store_result();
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<meta name="applicable-device" content="mobile">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="full-screen" content="yes"/>
<meta name="x5-fullscreen" content="true"/>
<meta name="360-fullscreen" content="true"/>
<meta name="screen-orientation" content="portrait">
<meta name="x5-orientation" content="portrait">
<meta name="x5-page-mode" content="app">
<title><?=$_CONFIG['game_name']?> <?=$_CONFIG['game_description']?></title>
<meta name="description" content="<?=$_CONFIG['game_name']?> <?=$_CONFIG['game_description']?>">
<meta name="keywords" content="<?=$_CONFIG['game_name']?>,<?=$_CONFIG['game_description']?>">
<link rel="stylesheet" href="static/css/login.css?v=1.1.6"/>
<script>
document.onkeydown = document.onkeyup = document.onkeypress = function(event) {
var e = event || window.event || arguments.callee.caller.arguments[0];
if (e && e.keyCode == 123) {
e.returnValue = false;
return false;
}
}
</script>
<script src="static/js/jquery.js"></script>
<script src="static/layer/layer.js"></script>
<!--<script src="static/js/cookie.js"></script>-->
<script src="static/js/md5.js"></script>
<script src="static/js/common.js?v=1"></script>
<script>
//全局ajax loading事件
// var layer_loading;
// $(document).ajaxStart(function() {
// layer_loading = layer.load(0, {shade: 0.8});
// });
// $(document).ajaxSuccess(function() {
// layer.close(layer_loading);
// });
layer.config({skin: 'dialogs'});
</script>
</head>
<body oncontextmenu="return false" onselectstart="return false" ondragstart="return false">
<div class="wrapper pagebg">
<div class="dialog account" id="account-login">
<h2 class="title"><?=$_CONFIG['game_name']?> <?=$_CONFIG['game_description']?></h2>
<input type="text" id="account" value="<?=isset($_COOKIE['account']) ? $_COOKIE['account'] : ''?>" placeholder="请输入<?=$_CONFIG['account_name']?><?=$_CONFIG['account_name_suffix']?>" onKeyUp="value = value.replace(/[\W]/g, '')" autocomplete="off" disableautocomplete>
<input type="password" id="password" value="<?=isset($_COOKIE['password']) ? $_COOKIE['password'] : ''?>" placeholder="请输入<?=$_CONFIG['account_name']?><?=$_CONFIG['password_name_suffix']?>">
<input type="password" id="password2" placeholder="请再次输入<?=$_CONFIG['account_name']?><?=$_CONFIG['password_name_suffix']?>" style="display: none;">
<select id="serverId" style="border: none; display: none; margin-bottom: 10px;">
<option value="0">请选择区服</option>
<?php while($stmt->fetch()) { ?>
<option value="<?=$server_id?>"><?=$server_id?>区</option>
<?php } ?>
</select>
<input type="text" id="email" placeholder="<?php if($_CONFIG['reg_code_open']): ?>请输入<?php if('email' == $_CONFIG['code_type']): ?>邮箱地址<?php else: ?>手机号<?php endif; ?><?php else: ?><?php if('email' == $_CONFIG['code_type']): ?>邮箱地址<?php else: ?>手机号<?php endif; ?>(选填)<?php endif; ?>,用于找回密码" style="display: none;" title="用于找回密码">
<div class="code" id="codeBox" style="display: none;">
<input type="text" id="code" placeholder="请输入验证码">
<a href="javascript:void(0);" id="getCode">获取验证码</a>
</div>
<div id="agree" class="agree">
<span><img data-v-427e1e01="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAVFBMVEWeICicICedISidISibIiadISeeISiOOTmdISeeISj///+aGSGcHiT68vOYFByhKjHRmZzqz9CzVlvx4OG4YWXJh4qpPUPkw8WkMjjdsrS/cXatR00P5JiiAAAACnRSTlPuTT//Gq+6A9iEOAr7KAAAAbBJREFUSMeVlte2gyAQRTHYcBBQiu3///OOMdZALvCUrHX2mYYAqao8Y2VN/l11ybK8qkiVv1hR04hVF+yVVwT1NaFRi9RIkIzVNHrVLCOsIPEAKRgpEwJgiJIk6ZEgUQlxAP5JKhLgnCYAHOg4ygQAwBnjEIsDAEDOSvUgooHRTHowkQCseqWbLh546wPA2e6r/4T6xp8SP/t9+M9vfQCQEtt9MnDqfSlxLpfe9OMVcLveB6x2StllG9D6n5/6dvqeg4BFaT3M46eQm76zywPgHAMMTaOVkQAf/6Hd9QpTvW8N4LJf+41ETwEbzJ296uVzewtwtnsLMDoVgi53PcADAGmmTdAO1gnxpb9H4HtCW0dmF/A/AOz4ocAyJqv8/geALbXdrm9a3Wm//xlh7Xl7EvvPp/+1hgWndCIB/+ukpTOXMgL+90nLxd6CePyvEfDjoc6orv3l//ge8Hjo7aB/+D8BgWnN2wD9/l+HAO65cU2rDfh7ANy1WHs3+P19x8y6sWdrzejz9wOCusWN1OcfOMg4B786CGC7QgRJv7KSL8Xkazf5Yk9+OiQ/TlKfP3/iYTk/HuYxLgAAAABJRU5ErkJggg=="></span>
我已阅读并同意 <a href="javascript:void(0);" id="agree_btn">用户协议及隐私协议<a/>
</div>
<a href="javascript:process_login();" id="submitButton" class="button fit">登 录</a>
<div style="display:flex;justify-content:center" id="linuxdoConnect">
<div style="display:flex;align-items:center;flex-direction:column;gap:4px;cursor:pointer">
<img src="static/img/linuxdo_logo.png" style="width:60px;height:60px" alt="Linux.Do登录"/>
<div>Linux.do登录</div>
</div>
</div>
<div class="forget_password">
<a href="javascript:void(0);" id="forgetPassword" data-type="2">忘记密码?</a>
<a href="javascript:void(0);" class="pull-right" id="switchBtn" data-type="1">注册</a>
</div>
</div>
<div id="bg" class="gamebg" style="background-image: url(static/img/login_bg.jpg);"></div>
</div>
<script>
var loginBox = $('#account-login'),
accountObj = $('#account'),
passwordObj = $('#password'),
password2Obj = $('#password2'),
serverObj = $('#serverId'),
emailObj = $('#email'),
codeBoxObj = $('#codeBox'),
codeObj = $('#code'),
getCodeBtn = $('#getCode'),
agree = $('#agree'),
submitButton = $('#submitButton'),
forgetPassword = $('#forgetPassword'),
switchBtn = $('#switchBtn');
const linuxdoConnect = $("#linuxdoConnect")
linuxdoConnect.click(()=>{
location.href="https://connect.linux.do/oauth2/authorize?response_type=code&client_id=tfKevot5lSwB5A5gcqPQMMhaXDLjib0P"
})
var isPhone = isMobile(),
agent_id = getQueryString('agent_id'),
codeOpen = <?=$_CONFIG['code_open']?>,
regCodeOpen = <?=$_CONFIG['reg_code_open']?>,
codeType = '<?=$_CONFIG['code_type']?>',
type = 0,
codeTime = 0,
getCodeTimer = 0;
var saveAccount = '',
savePassword = '',
codeBtnTxt = getCodeBtn.html(),
curBtnTxt = '',
accountName = '<?=$_CONFIG['account_name']?>',
accountNameLast = '<?=$_CONFIG['account_name_suffix']?>',
passwordNameLast = '<?=$_CONFIG['password_name_suffix']?>';
$(window).load(function() {
var copyright = $('#copyright'),
firstChangeBg = getCookie('first_change_bg'),
bgImgPath = 'static/img/',
bgImgs = ['login_bg.jpg', 'login_bg.jpg', 'login_bg2.jpg', 'login_bg.jpg', 'login_bg.jpg'],
randomBg = !firstChangeBg ? (setCookie('first_change_bg', 1), 0) : randomRange(0, 4),
bgImg = bgImgs[randomBg];
$('#bg').css('background-image', 'url(' + bgImgPath + bgImg + ')');
setTimeout(function() {
layer.open({
type: 1,
content: loginBox,
skin: 'loginbox',
closeBtn: 0,
shade: .2,
title: false
});
if(!isPhone) {
if(accountObj.val() == '') {
accountObj.focus();
} else if(passwordObj.val() == '') {
passwordObj.focus();
}
}
}, 300);
setTimeout(function() {
copyright.fadeIn();
}, 750);
if(isPhone) {
$('input').focus(function() {
copyright.hide();
}).blur(function() {
copyright.fadeIn();
});
} else {
$(window).resize(function() {
if(125 >= loginBox.offset().top) {
copyright.hide();
} else{
copyright.show();
}
});
}
});
$(function() {
document.documentElement.addEventListener('touchstart', function (event) {
if (event.touches.length > 1) {
event.preventDefault();
}
}, false);
if(!isPhone) {
$(document).keydown(function() {
if (event.keyCode == 13) {
process_login();
}
});
}
if(agent_id) {
changePage(1);
}
forgetPassword.click(function(t) {
var _type = $(t.currentTarget).attr('data-type');
changePage(_type);
});
switchBtn.click(function(t) {
var _type = $(t.currentTarget).attr('data-type');
changePage(_type);
});
getCodeBtn.click(function(t) {
var t = $(t.currentTarget),
ret;
if(t.hasClass('disabled')) return;
var account = accountObj.val(),
emailVal = emailObj.val();
ret = checkAccountLength(account, accountName + accountNameLast);
//console.log(ret);
if(true !== ret) {
showTips(ret, accountObj, 'error');
return;
}
ret = funcChina(account, accountName + accountNameLast);
//console.log(ret);
if(true !== ret) {
showTips(ret, accountObj, 'error');
return;
}
ret = checkAccount(account, accountName + accountNameLast);
//console.log(ret);
if(true !== ret) {
showTips(ret, accountObj, 'error');
return;
}
ret = checkEmail(emailVal);
//console.log(ret);
if(true !== ret) {
showTips(ret, emailObj, 'error');
return;
}
t.addClass('disabled').html('正在发送..');
let fm = new FormData();
fm.append('type', type);
fm.append('account', account);
fm.append('email', emailVal);
$.ajax({
url: '/api?act=getCode',
type: 'post',
data: fm,
contentType: false,
processData: false,
dataType: 'json',
success: function(res) {
if(0 == res.code) {
codeTime = res.time;
clearInterval(getCodeTimer);
getCodeTimer = setInterval(function() {
updateCodeTime(res.time);
}, 1e3);
layer.alert(res.msg, {icon: 6, title: false});
} else {
showTips(res.msg, 'error');
if(res.time) {
codeTime = res.time;
clearInterval(getCodeTimer);
getCodeTimer = setInterval(function() {
updateCodeTime(res.time);
}, 1e3);
} else {
setTimeout(function() {
t.html(codeBtnTxt).removeClass('disabled');
}, 3e3);
}
}
return false;
},
error: function(e) {
showTips('系统错误,请稍候重试。', 6, 'error');
setTimeout(function() {
t.html(codeBtnTxt).removeClass('disabled');
}, 3e3);
return false;
}
});
});
$('#kfqq').click(function() {
var callFunc;
if(isPhone) {
callFunc = function() {
window.location.href = 'http://wpa.qq.com/msgrd?v=3&uin=123456&site=qq';
};
} else {
callFunc = function() {
window.open('http://wpa.qq.com/msgrd?v=3&uin=123456&site=qq');
};
}
layer.alert('开始发起QQ客服聊天', {
title: false,
icon: 6,
anim: 2,
shadeClose: true,
btn: ['确定', '取消'],
yes: function() {
callFunc();
}
});
});
$('#agree_btn').click(function() {
layer.open({
type: 2,
anim: 2,
content: 'api?act=misc&do=agree',
skin: 'agree_content',
area: isPhone ? [$(document).width() + 'px', $(document).height() + 'px'] : ['700px', '800px'],
closeBtn: isPhone ? 1 : 2,
shade: 0.3,
shadeClose: true,
title: '用户协议及隐私协议',
//maxmin: true
});
});
});
function changePage(t) {
if(1 == t || 2 == t) {
saveAccount = accountObj.val();
savePassword = passwordObj.val();
} else {
accountObj.val(saveAccount);
passwordObj.val(savePassword);
}
if(1 == t) {
accountObj.val('');
passwordObj.val('');
password2Obj.val('');
codeOpen && emailObj.val('');
} else if(2 == t) {
passwordObj.val('');
password2Obj.val('');
}
if(codeOpen && (1 == t || 2 == t)) {
codeObj.val('');
}
if(0 == t || 1 == t) {
var txt = '',
txt2 = '',
regTxt = '注 册',
loginTxt = '登 录';
if(1 == t) {
passwordObj.attr('placeholder', '请输入' + accountName + passwordNameLast);
password2Obj.attr('placeholder', '请再次输入' + accountName + passwordNameLast);
password2Obj.show();
serverObj.show();
codeOpen && emailObj.show();
codeOpen && regCodeOpen && codeBoxObj.show();
txt = regTxt;
txt2 = loginTxt;
switchBtn.attr('data-type', 0);
forgetPassword.hide();
} else if(0 == t) {
passwordObj.attr('placeholder', '请输入' + accountName + passwordNameLast);
password2Obj.hide();
serverObj.hide();
emailObj.hide();
codeBoxObj.hide();
txt = loginTxt;
txt2 = regTxt;
switchBtn.attr('data-type', 1);
forgetPassword.show();
} else {
showTips('参数错误!请刷新页面重试~', 'error');
return;
}
agree.show();
type = t;
curBtnTxt = txt;
switchBtn.html(txt2.replace(' ', ''));
submitButton.html(txt);
} else {
if(!codeOpen) {
showTips('验证码系统尚未开启找回密码请联系QQ客服。', 'error');
return;
}
var txt = '修改' + accountName + passwordNameLast,
txt2 = '登 录';
passwordObj.attr('placeholder', '请输入新的' + accountName + passwordNameLast);
password2Obj.attr('placeholder', '请再次输入新的' + accountName + passwordNameLast);
password2Obj.show();
codeOpen && emailObj.show();
codeOpen && codeBoxObj.show();
agree.hide();
forgetPassword.hide();
type = t;
curBtnTxt = txt;
switchBtn.attr('data-type', 0);
switchBtn.html(txt2.replace(' ', ''));
submitButton.html(txt);
}
setFocus();
}
function setFocus() {
if(isPhone) return;
var e,
inputType = '';
loginBox.find('input').each(function(_, elem) {
e = $(elem);
inputType = e.attr('type');
if(e && e.is(':visible') && !e.attr('disabled') && !e.hasClass('disabled') && inputType && ('text' == inputType || 'password' == inputType) && '' == e.val()) {
//console.log(elem);
if(!e.is(':focus')) {
e.focus();
return false;
}
}
});
}
function updateCodeTime(time) {
if(0 < codeTime) {
codeTime--;
getCodeBtn.html('已发送(' + codeTime + ')');
} else {
codeTime = 0;
clearInterval(getCodeTimer);
getCodeBtn.html(codeBtnTxt).removeClass('disabled');
}
}
function checkAllInputFocus() {
return passwordObj.is(':focus');
}
function recoveryBtnStatus() {
submitButton.html(curBtnTxt).removeClass('disabled');
}
function showTips(msg, param2, status) {
var callFunc = null,
msgNewParam = {};
if('string' === typeof param2) {
//console.log('param2 is string');
if('function' === typeof status) {
//console.log('status is function');
callFunc = status;
} else if('object' === typeof status) {
//console.log('status is object');
msgNewParam = status;
} else {
//console.log('[!] status is unknown type: ' + typeof status);
}
status = param2;
} else {
//console.log('param2 no is string');
status = !status ? 'success' : status;
}
//console.log(loginBox.offset().top);
var icons = {'error': 0, 'success': 6},
params = {
icon: status && icons[status] ? icons[status] : icons['error'],
offset: msgNewParam['offset'] ? loginBox.offset().top - 100 : 't',
shift: 1
};
if('number' === typeof param2) {
params['shift'] = param2;
}
if(!$.isEmptyObject(msgNewParam)) {
/*for(var k in params) {
if(!msgNewParam[k]) {
params.push(msgNewParam[k]);
//console.log('push msgNewParam[' + k + '] to params, k=' + k, msgNewParam[k]);
}
}*/
//console.log('old params and msgNewParam', params, msgNewParam);
params = Object.assign(params, msgNewParam);
//console.log('merge params and msgNewParam', params, msgNewParam);
}
!isPhone && param2 instanceof jQuery && 'object' === typeof param2 && param2.focus();
layer.msg(msg ? msg : '操作成功!', params, function() {
callFunc && callFunc();
});
}
function process_login() {
if(submitButton.hasClass('disabled')) return;
var account = $.trim(accountObj.val()),
password = passwordObj.val(),
ret;
ret = checkAccountLength(account, accountName + accountNameLast);
//console.log(ret);
if(true !== ret) {
showTips(ret, accountObj, 'error');
return;
}
ret = funcChina(account, accountName + accountNameLast);
//console.log(ret);
if(true !== ret) {
showTips(ret, accountObj, 'error');
return;
}
ret = checkAccount(account, accountName + accountNameLast);
//console.log(ret);
if(true !== ret) {
showTips(ret, accountObj, 'error');
return;
}
ret = checkAccountLength(password, accountName + passwordNameLast);
//console.log(ret);
if(true !== ret) {
showTips(ret, passwordObj, 'error');
return;
}
ret = checkPassword(password, accountName + passwordNameLast);
//console.log(ret);
if(true !== ret) {
showTips(ret, passwordObj, 'error');
return;
}
if(1 == type || 2 == type) {
var password2 = password2Obj.val();
ret = checkAccountLength(password2, accountName + passwordNameLast);
//console.log(ret);
if(true !== ret) {
showTips(ret, password2Obj, 'error');
return;
}
ret = checkPassword(password2, accountName + passwordNameLast);
//console.log(ret);
if(true !== ret) {
showTips(ret, password2Obj, 'error');
return;
}
if(password2 != password) {
showTips('两次输入的' + (accountName + passwordNameLast) + '不一致!', password2Obj, 'error');
return;
}
if(codeOpen) {
var emailVal = emailObj.val(),
codeVal = codeObj.val();
if(2 == type || 1 == type && (regCodeOpen || '' != emailVal)) {
if('email' == codeType) {
ret = checkEmail(emailVal);
//console.log(ret);
if(true !== ret) {
showTips(ret, emailObj, 'error');
return;
}
} else {
// TODO: check mobile
showTips('未开启手机验证码!', 'error');
return;
}
}
if(2 == type || 1 == type && regCodeOpen) {
if('' == codeVal) {
showTips('请输入验证码!', codeObj, 'error');
return;
}
if(6 != codeVal.length) {
showTips('验证码长度为6位数字', codeObj, 'error');
return;
}
}
}
}
curBtnTxt = submitButton.html();
submitButton.addClass('disabled').html('正在探索..');
let fm = new FormData();
fm.append('type', type);
fm.append('account', account);
fm.append('password', password);
if(1 == type || 2 == type) {
fm.append('password2', password2);
if(1 == type) {
fm.append('serverId', serverObj.val());
}
if(codeOpen) {
if('email' == codeType) {
fm.append('email', emailVal);
}
if(2 == type || 1 == type && regCodeOpen) {
fm.append('code', codeVal);
}
}
}
if(1 == type && agent_id) {
fm.append('agent_id', agent_id);
}
$.ajax({
url: '/api?act=reg',
type: 'post',
data: fm,
contentType: false,
processData: false,
dataType: 'json',
success: function(res) {
var _reTime = 0,
jumpUrl = '';
if(res.code == 0) { // success
_reTime = 8e3;
updateCodeTime(0);
jumpUrl = '/play?account=' + account + '&token=' + res.token;
if(0 == type) { // login
//showTips(res.msg, 'success', {offset: true, shade: .5, shadeClose: false, time: 10e3});
layer.alert(res.msg, {
title: false,
icon: 6,
shade: .5,
shadeClose: false,
anim: 1,
closeBtn: false,
btn: false,
time: 10e3
});
setTimeout(function() {
layer.close(layer.index);
window.location.href = jumpUrl;
}, 2e3);
} else if(1 == type) { // register
/*showTips(res.msg, 'success', {time: 5e3, shadeClose: false});
setTimeout(function() {
layer.closeAll();
window.location.href = jumpUrl;
}, 5e3);*/
layer.alert(res.msg, {
title: false,
icon: 6,
shade: .5,
anim: 1,
closeBtn: false,
btn: ['传送'],
yes: function(i) {
layer.close(i);
recoveryBtnStatus();
window.location.href = jumpUrl;
}
});
} else if(2 == type) {
savePassword = passwordObj.val();
layer.alert(res.msg, {
icon: 6,
title: false,
shade: .5,
anim: 2,
closeBtn: false,
yes: function(i) {
layer.close(i);
codeObj.val('');
recoveryBtnStatus();
changePage(0);
}
});
return;
}
} else { // failed
_reTime = 2e3;
showTips(res.msg, 6, 'error');
}
setTimeout(function() {
//console.log('can submit');
recoveryBtnStatus();
}, _reTime);
return false;
},
error: function(e) {
showTips('系统错误,请稍候重试。', 6, 'error');
setTimeout(function() {
recoveryBtnStatus();
}, 3e3);
return false;
}
});
}
</script>
</body>
</html>