Authored by htoooth

refactor代码

... ... @@ -6,72 +6,120 @@
* @author: tao.huang<tao.huang@yoho.cn>
* @date: 2016/8/29
*/
/**************************************************************************/
/* 流程 */
/**************************************************************************/
/**
* 登录分为:普通登录(使用帐户和密码登录)和手机验证码登录(使用手机号和验证短信登录)
*
* 每种登录的流程都是一致的,具体如下:
* 1. 各个输入框失去焦点验证(包括本地和网络)。
* 2. 验证包括:本地(Local)和网络(Async)。本地主要是格式验证,网络是服务器验证。
* 3. 在登录之前,还有预验证(pre),包括之前所有的验证。
*
* 普通登录
* 帐号验证 => 密码验证 => 图形验证码验证 => 登录之前验证 => 登录
*
* 手机验证码登录
* 帐号验证 => 手机短信验证 => 图形验证码验证 => 登录之前验证 => 登录
*/
/**************************************************************************/
/* 引入第三方库 */
/**************************************************************************/
var $ = require('yoho-jquery');
var $accountInput = $('#account'),
$passwordInput = $('#password'),
$captchaImg = $('#captcha'),
$captchaSMSInput = $('#captcha-sms'),
$captchaSMSBtn = $('.change-captcha-sms'),
$captchaSMSToken = $('#captcha-sms-token-hide');
/**************************************************************************/
/* 初始化变量 */
/**************************************************************************/
var $accountTip = $accountInput.siblings('.err-tip'),
$passwordTip = $passwordInput.siblings('.err-tip'),
$captchaImgTip = $captchaImg.siblings('.err-tip'),
$captchaSMSTip = $captchaSMSInput.siblings('.err-tip'),
$capsLock = $('#caps-lock');
// 帐号
var $accountInput = $('#account'),
getAccountVal = function() {
return $.trim($accountInput.val());
},
var $countryCodeInput = $('#country-code-hide'),
$countryCodeHeader = $('#country-code > em'),
$countryList = $('#country-list');
// 密码
$passwordInput = $('#password'),
getPasswordVal = function() {
return $.trim($passwordInput.val());
},
var $emailAutoComplete = $('#email-autocomplete');
// 图像验证码
$captchaImgInput = $('#captcha'),
$captchaWrap = $('.captcha-wrap'),
getCaptchaImgVal = function() {
return $.trim($captchaImgInput.val());
},
var mailPhoneRegx = require('../common/mail-phone-regx');
var mailAc = require('../common/ac-email'); // 邮箱自动完成
// 短信验证码
$captchaSmsInput = $('#captcha-sms'),
getCaptchaSmsVal = function() {
return $.trim($captchaSmsInput.val());
},
$captchaSmsBtn = $('.change-captcha-sms'),
$captchaSMSToken = $('#captcha-sms-token-hide'),
var $remember = $('.remember-me');
// 区域选择
$countryCodeInput = $('#country-code-hide'),
getAreaCodeVal = function() {
return $countryCodeInput.val().replace('+', '');
},
$countryCodeHeader = $('#country-code > em'),
$countryList = $('#country-list'),
var captchaUrl = '/passport/imagesNode?t='; // /passport/images?t=1454464125
// 记住我
$rememberMe = $('.remember-me');
var $captchaWrap = $('.captcha-wrap'),
$captchaImgInput = $captchaWrap.find('#captcha-img');
// 提示
var $accountTip = $accountInput.siblings('.err-tip'),
$passwordTip = $passwordInput.siblings('.err-tip'),
$captchaImgTip = $captchaImgInput.siblings('.err-tip'),
$captchaSmsTip = $captchaSmsInput.siblings('.err-tip'),
$capsLock = $('#caps-lock');
var $changLoginType = $.Callbacks(); //eslint-disable-line
var mailPhoneRegx = require('../common/mail-phone-regx'), //邮箱格式验证
mailAc = require('../common/ac-email'); // 邮箱自动完成
var currentLogin = null;
// 图像验证码URL
var CAPTCHA_IMG_URL = '/passport/imagesNode?t='; // /passport/images?t=1454464125
// checkbox status unicode
var checkbox = {
// 记住我符号
var checkboxSymbol = {
checked: '&#xe612;',
unchecked: '&#xe613;'
};
// 短信验证码的时间间隔,60s
var second = 60;
var emailAcTime;
/**************************************************************************/
/* 登录类型设置 */
/**************************************************************************/
var changeLoginTypeEvent = $.Callbacks(); //eslint-disable-line
var currentLogin = null;
var $switchLoginType = $('.switch');
var LoginType = {
PasswordLogin: {
ele: '.password-login',
validateAccountAsync: function() {
// true 存在
// false 不存在
return $.ajax({
url: '/passport/login/password/checkuser',
type: 'POST',
data: {
phoneNum: $.trim($accountInput.val()),
area: $countryCodeInput.val().replace('+', '')
phoneNum: getAccountVal(),
area: getAreaCodeVal()
}
}).then(function(result) {
var defer = $.Deferred(); // eslint-disable-line
var defer = $.Deferred(); // eslint-disable-line
if (result.code === 200) {
hideAccountTip();
hideAccountTip(); // eslint-disable-line
defer.resolve();
} else {
showAccountTip(result.message);
showAccountTip(result.message); // eslint-disable-line
defer.reject();
}
... ... @@ -79,12 +127,12 @@ var LoginType = {
});
},
creditableToken: function() {
return $.trim($passwordInput.val());
return getPasswordVal();
},
type: function() {
return 'password';
},
validate: validateByPassword
validate: prePasswordLoginWithValidate // eslint-disable-line
},
SMSLogin: {
ele: '.sms-login',
... ... @@ -93,17 +141,17 @@ var LoginType = {
url: '/passport/login/sms/checkuser',
type: 'POST',
data: {
mobile: $.trim($accountInput.val()),
area: $countryCodeInput.val().replace('+', '')
mobile: getAccountVal(),
area: getAreaCodeVal()
}
}).then(function(result) {
var defer = $.Deferred(); // eslint-disable-line
var defer = $.Deferred(); // eslint-disable-line
if (result.code === 200) {
hideAccountTip();
hideAccountTip(); // eslint-disable-line
defer.resolve();
} else {
showAccountTip(result.message);
showAccountTip(result.message); // eslint-disable-line
defer.reject();
}
... ... @@ -111,25 +159,45 @@ var LoginType = {
});
},
creditableToken: function() {
return $.trim($captchaSMSToken.val());
return getCaptchaSmsVal();
},
type: function() {
return 'sms';
},
validate: validateBySMS
validate: preSmsLoginWithValidate // eslint-disable-line
}
};
$changLoginType.add(function(type) {
// 切换登录方式
changeLoginTypeEvent.add(function(type) {
currentLogin = LoginType[type];
});
require('../../simple-header');
// 清除输入状态
changeLoginTypeEvent.add(function() {
hideAccountTip(); // eslint-disable-line
hideCaptchaImgTip(); // eslint-disable-line
hideCaptchaSmsTip(); // eslint-disable-line
hidePasswordTip(); // eslint-disable-line
$captchaImgInput = $captchaWrap.find('#captcha');
$captchaImgTip = $captchaWrap.find('.err-tip');
// clear input state
$accountInput.val('');
$passwordInput.val('');
$captchaImgInput.val('');
$captchaSmsInput.val('');
});
/**************************************************************************/
/* 加载自定义库 */
/**************************************************************************/
require('../../simple-header');
require('yoho-jquery-placeholder');
require('../../common');// yas
/**************************************************************************/
/* 错误提示框 */
/**************************************************************************/
function errTipShow($tip, $input, msg) {
$tip.removeClass('hide').children('em').empty().html(msg);
... ... @@ -141,6 +209,8 @@ function errTipHide($tip, $input) {
$input.removeClass('error');
}
/**************************************************************************/
// 帐号
function showAccountTip(msg) {
return errTipShow($accountTip, $accountInput, msg);
}
... ... @@ -149,14 +219,18 @@ function hideAccountTip() {
return errTipHide($accountTip, $accountInput);
}
/**************************************************************************/
// 密码
function showPasswordTip(msg) {
return errTipShow($passwordTip, $passwordInput, msg);
}
function hidePassword() {
function hidePasswordTip() {
return errTipHide($passwordTip, $passwordInput);
}
/**************************************************************************/
// 图形验证码
function showCaptchaImgTip(msg) {
return errTipShow($captchaImgTip, $captchaImgInput, msg);
}
... ... @@ -165,18 +239,24 @@ function hideCaptchaImgTip() {
return errTipHide($captchaImgTip, $captchaImgInput);
}
function showCaptchaSMSTip(msg) {
return errTipShow($captchaSMSTip, $captchaSMSInput, msg);
/**************************************************************************/
// 短信验证码
function showCaptchaSmsTip(msg) {
return errTipShow($captchaSmsTip, $captchaSmsInput, msg);
}
function hideCaptchaSMSTip() {
return errTipHide($captchaSMSTip, $captchaSMSInput);
function hideCaptchaSmsTip() {
return errTipHide($captchaSmsTip, $captchaSmsInput);
}
// 验证账户名
/**************************************************************************/
/* 用户帐号验证 */
/**************************************************************************/
// 本地验证用户输入格式
function validateAccountLocal() {
var account = $.trim($accountInput.val()),
countryCode = $countryCodeInput.val(),
var account = getAccountVal(),
countryCode = getAreaCodeVal(),
err;
var defer = $.Deferred(); // eslint-disable-line
... ... @@ -205,25 +285,28 @@ function validateAccountLocal() {
}
if (defer.state() === 'resolved') {
hideAccountTip;
hideAccountTip();
} else {
showAccountTip(err);
}
return defer.promise();
}
// 本地验证和网络验证
function validateAccount() {
return validateAccountLocal().then(function() {
return currentLogin.validateAccountAsync();
}).then(function() {
hideAccountTip();
return null;
});
return validateAccountLocal()
.then(currentLogin.validateAccountAsync)
.then(hideAccountTip);
}
// 验证密码
/**************************************************************************/
/* 密码验证 */
/**************************************************************************/
// 本地验证密码格式
function validatePasswordLocal() {
var password = $.trim($passwordInput.val()),
var password = getPasswordVal(),
err;
var defer = $.Deferred(); // eslint-disable-line
... ... @@ -241,16 +324,20 @@ function validatePasswordLocal() {
}
if (defer.state() === 'resolved') {
hidePassword();
hidePasswordTip();
} else {
showPasswordTip(err);
}
return defer.promise();
}
// 验证图形验证码
/**************************************************************************/
/* 图形验证码 */
/**************************************************************************/
// 本地验证图形验证码格式
function validateCaptchaImgLocal() {
var captcha = $.trim($captchaImgInput.val()),
var captcha = getCaptchaImgVal(),
err;
var defer = $.Deferred(); // eslint-disable-line
... ... @@ -276,12 +363,13 @@ function validateCaptchaImgLocal() {
return defer.promise();
}
// 网络验证图形验证码格式
function validateCaptchaImgAsync() {
return $.ajax({
url: '/passport/captcha/img',
type: 'POST',
data: {
verifyCode: $.trim($captchaImgInput.val())
verifyCode: getCaptchaImgVal()
}
}).then(function(result) {
var defer = $.Deferred(); // eslint-disable-line
... ... @@ -298,8 +386,8 @@ function validateCaptchaImgAsync() {
});
}
// 本地和网络验证图形验证码
function validateCaptchaImg() {
// 验证码不可见的时候验证通过
if ($captchaWrap.is(':hidden')) {
return $.Deferred().resolve().promise(); //eslint-disable-line
... ... @@ -313,9 +401,13 @@ function validateCaptchaImg() {
});
}
// 验证短信验证码
function validateCaptchaSMSLocal() {
var captcha = $.trim($captchaSMSInput.val()),
/**************************************************************************/
/* 短信验证码 */
/**************************************************************************/
// 本地验证短信验证码格式
function validateCaptchaSmsLocal() {
var captcha = getCaptchaSmsVal(),
err;
var defer = $.Deferred(); // eslint-disable-line
... ... @@ -333,32 +425,33 @@ function validateCaptchaSMSLocal() {
}
if (defer.state() === 'resolved') {
hideCaptchaSMSTip();
hideCaptchaSmsTip();
} else {
showCaptchaSMSTip(err);
showCaptchaSmsTip(err);
}
return defer.promise();
}
function validateCaptchaSMSAsync() {
// 网络验证短信验证码
function validateCaptchaSmsAsync() {
return $.ajax({
url: '/passport/login/sms/auth',
type: 'POST',
data: {
area: $countryCodeInput.val().replace('+', ''),
mobile: $.trim($accountInput.val()),
code: $.trim($captchaSMSInput.val())
area: getAreaCodeVal(),
mobile: getAccountVal(),
code: getCaptchaSmsVal()
}
}).then(function(result) {
var defer = $.Deferred(); // eslint-disable-line
if (result.code === 200) {
hideCaptchaSMSTip();
hideCaptchaSmsTip();
$captchaSMSToken.val(result.token);
defer.resolve();
} else {
showCaptchaSMSTip('验证码不正确');
showCaptchaSmsTip('验证码不正确');
defer.reject();
}
... ... @@ -366,28 +459,40 @@ function validateCaptchaSMSAsync() {
});
}
function validateCaptchaSMS() {
return validateCaptchaSMSLocal().then(function() {
return validateCaptchaSMSAsync();
}).then(function() {
hideCaptchaSMSTip();
return null;
});
// 本地和网络验证短信验证码
function validateCaptchaSms() {
return validateCaptchaSmsLocal()
.then(validateCaptchaSmsAsync)
.then(hideCaptchaSmsTip);
}
/**************************************************************************/
/* 全部验证过程 */
/**************************************************************************/
// 密码验证过程
function validateWithPasswordMode() {
return $.when(validateAccount(), validatePasswordLocal(), validateCaptchaImg());
return validateAccount()
.then(validatePasswordLocal)
.then(validateCaptchaImg);
}
function validateWithSMSMode() {
return $.when(validateAccount, validateCaptchaSMS(), validateCaptchaImg());
// 短信验证过程
function validateWithSmsMode() {
return validateAccount()
.then(validateCaptchaSms)
.then(validateCaptchaImg);
}
// password验证
function validateByPassword() {
/**************************************************************************/
/* 登录之前验证 */
/**************************************************************************/
// password登录之前验证
function prePasswordLoginWithValidate() {
return (function() {
var account = $.trim($accountInput.val()),
password = $.trim($passwordInput.val());
var account = getAccountVal(),
password = getPasswordVal();
var defer = $.Deferred(); // eslint-disable-line
... ... @@ -405,16 +510,14 @@ function validateByPassword() {
}
return defer.resolve().promise();
}()).then(function() {
return validateWithPasswordMode();
});
}()).then(validateWithPasswordMode);
}
// SMS验证
function validateBySMS() {
// sms登录之前验证
function preSmsLoginWithValidate() {
return (function() {
var account = $.trim($accountInput.val()),
password = $.trim($captchaSMSInput.val());
var account = getAccountVal(),
password = getCaptchaSmsVal();
var defer = $.Deferred(); // eslint-disable-line
... ... @@ -433,18 +536,63 @@ function validateBySMS() {
}
return defer.resolve().promise();
}()).then(function() {
return validateWithSMSMode();
});
}()).then(validateWithSmsMode);
}
/**************************************************************************/
/* 帮助函数 */
/**************************************************************************/
// 密码错误次数,超过三次显示验证码
function vaAccountErrTimes() {
$captchaImgInput.attr('src', captchaUrl + $.now());
$captchaImgInput.attr('src', CAPTCHA_IMG_URL + $.now());
$captchaImgInput.val('');
$captchaWrap.removeClass('hide');
}
// 短信验证码重新发送
function switchSmsBtnState() {
second -= 1;
if (second < 0) {
second = 60;
$captchaSmsBtn.text('获取短信验证码').removeClass('second-progress');
} else {
$captchaSmsBtn.addClass('second-progress').text(second + '秒后可重新操作');
window.setTimeout(switchSmsBtnState, 1000);
}
}
// 发送短信验证码
function sendCaptchaSmsAsync() {
return $.ajax({
type: 'POST',
url: '/passport/login/sms/send',
data: {
area: getCaptchaSmsVal(),
mobile: getAccountVal()
}
});
}
// 检查验证次数
function checkUserAuthCountAsync() {
return $.ajax({
url: '/passport/login/account',
type: 'GET',
data: {
account: getAccountVal()
}
}).then(function(res) {
if (res.data && res.data.needCaptcha) {
vaAccountErrTimes();
}
});
}
/**************************************************************************/
/* 登录函数 */
/**************************************************************************/
// 登录
function login() {
return currentLogin.validate().then(function() {
... ... @@ -452,60 +600,43 @@ function login() {
url: '/passport/login/auth',
type: 'POST',
data: {
areaCode: $countryCodeInput.val().replace('+', ''),
account: $.trim($accountInput.val()),
areaCode: getAreaCodeVal(),
account: getAccountVal(),
password: currentLogin.creditableToken(),
captcha: $.trim($captchaImgInput.val()),
isRemember: $remember.hasClass('checked') ? true : false,
captcha: getCaptchaImgVal(),
isRemember: $rememberMe.hasClass('checked') ? true : false,
loginType: currentLogin.type()
},
success: function(res) {
if (res.code === 200) {
if (res.data) {
// 防止data.data为undefined时下行语句执行出错而导致脚本不能走到complete去处理authing
location.href = res.data.session;
}
} else {
if (res.data.errorType === 'captcha') {
$captchaImgTip.removeClass('hide').children('em').html(res.message);
$captchaImgInput.addClass('error').val('');
} else {
$passwordTip.removeClass('hide').children('em').html(res.message);
$passwordInput.addClass('error').val('');
}
// 验证错误次数
if (res.data && res.data.needCaptcha) {
vaAccountErrTimes();
}
}
}
});
});
}
}).then(function(res) {
if (res.code === 200) {
if (res.data) {
mailAc($accountInput, function() {
if (validateAccountLocal()) {
$.ajax({
url: '/passport/login/account',
type: 'GET',
data: {
account: $.trim($accountInput.val())
// 防止data.data为undefined时下行语句执行出错而导致脚本不能走到complete去处理authing
location.href = res.data.session;
}
} else {
if (res.data.errorType === 'captcha') {
$captchaImgTip.removeClass('hide').children('em').html(res.message);
$captchaImgInput.addClass('error').val('');
} else {
$passwordTip.removeClass('hide').children('em').html(res.message);
$passwordInput.addClass('error').val('');
}
}).then(function(res) {
// 验证错误次数
if (res.data && res.data.needCaptcha) {
vaAccountErrTimes();
}
});
}
});
}
});
}
$('[placeholder]').placeholder();
/**************************************************************************/
/* 事件绑定 */
/**************************************************************************/
$accountInput.on('blur', function() {
validateAccount();
});
$('[placeholder]').placeholder(); // ie8 兼容 placeholder
// 展开地区列表
$('#country-code').on('click', function() {
... ... @@ -535,7 +666,16 @@ $(document).on('click', function(e) {
}
});
// 密码
/**************************************************************************/
// 邮箱自动完成后失去焦点:1. 本地验证格式;2.服务器检查用户是否注册;3.检查验证用户次数
mailAc($accountInput, function() {
return validateAccountLocal().then(function() {
return currentLogin.validateAccountAsync().always(checkUserAuthCountAsync);
});
});
// 密码输入框事件
$passwordInput.on('blur', function() {
validatePasswordLocal();
... ... @@ -555,73 +695,46 @@ $passwordInput.on('blur', function() {
$capsLock.addClass('hide');
});
// 图像验证码
// 图像验证码输入框事件
$captchaImgInput.on('blur', function() {
validateCaptchaImgLocal();
validateCaptchaImg();
});
// sms验证码
$captchaSMSInput.on('blur', function() {
validateCaptchaSMSLocal();
// sms验证码输入框事件
$captchaSmsInput.on('blur', function() {
validateCaptchaSms();
});
// 短信验证码重新发送
function disableSMSBtn() {
second -= 1;
if (second < 0) {
second = 60;
$captchaSMSBtn.text('获取短信验证码').removeClass('disable').removeClass('second-progress');
} else {
$captchaSMSBtn.addClass('second-progress').text(second + '秒后可重新操作');
window.setTimeout(disableSMSBtn, 1000);
}
}
function sendSMSCaptcha() {
return $.ajax({
type: 'POST',
url: '/passport/login/sms/send',
data: {
area: $countryCodeInput.val().replace('+', ''),
mobile: $.trim($accountInput.val())
}
});
}
// 发送短信验证码
$captchaSMSBtn.on('click', function() {
var val = $.trim($captchaSMSInput.val());
// 短信验证码发送按钮
$captchaSmsBtn.on('click', function() {
var val = getAccountVal();
if (val === '') {
showAccountTip('请输入账户名');
return;
}
if (!$captchaSMSBtn.hasClass('second-progress')) {
disableSMSBtn();
sendSMSCaptcha();
// 已在发送短信时间范围内
if ($captchaSmsBtn.hasClass('second-progress')) {
return;
}
});
// 邮箱自动完成列表项点击
$emailAutoComplete.on('click', 'li', function() {
clearTimeout(emailAcTime); // 清空默认关闭
$accountInput.val($(this).text()).focus();
$emailAutoComplete.addClass('hide');
currentLogin.validateAccountAsync().then(function() {
switchSmsBtnState();
return sendCaptchaSmsAsync();
});
});
// 记住登录状态
$remember.on('click', function() {
$rememberMe.on('click', function() {
var $this = $(this);
$this.toggleClass('checked');
if ($this.hasClass('checked')) {
$this.children('i').html(checkbox.checked);
$this.children('i').html(checkboxSymbol.checked);
} else {
$this.children('i').html(checkbox.unchecked);
$this.children('i').html(checkboxSymbol.unchecked);
}
});
... ... @@ -630,31 +743,15 @@ $('.va').on('focus', function() {
var $this = $(this);
$this.removeClass('error');
$this.siblings('.err-tip').addClass('hide');
});
// 验证码刷新
$captchaWrap.on('click', '.change-captcha, .captcha-img', function() {
$captchaImgInput.attr('src', captchaUrl + $.now());
});
// 登录
$('#login-btn').on('click', login);
// Enter登录
$('input.va').on('keypress', function(e) {
if (e.which === 13) {
login();
}
$captchaImgInput.attr('src', CAPTCHA_IMG_URL + $.now());
});
// 初始:只带账户名的页面,密码输入获得焦点
if (($accountInput.val() !== '' || $accountInput.val() === $accountInput.attr('placeholder')) &&
$passwordInput.val() === '') {
$passwordInput.focus();
}
// 切换登录模式:密码登录和短信登录
$switchLoginType.on('click', 'div', function() {
var $this = $(this),
type = $this.data('type');
... ... @@ -663,7 +760,7 @@ $switchLoginType.on('click', 'div', function() {
return;
}
$changLoginType.fire(type);
changeLoginTypeEvent.fire(type);
$this.addClass('selected');
$this.siblings().removeClass('selected');
... ... @@ -671,4 +768,33 @@ $switchLoginType.on('click', 'div', function() {
$(LoginType[type].ele).removeClass('hide').siblings('.login').addClass('hide');
});
$changLoginType.fire('PasswordLogin'); // 默认为密码登录
\ No newline at end of file
/**************************************************************************/
/* 登录 */
/**************************************************************************/
// click登录
$('#login-btn').on('click', login);
// enter登录
$('input.va').on('keypress', function(e) {
if (e.which === 13) {
login();
}
});
/**************************************************************************/
/* 初始化 */
/**************************************************************************/
// 初始化为密码登录
changeLoginTypeEvent.fire('PasswordLogin');
// 只带账户名的页面,密码输入获得焦点
if (($accountInput.val() !== '' || $accountInput.val() === $accountInput.attr('placeholder')) &&
$passwordInput.val() === '') {
$passwordInput.focus();
}
/**************************************************************************/
/* 结束 */
/**************************************************************************/
\ No newline at end of file
... ...