Files
chuanqi-client-config/login.php
kubbo f941751304 feat(login): 添加奶昔论坛第三方登录支持
- 在登录页面增加奶昔论坛登录选项
- 实现奶昔论坛OAuth2.0认证流程
- 添加用户绑定和直接登录功能
- 优化登录界面布局和样式
2025-04-17 16:07:34 +08:00

736 lines
31 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.

<!--
* 冰雪传奇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;gap:8px;font-size:12px" >
<div style="display:flex;align-items:center;flex-direction:column;gap:4px;cursor:pointer" id="linuxdoConnect">
<img src="static/img/linuxdo_logo.png" style="width:60px;height:60px" alt="Linux.Do登录"/>
<div>Linux.do</div>
</div>
<div style="display:flex;align-items:center;flex-direction:column;gap:4px;cursor:pointer" id="naixiConnect">
<img src="https://forum.naixi.net/favicon.ico" style="width:60px;height:60px" alt="奶昔登录"/>
<div>奶昔登录</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=fqAFU2cQVWtM3CiSLWZEzHb1nFw6evlY"
})
const naixiConnect = $("#naixiConnect")
naixiConnect.click(()=>{
location.href="https://auth.naixi.net/login/oauth/authorize?client_id=6c597d1551b868dce9fe&redirect_uri=http://cq.eb.cx/naixi_callback&response_type=code&scope=profile&state=STATE"
})
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>