Authored by htoooth

add reg captcha

... ... @@ -36,12 +36,21 @@ const requiredPage = (req, res, next) => {
const generate = (req, res, next) => {
captchaService.generateCaptcha().then((result) => {
req.session.captcha = result.data.text;
return res.json({
code: 200,
data: {
images: result.data.images
}
});
if (result.code === 200) {
return res.json({
code: result.code,
data: {
images: result.data.images
}
});
} else {
return res.json({
code: result.code,
message: result.message
});
}
}).catch(next);
};
... ...
... ... @@ -23,7 +23,10 @@ exports.generateCaptcha = () => {
} else {
return {
code: 400,
message: '生成二维码失败,请重新刷新!'
message: '生成二维码失败,请重新刷新!',
data: {
text: 'yoho9636'
}
};
}
});
... ...
<div class="register-page">
<ul>
<li class="clearfix">
<select id="region" class="region" name="region">
{{#each region}}
<option {{#if selected}}selected="selected"{{/if}} value="{{areaCode}}">{{name}}</option>
{{/each}}
</select>
</li>
<li class="clearfix" data-index="0">
<span id="country-code" class="country-code">{{location}}</span>
<input value="{{#if defaultMobile}}{{defaultMobile}}{{/if}}" id="phone-num" class="input va phone-num"
type="text" name="phoneNum" placeholder="请输入手机号码" autocomplete="off">
</li>
<li class="w330 clearfix" data-index="1">
<input id="captcha" class="input va captcha" type="text" name="captcha" placeholder="图形验证码"
autocomplete="off" maxlength="4">
<img id="captcha-img" class="captcha-img" src="{{captchaUrl}}" alt="">
<a class="link change-captcha">换一张</a>
</li>
<li class="clearfix" data-index="2">
<input id="msg-captcha" class="input va msg-captcha" type="text" name="msgCaptcha" placeholder="短信验证码"
autocomplete="off" maxlength="4">
<input id="send-captcha" class="btn send-captcha disable" type="button" value="获取短信验证码">
<span id="msg-tip" class="hide msg-tip">短信验证码已发送至您的手机,请查收</span>
</li>
<li class="clearfix" data-index="3">
<input id="pwd" class="input va pwd" name="pwd" placeholder="设置密码" autocomplete="off" maxlength="20"
type="password">
<div class="pwd-intensity-container">
<span class="pwd-intensity low"></span>
<span class="pwd-intensity mid"></span>
<span class="pwd-intensity high"></span>
</div>
<div id="pwd-tips" class="hide pwd-tips">
<div class="default" id="pwd-tip1"><i></i>密码只支持6-20位字符</div>
<div class="default" id="pwd-tip2"><i></i>由字母、 数字组合,不能包含特殊符号</div>
</div>
</li>
<li class="items-container clearfix">
<input id="agree-terms" class="agree-terms" type="checkbox" checked="">
<span>
我已阅读并同意遵守
<a class="link go-yoho-items" href="{{itemUrl}}" target="_blank">YOHO!BUY 有货服务条款</a>
</span>
</li>
<li class="clearfix">
<input name="refer" id="refer" type="hidden" value="{{referUrl}}">
<input id="register-btn" class="btn register-btn disable" type="submit" value="{{regBtnText}}" disabled="">
</li>
{{# loginUrl}}
<li class="quick-login-container">
我已注册YOHO!BUY 有货账号
<a class="link go-login" href="{{.}}">快速登录</a>
</li>
{{/loginUrl}}
{{# skipUrl}}
<li class="skip-user-info">
<a href="{{.}}">跳过此步</a>
</li>
{{/skipUrl}}
</ul>
<div id="err-tip" class="err-tip hide">
<span></span>
<b></b>
</div>
<input name="" type="hidden" id="open-id" value="{{openId}}"/>
<input name="" type="hidden" id="source-type" value="{{sourceType}}"/>
</div>
<div class="register-page">
<ul>
<li class="clearfix">
<select id="region" class="region" name="region">
{{#each region}}
<option {{#if selected}}selected="selected"{{/if}} value="{{areaCode}}">{{name}}</option>
{{/each}}
</select>
</li>
<li class="clearfix" data-index="0">
<span id="country-code" class="country-code">{{location}}</span>
<input value="{{#if defaultMobile}}{{defaultMobile}}{{/if}}" id="phone-num" class="input va phone-num"
type="text" name="phoneNum" placeholder="请输入手机号码" autocomplete="off">
</li>
<li id="captcha-img" class="w330 clearfix" data-index="1">
</li>
<li class="clearfix" data-index="2">
<input id="msg-captcha" class="input va msg-captcha" type="text" name="msgCaptcha" placeholder="短信验证码"
autocomplete="off" maxlength="4">
<input id="send-captcha" class="btn send-captcha" type="button" value="获取短信验证码">
<span id="msg-tip" class="hide msg-tip">短信验证码已发送至您的手机,请查收</span>
</li>
<li class="clearfix" data-index="3">
<input id="pwd" class="input va pwd" name="pwd" placeholder="设置密码" autocomplete="off" maxlength="20"
type="password">
<div class="pwd-intensity-container">
<span class="pwd-intensity low"></span>
<span class="pwd-intensity mid"></span>
<span class="pwd-intensity high"></span>
</div>
<div id="pwd-tips" class="hide pwd-tips">
<div class="default" id="pwd-tip1"><i></i>密码只支持6-20位字符</div>
<div class="default" id="pwd-tip2"><i></i>由字母、 数字组合,不能包含特殊符号</div>
</div>
</li>
<li class="items-container clearfix">
<input id="agree-terms" class="agree-terms" type="checkbox" checked="">
<span>
我已阅读并同意遵守
<a class="link go-yoho-items" href="{{itemUrl}}" target="_blank">YOHO!BUY 有货服务条款</a>
</span>
</li>
<li class="clearfix">
<input name="refer" id="refer" type="hidden" value="{{referUrl}}">
<input id="register-btn" class="btn register-btn disable" type="submit" value="{{regBtnText}}" disabled="">
</li>
{{# loginUrl}}
<li class="quick-login-container">
我已注册YOHO!BUY 有货账号
<a class="link go-login" href="{{.}}">快速登录</a>
</li>
{{/loginUrl}}
{{# skipUrl}}
<li class="skip-user-info">
<a href="{{.}}">跳过此步</a>
</li>
{{/skipUrl}}
</ul>
<div id="err-tip" class="err-tip hide">
<span></span>
<b></b>
</div>
<input name="" type="hidden" id="open-id" value="{{openId}}"/>
<input name="" type="hidden" id="source-type" value="{{sourceType}}"/>
</div>
... ...
... ... @@ -5,7 +5,8 @@
var $ = require('yoho-jquery'),
regValidate = require('../common/mail-phone-regx'),
computeComplex = require('../common/pwd-strength');
computeComplex = require('../common/pwd-strength'),
Captcha = require('../../plugins/captcha');
var $registerPage = $('.register-page'),
$pwdTips = $('#pwd-tips'),
... ... @@ -15,18 +16,19 @@ var $registerPage = $('.register-page'),
$countDown = $('#count-down'),
$successBtn = $('.success-btn'),
countDown = 5,
clearT;
clearT,
captchaImage = new Captcha('#captcha-img').init();
var $sendCaptcha = $('#send-captcha'),
caCount = 4,
validateResult = [];
var $pn = $('#phone-num'),
$mc = $('#msg-captcha'),
$pwd = $('#pwd'),
$repwd = $('#repwd'),
$ca = $('#captcha'),
timeResidue = 0;
getCaptchaImageVal = function() {
return captchaImage.getResults();
},
timeSecond = 0;
// 密码强度验证
var $pwdIntensity = $('.pwd-intensity'),
... ... @@ -36,9 +38,6 @@ var $pwdIntensity = $('.pwd-intensity'),
var $region = $('#country-code'),
$regionSelect = $('#region');
var isPwd = false,
pwdVal;
var pwdReg = regValidate.pwdValidateRegx;
var $curErrContainer;
... ... @@ -48,20 +47,13 @@ var oldPhone = ''; // 如果手机号改变时刷新验证码
require('../../simple-header');
require('yoho-jquery-placeholder');
// 验证码位数
$ca.attr('maxlength', caCount);
// 密码规则提示
$pwd.focus(function() {
$pwdTips.removeClass('hide');
isPwd = true;
pwdVal = $(this).val();
}).blur(function() {
$pwdTips.addClass('hide');
isPwd = false;
});
// IE8 placeholder
$('[placeholder]').placeholder();
... ... @@ -73,7 +65,7 @@ validateResult = [
status: false // 当前的状态
},
{
id: 'captcha',
id: 'captcha-img',
message: '',
status: false
},
... ... @@ -96,11 +88,7 @@ validateResult = [
// 刷新图形验证码
function refreshPic() {
var time = new Date(),
$captchaImg = $('.captcha-img'),
captchaImgSrc = $captchaImg.attr('src').split('?')[0];
$captchaImg.attr('src', captchaImgSrc + '?t=' + time.getTime());
captchaImage.refresh();
}
// 手机号ajax校验
... ... @@ -127,13 +115,17 @@ function phoneAjaxFn(page, callback) {
validateResult[0].message = 'err';
validateResult[0].status = false;
$.ajax({
return $.ajax({
url: url,
type: 'POST',
data: data
}).then(function(res) {
var defer = $.Deferred();
defer.always(callback);
if (!res) {
return;
return defer.reject().promise();
}
switch (res.code) {
... ... @@ -143,8 +135,7 @@ function phoneAjaxFn(page, callback) {
// 如果手机号发生改变则刷新验证码并且更新状态
refreshPic();
$sendCaptcha.addClass('disable').attr('disabled', 'disabled');
validateResult[1].message = '图形验证码错误';
validateResult[1].message = 'err';
validateResult[1].status = false;
}
... ... @@ -152,58 +143,28 @@ function phoneAjaxFn(page, callback) {
validateResult[0].message = '';
validateResult[0].status = true;
break;
return defer.resolve().promise();
case 400:
refreshPic();
validateResult[0].message = res.message;
validateResult[0].status = false;
break;
return defer.reject().promise();
default:
break;
return defer.reject().promise();
}
callback();
});
}
// 图形验证码ajax校验
function picCaptchaAjaxFn(page, callback) {
var url;
if (page === 'reg') {
url = '/passport/reg/piccaptcha';
} else if (page === 'third') {
url = '/passport/autouserinfo/checkPicCode';
}
$.ajax({
type: 'POST',
url: url,
data: {
verifyCode: $ca.val()
// mobile: $pn.val(),
// area: $region.text().split('+')[1]
}
}).then(function(data) {
if (!data) {
return;
}
switch (data.code) {
case 200:
validateResult[1].message = '';
validateResult[1].status = true;
break;
case 400:
refreshPic();
validateResult[1].message = '图形验证码错误';
validateResult[1].status = false;
break;
default:
break;
}
callback();
});
function picCaptchaAjaxFn(callback) {
return captchaImage.check().then(function() {
validateResult[1].message = '';
validateResult[1].status = true;
}).fail(function() {
validateResult[1].message = 'err';
validateResult[1].status = false;
}).always(callback);
}
// 短信验证码ajax校验
... ... @@ -215,7 +176,8 @@ function msgCaptchaAjaxFn(page, callback) {
} else if (page === 'third') {
url = '/passport/autouserinfo/checkBindMsg';
}
$.ajax({
return $.ajax({
type: 'POST',
url: url,
data: {
... ... @@ -224,24 +186,26 @@ function msgCaptchaAjaxFn(page, callback) {
area: $region.text().split('+')[1]
}
}).then(function(data) {
var defer = $.Deferred();
defer.always(callback);
if (!data) {
return;
return defer.reject().promise();
}
switch (data.code) {
case 200:
validateResult[2].message = '';
validateResult[2].status = true;
break;
return defer.resolve().promise();
case 400:
validateResult[2].message = '短信验证码错误';
validateResult[2].status = false;
break;
return defer.reject().promise();
default:
break;
return defer.reject().promise();
}
callback();
});
}
... ... @@ -251,56 +215,45 @@ function validateRule(page, $element, callback) {
var val = $.trim($element.val()),
regionCode;
// 根据需求http://redmine.yoho.cn/issues/3117改成上边的正则
// 对应的错误提示语也改了,感觉要不了多久就会改回来
// pwdReg = /^([a-zA-Z0-9\-\+_!@\#$%\^&\*\(\)\:\;\.=\[\]\\\',\?]){6,20}$/gi;
var defer = $.Deferred();
defer.always(callback);
// 手机号校验
if ($element.hasClass('phone-num')) {
regionCode = $region.text();
if (val === '') {
validateResult[0].message = '请输入手机号码';
validateResult[0].status = false;
return callback();
return defer.reject().promise();
} else {
if (!/^[0-9]+$/.test(val) ||
(regionCode === '+86' && !regValidate.phoneRegx[regionCode].test(val))) {
validateResult[0].message = '手机号码格式不正确,请重新输入';
validateResult[0].status = false;
return callback();
return defer.reject().promise();
} else {
phoneAjaxFn(page, callback);
return phoneAjaxFn(page, callback);
}
}
// 图形验证码校验
} else if ($element.hasClass('captcha')) {
if (val === '') {
validateResult[1].message = '请输入图形验证码';
validateResult[1].status = false;
return callback();
} else if (val.length <= 3) {
validateResult[1].message = '图形验证码为4位';
validateResult[1].status = false;
return callback();
} else if ($element.hasClass('w330')) {
// 并且手机号正确
if (validateResult[0].status) {
return picCaptchaAjaxFn(callback);
} else {
// 并且手机号正确
if (validateResult[0].status) {
picCaptchaAjaxFn(page, callback);
} else {
validateResult[1].message = '图形验证码错误';
validateResult[1].status = false;
return callback();
}
validateResult[1].message = 'err';
validateResult[1].status = false;
return defer.reject().promise();
}
// 短信验证码校验
... ... @@ -309,22 +262,22 @@ function validateRule(page, $element, callback) {
if (val === '') {
validateResult[2].message = '请输入短信验证码';
validateResult[2].status = false;
return callback();
return defer.reject().promise();
} else if (val.length <= 3) {
validateResult[2].message = '短信验证码错误';
validateResult[2].status = false;
return callback();
return defer.reject().promise();
} else {
// 并且图形验证码正确
if (validateResult[1].status) {
msgCaptchaAjaxFn(page, callback);
return msgCaptchaAjaxFn(page, callback);
} else {
validateResult[2].message = '短信验证码错误';
validateResult[2].status = false;
return callback();
return defer.reject().promise();
}
}
... ... @@ -333,39 +286,23 @@ function validateRule(page, $element, callback) {
if (val === '') {
validateResult[3].message = '请输入密码';
validateResult[3].status = false;
return defer.reject().promise();
} else if (val.length < 6 || val.length > 20) {
validateResult[3].message = '密码只支持6-20位字符';
validateResult[3].status = false;
return defer.reject().promise();
} else if (!pwdReg.test($element.val())) {
validateResult[3].message = '密码须字母和数字组合';
validateResult[3].status = false;
return defer.reject().promise();
} else {
validateResult[3].message = '';
validateResult[3].status = true;
return defer.resolve().promise();
}
return callback();
// 二次密码校验
} else if ($element.hasClass('repwd')) {
if (val === '') {
validateResult[4].message = '请输入密码确认';
validateResult[4].status = false;
} else if ($pwd.val() !== val) {
validateResult[4].message = '与密码不一致,请重新输入';
validateResult[4].status = false;
} else {
validateResult[4].message = '';
validateResult[4].status = true;
}
return callback();
}
return defer.promise();
}
function posErrTip() {
... ... @@ -411,7 +348,7 @@ function showBorder() {
validateResultLen = validateResult.length;
for (i = 0; i < validateResultLen; i++) {
if (validateResult[i].message) {
if (validateResult[i].message && validateResult[i].message !== 'err') {
// 显示红色边框
$errInput = $('#' + validateResult[i].id);
... ... @@ -489,6 +426,8 @@ $(window).resize(function() {
// ( ▼-▼ )注册页和信息完善页面接口不同
exports.init = function(page) {
captchaImage.refresh();
$('#agree-terms').click(function() {
var $this = $(this),
... ... @@ -551,16 +490,6 @@ exports.init = function(page) {
} else {
$registerBtn.addClass('disable').attr('disabled', 'disabled');
}
// 图形验证通过时,发送短信按钮可点击
if (validateResult[1].status && timeResidue <= 0) {
$sendCaptcha.removeClass('disable').removeAttr('disabled');
} else {
$sendCaptcha.addClass('disable').attr('disabled', 'disabled');
}
// 图形验证通过时,发送短信按钮可点击 end
});
// 如果是密码则校验强度
... ... @@ -568,12 +497,6 @@ exports.init = function(page) {
pwdFn($that);
}
}).blur(function() {
/* validateRule($(this), function() {
showErrTip();
showBorder(); // 显示红色边框
});*/
});
$regionSelect.change(function() {
... ... @@ -598,37 +521,46 @@ exports.init = function(page) {
url = '/passport/autouserinfo/sendBindMsg';
}
// todo ajax 发送验证码
$.ajax({
type: 'POST',
url: url,
data: {
area: $region.text().split('+')[1],
mobile: $pn.val(),
verifyCode: $ca.val()
}
}).then(function(result) {
if (result.code !== 200) {
validateResult[0].message = result.message;
validateResult[0].status = false;
showErrTip();
return;
}
$('#msg-tip').removeClass('hide');
timeResidue = 60;
$sendCaptcha.addClass('disable').attr('disabled', 'disabled');
$sendCaptcha.val('60秒可重新发送');
// 1.验证图形验证码是否正确
// 2.验证手机号被注册过
// 3.发送短信
captchaImage.check().then(function() {
return validateRule(page, $pn, function() {
showErrTip(); // 显示错误提示
showBorder(); // 显示红色边框
});
}).then(function() {
return $.ajax({
type: 'POST',
url: url,
data: {
area: $region.text().split('+')[1],
mobile: $pn.val(),
verifyCode: getCaptchaImageVal()
}
}).then(function(result) {
if (result.code !== 200) {
validateResult[0].message = result.message;
validateResult[0].status = false;
t = setInterval(function() {
if (timeResidue <= 0) {
$sendCaptcha.removeClass('disable').removeAttr('disabled').val('获取短信验证码');
clearInterval(t);
showErrTip();
return;
}
$sendCaptcha.val(timeResidue-- + '秒可重新发送');
}, 1000);
$('#msg-tip').removeClass('hide');
timeSecond = 60;
$sendCaptcha.addClass('disable').attr('disabled', 'disabled');
$sendCaptcha.val('60秒可重新发送');
t = setInterval(function() {
if (timeSecond <= 0) {
$sendCaptcha.removeClass('disable').removeAttr('disabled').val('获取短信验证码');
clearInterval(t);
return;
}
$sendCaptcha.val(timeSecond-- + '秒可重新发送');
}, 1000);
});
});
});
... ... @@ -660,7 +592,7 @@ exports.init = function(page) {
data: {
area: $region.text().split('+')[1],
mobile: $pn.val(),
verifyCode: $ca.val(),
verifyCode: getCaptchaImageVal(),
code: $mc.val(),
password: $pwd.val()
}
... ... @@ -703,10 +635,6 @@ exports.init = function(page) {
}
});
$('.change-captcha').click(function() {
refreshPic();
});
// 注册成功页面5秒后跳转
if ($('.success-box').length > 0) {
clearT = setInterval(function() {
... ...
... ... @@ -90,6 +90,10 @@ Captcha.prototype = {
return $.get(uri)
.done(function(result) {
if (result.code !== 200) {
return self.showTip();
}
var src = result.data.images;
self.render({
... ...
... ... @@ -4,6 +4,7 @@
.img-check {
margin-top: 25px;
margin-bottom: 25px;
width: 270px;
}
.img-check-header {
... ... @@ -32,8 +33,8 @@
float: left;
background-size: 240px 240px;
background: #575757 no-repeat;
width: 60px;
height: 60px;
width: 60px !important;
height: 60px !important;
border: 1px #e0e0e0 solid;
margin-right: 7px;
... ...