index.js 9.9 KB
/**
 * @description 登录
 * @author TaoHuang
 * @time 2016/7/14
 */

var $ = require('yoho-jquery');
var EventProxy = require('yoho-eventproxy');

var $phoneNumInput = $('#account'),
    $passwordInput = $('#password'),
    $imgCaptchaInput = $('#captcha'),
    $loginBtn = $('#login-btn'),
    $phone = $('#phone');

var $loginTip = $loginBtn.siblings('.login-fail-tip'),
    ep = new EventProxy();

var $regionCodeText = $('#country-code'),
    $regionSelectList = $('#country-select-list'),
    $regionSelectHeader = $('#country-select-header');

var $emailAutoComplete = $('#email-autocomplete');

var mailPhoneRegx = require('../common/mail-phone-regx');
var mailAc = require('../common/ac-email'); // 邮箱自动完成

var $remember = $('.remember-me');

var captchaUrl = '/passport/images?t='; // /passport/images?t=1454464125

var $captchaWrap = $('.captcha-wrap'),
    $captchaImg = $captchaWrap.find('#captcha-img');

// checkbox status unicode
var checkbox = {
    checked: '',
    unchecked: ''
};

var upDown = {
    up: '',
    down: ''
};

var selectedIcon = '';

require('yoho-jquery-placeholder');

function errTip(ele, msg) {
    var $errTip = ele.next('.tips');
    var $errMsg = $errTip.find('.content');

    $errMsg.text(msg);
    return $errTip.removeClass('hide');
}

function hideTip(ele) {
    return ele.next('.tips').addClass('hide');
}

// 验证账户名
function validateAccountLocal() {
    var phoneNum = $.trim($phoneNumInput.val()),
        regionCode = $regionCodeText.text();

    if (phoneNum !== '') {
        if (/^[0-9]+$/.test(phoneNum)) {

            // 这里只做中国区验证
            if (regionCode === '+86') {
                if (phoneNum.length === 11 && mailPhoneRegx.phoneRegx['+86'].test(phoneNum)) {
                    return true;
                } else {
                    errTip($phoneNumInput, '手机号码不正确,请重新输入');
                    return false;
                }
            }

            return true;
        } else {

            // 邮箱验证
            if (mailPhoneRegx.emailRegx.test(phoneNum)) {
                return true;
            } else {
                errTip($phoneNumInput, '邮箱格式不正确,请重新输入');
                return false;
            }
        }

    } else {
        errTip($phoneNumInput, '请输入账号');
        return false;
    }
}

// 异步验证帐号是否存在
function validateAccountAsync() {
    return $.ajax({
        type: 'POST',
        url: '/passport/login/user',
        data: {
            phoneNum: $phoneNumInput.val(),
            area: $regionCodeText.text().replace('+', '')
        }
    }).then(function(data) {
        if (data.code && data.code === 200) {
            return true;
        } else {
            errTip($phoneNumInput, '账号不存在');
            return false;
        }
    });
}

// 整合本地和异步验证信息
function validateAccount() {
    function validate() {
        var defer = $.Deferred(); // eslint-disable-line

        if (validateAccountLocal()) {
            validateAccountAsync().then(function(result) {
                if (result) {
                    defer.resolve(result);
                } else {
                    defer.reject(result);
                }
            });
        } else {
            defer.reject(false);
        }

        return defer.promise();
    }

    return validate().then(function() {
        hideTip($phoneNumInput);
        ep.emit('phone', true);
    }).fail(function() {
        ep.emit('phone', false);
    });
}

// 验证密码
function validatePasswordLocal() {
    var password = $.trim($passwordInput.val());
    var length = password.length;

    if (length !== 0) {
        if (length < 6) {
            ep.emit('password', false);
            errTip($passwordInput, '请输入长度为6-20字符的密码');
            return false;
        } else {
            ep.emit('password', true);
            return true;
        }
    } else {
        errTip($passwordInput, '请输入密码');
        ep.emit('password', false);
        return false;
    }
}

// 验证验证码
function validateCaptchaLocal() {
    var captcha = $.trim($imgCaptchaInput.val());
    var length = captcha.length;

    if ($captchaWrap.hasClass('hide')) {
        ep.emit('captcha', true);
        return;
    }

    switch (length) {
        case 0:
            errTip($imgCaptchaInput, '请输入验证码');
            ep.emit('captcha', false);
            break;
        case 4:
            ep.emit('captcha', true);
            break;
        default:
            errTip($imgCaptchaInput, '请输入长度为4字符的验证码');
            ep.emit('captcha', false);
            break;
    }
}

// 密码错误次数,超过三次显示验证码
function showAccountErrTimes() {
    $captchaWrap.removeClass('hide');
    $captchaImg.attr('src', captchaUrl + $.now());
    $imgCaptchaInput.val('');
}

// 登录
function login() {
    $.ajax({
        url: '/passport/login/auth',
        type: 'POST',
        data: {
            areaCode: $regionCodeText.text().replace('+', ''),
            account: $.trim($phoneNumInput.val()),
            password: $.trim($passwordInput.val()),
            captcha: $.trim($imgCaptchaInput.val()),
            isRemember: $remember.hasClass('checked') ? true : false
        },
        success: function(res) {
            if (res.code === 200) {
                if (res.data) {

                    // 防止data.data为undefined时下行语句执行出错而导致脚本不能走到complete去处理authing
                    location.href = res.data.refer;
                }
            } else {
                if (res.data.errorType === 'captcha') {
                    $imgCaptchaInput.val('');
                } else {
                    $loginTip.removeClass('hide').children('em').html(res.message);
                    $passwordInput.val('');
                }

                // 验证错误次数
                if (res.data && res.data.needCaptcha) {
                    showAccountErrTimes();
                }
            }
        }
    });
}

// 邮箱自动补全,并验证信息
mailAc($phoneNumInput, function() {
    function throttle() {
        return $.ajax({
            url: '/passport/login/account',
            type: 'GET',
            data: {
                account: $.trim($phoneNumInput.val())
            }
        });
    }

    validateAccount().then(function(result) {
        if (result) {
            return throttle();
        } else {
            return false;
        }
    }).then(function(res) {
        if (!res) {
            return;
        }

        if (res.data && res.data.needCaptcha) {
            showAccountErrTimes();
        }
    });
});

$phoneNumInput.on('focus', function() {
    hideTip($phoneNumInput);
    $phone.addClass('focus');
}).on('blur', function() {
    $phone.removeClass('focus');
});

$('[placeholder]').placeholder();

// 改变选择图标
function changeHeader() {
    var $indicator = $regionSelectHeader.find('.iconfont');

    if ($regionSelectList.hasClass('hide')) {
        $indicator.html(upDown.up);
    } else {
        $indicator.html(upDown.down);
    }
}

// 选择国家列表
$regionSelectList.on('click', '.option', function() {
    var $clickItem = $(this);
    var areaCode = $clickItem.data('code');
    var name = $clickItem.data('value');
    var $selectedItem = $clickItem.siblings('.selected');

    $selectedItem.find('.iconfont').html('').end().removeClass('selected');

    $clickItem.find('.iconfont').html(selectedIcon).end().addClass('selected');

    $regionSelectHeader.find('.name').html(name);
    $regionCodeText.text(areaCode);

    $regionSelectList.addClass('hide');
    changeHeader();
});

// 选择国家头
$regionSelectHeader.on('click', function() {
    $regionSelectList.toggleClass('hide');
    changeHeader();
});

// 密码
$passwordInput.on('blur', function() {
    $passwordInput.removeClass('focus');
    validatePasswordLocal();
}).on('focus', function() {
    $passwordInput.addClass('focus');

    hideTip($passwordInput);
});

// 验证码
$imgCaptchaInput.on('blur', function() {
    $imgCaptchaInput.removeClass('focus');
    validateCaptchaLocal();
}).on('focus', function() {
    $imgCaptchaInput.addClass('focus');
});

// 邮箱自动完成列表项点击
$emailAutoComplete.on('click', 'li', function() {
    $phoneNumInput.val($(this).text()).focus();
    $emailAutoComplete.addClass('hide');
});

// 记住登录状态
$remember.on('click', function() {
    var $this = $(this);

    $this.toggleClass('checked');

    if ($this.hasClass('checked')) {
        $this.children('span').html(checkbox.checked);
    } else {
        $this.children('span').html(checkbox.unchecked);
    }
});

// 验证码刷新
$captchaWrap.on('click', '.change-captcha, .captcha-img', function() {
    $captchaImg.attr('src', captchaUrl + $.now());
});

// 初始:只带账户名的页面,密码输入获得焦点
if (($phoneNumInput.val() !== '' || $phoneNumInput.val() === $phoneNumInput.attr('placeholder')) &&
    $passwordInput.val() === '') {
    $passwordInput.focus();
}

// 同时监听三个事件
ep.tail('phone', 'password', 'captcha', function(phoneAuth, passwordAuth, captchaAuth) {
    if (phoneAuth && passwordAuth && captchaAuth) {
        $loginBtn.removeClass('auth_ok');
    } else {
        $loginBtn.addClass('auth_ok');
    }
});

ep.on('phone', function(auth) {
    if (auth) {
        hideTip($phoneNumInput);
    }
});

ep.on('password', function(auth) {
    if (auth) {
        hideTip($passwordInput);
    }
});

ep.on('captcha', function(auth) {
    if (auth && !$captchaWrap.hasClass('hide')) {
        hideTip($imgCaptchaInput);
    }
});

// 登录
$loginBtn.on('click', function() {
    if ($loginBtn.hasClass('auth_ok')) {
        return;
    }

    login();
});

// Enter登录
$('input.va').on('keypress', function(e) {
    if (e.which === 13) {
        login();
    }
});

// 首次触发
$imgCaptchaInput.triggerHandler('blur');