Authored by htoooth

fix

@@ -55,13 +55,10 @@ passport.use('local', new LocalStrategy({ @@ -55,13 +55,10 @@ passport.use('local', new LocalStrategy({
55 const captchaNeeded = await req.ctx(CaptchaServiceModel).try(); 55 const captchaNeeded = await req.ctx(CaptchaServiceModel).try();
56 56
57 if (result.code === 50004) { 57 if (result.code === 50004) {
58 - return done({  
59 - code: result.code,  
60 - message: result.message,  
61 - needCaptcha: captchaNeeded,  
62 - username: encodeURIComponent(username),  
63 - password: encodeURIComponent(password)  
64 - }); 58 + req.session.forceBind = {
  59 + username,
  60 + password
  61 + };
65 } 62 }
66 63
67 return done({ 64 return done({
@@ -17,8 +17,6 @@ const config = global.yoho.config; @@ -17,8 +17,6 @@ const config = global.yoho.config;
17 const cert = { 17 const cert = {
18 index: (req, res) => { 18 index: (req, res) => {
19 let refer = req.query.refer || `${config.siteUrl}`; 19 let refer = req.query.refer || `${config.siteUrl}`;
20 - let username = req.query.username;  
21 - let password = req.query.password;  
22 20
23 res.render('cert/index', { 21 res.render('cert/index', {
24 region: passportHelper.getCountry(), 22 region: passportHelper.getCountry(),
@@ -29,8 +27,6 @@ const cert = { @@ -29,8 +27,6 @@ const cert = {
29 simpleHeader: simpleHeaderModel.setSimpleHeaderData(), 27 simpleHeader: simpleHeaderModel.setSimpleHeaderData(),
30 module: 'passport', 28 module: 'passport',
31 page: 'cert', 29 page: 'cert',
32 - username,  
33 - password,  
34 title: '登录完善信息' 30 title: '登录完善信息'
35 }); 31 });
36 }, 32 },
@@ -93,45 +89,26 @@ const cert = { @@ -93,45 +89,26 @@ const cert = {
93 check: (req, res, next) => { 89 check: (req, res, next) => {
94 let mobile = req.body.mobile; 90 let mobile = req.body.mobile;
95 let area = req.body.area || '86'; 91 let area = req.body.area || '86';
  92 + let code = req.body.code;
96 93
97 - if (mobile && area) {  
98 -  
99 - /**  
100 - * 接口绑定返回值:  
101 - * code:200,isCanBind=Y // 可绑定  
102 - * code:200,isCanBind=Y // 不可绑定  
103 - */  
104 -  
105 - req.ctx(CertService).certCheck(mobile, area).then(result => {  
106 - if (!result || !result.code) {  
107 - return {code: 400, message: '', data: ''};  
108 - } else if (result.code === 200) {  
109 - let nextUrl;  
110 -  
111 - if (_.get(result, 'data.isCanBind') === 'Y') {  
112 - nextUrl = helpers.urlFormat('/passport/cert/cert');  
113 - return {code: 200, message: result.message, data: {next: nextUrl}};  
114 - } else {  
115 - // 不可以关联  
116 - return {code: 403, message: '绑定失败,该手机号已注册,请更换或使用该手机号直接登录'};  
117 - }  
118 - } else {  
119 - return {code: result.code, message: result.message, data: result.data ? result.data : ''};  
120 - }  
121 - }).then(result => {  
122 - return res.json(result);  
123 - }).catch(next);  
124 - } else { 94 + if (!mobile || !area || !code) {
125 return res.json({code: 400, message: '', data: ''}); 95 return res.json({code: 400, message: '', data: ''});
126 } 96 }
  97 +
  98 + req.ctx(CertService).certCheck(mobile, area, code).then(({error, result}) => {
  99 + if (error) {
  100 + return res.json({code: 400, message: '验证错误,请重新登录', data: ''});
  101 + }
  102 +
  103 + return res.json({code: 200, data: result});
  104 + }).catch(next);
127 }, 105 },
128 sendCertMsg: (req, res, next) => { 106 sendCertMsg: (req, res, next) => {
129 let mobile = req.body.mobile; 107 let mobile = req.body.mobile;
130 let area = req.body.area; 108 let area = req.body.area;
131 - let id = req.session.id;  
132 - let captcha = req.body.verifyCode;  
133 109
134 - req.ctx(CertService).sendCertMsg(mobile, area, id, captcha).then(result => { 110 + req.ctx(CertService).sendCertMsg(mobile, area).then(result => {
  111 + console.log(result);
135 if (result && result.code) { 112 if (result && result.code) {
136 return res.json(result); 113 return res.json(result);
137 } else { 114 } else {
@@ -140,37 +117,48 @@ const cert = { @@ -140,37 +117,48 @@ const cert = {
140 }).catch(next); 117 }).catch(next);
141 }, 118 },
142 certMobile: (req, res, next) => { 119 certMobile: (req, res, next) => {
143 -  
144 - let uid = req.user.uid;  
145 let mobile = _.trim(req.body.mobile); 120 let mobile = _.trim(req.body.mobile);
146 let area = _.trim(req.body.area) || '86'; 121 let area = _.trim(req.body.area) || '86';
147 let code = _.trim(req.body.code); 122 let code = _.trim(req.body.code);
148 - let refer = req.body.refer;  
149 123
150 - req.ctx(CertService).certMobile(uid, mobile, code, area).then(result => { 124 + if (!code) {
  125 + return {
  126 + code: 400,
  127 + message: '短信验证码错误'
  128 + };
  129 + }
151 130
152 - if (result && result.code === 200) {  
153 - let url = helpers.urlFormat('/passport/cert/success', {  
154 - type: 'cert',  
155 - refer: refer  
156 - }); 131 + if (!req.session.forceBind ||
  132 + !req.session.forceBind.username ||
  133 + !req.session.forceBind.password
  134 + ) {
  135 + return {
  136 + code: 400,
  137 + message: '请重新登录'
  138 + };
  139 + }
157 140
158 - return {  
159 - code: 200,  
160 - message: result.message,  
161 - data: {  
162 - nextUrl: url  
163 - }  
164 - };  
165 - } else {  
166 - return {  
167 - code: _.get(result, 'code', 400), 141 + req.ctx(CertService).certMobile(
  142 + req.session.forceBind.username,
  143 + req.session.forceBind.password,
  144 + mobile, code, area
  145 + ).then(result => {
  146 + delete req.session.forceBind;
  147 +
  148 + if (!result || result.code !== 200) {
  149 + return res.json({
  150 + code: 400,
168 message: _.get(result, 'message') || '操作错误,请稍后再试!' 151 message: _.get(result, 'message') || '操作错误,请稍后再试!'
169 - }; 152 + });
170 } 153 }
171 - }).then(result => {  
172 - res.json(result);  
173 - }).catch(next); 154 +
  155 + return res.json({
  156 + code: 200
  157 + });
  158 + }).catch(() => {
  159 + delete req.session.forceBind;
  160 + next();
  161 + });
174 }, 162 },
175 relateMobile: (req, res, next) => { 163 relateMobile: (req, res, next) => {
176 let uid = req.user.uid; 164 let uid = req.user.uid;
@@ -156,10 +156,7 @@ const local = { @@ -156,10 +156,7 @@ const local = {
156 data: { 156 data: {
157 needCaptcha: err.needCaptcha, 157 needCaptcha: err.needCaptcha,
158 type: err.type, 158 type: err.type,
159 - session: helpers.urlFormat('/passport/cert/index', {  
160 - username: user.username,  
161 - password: user.password  
162 - }) 159 + session: helpers.urlFormat('/passport/cert/index')
163 } 160 }
164 }); 161 });
165 } 162 }
@@ -4,40 +4,37 @@ @@ -4,40 +4,37 @@
4 4
5 'use strict'; 5 'use strict';
6 6
7 -const PAGE = 'pc';  
8 -  
9 module.exports = class extends global.yoho.BaseModel { 7 module.exports = class extends global.yoho.BaseModel {
10 constructor(ctx) { 8 constructor(ctx) {
11 super(ctx); 9 super(ctx);
12 } 10 }
13 11
14 - certCheck(mobile, area) { 12 + certCheck(mobile, area, code) {
15 let params = { 13 let params = {
16 - method: 'app.passport.checkIsCanBind', 14 + method: 'app.bind.changeMobileCheck',
17 area: area, 15 area: area,
18 - mobile: mobile 16 + mobile: mobile,
  17 + code: code
19 }; 18 };
20 19
21 return this.get({data: params}); 20 return this.get({data: params});
22 } 21 }
23 22
24 - sendCertMsg(mobile, area, id, captcha) { 23 + sendCertMsg(mobile, area) {
25 let params = { 24 let params = {
26 - method: 'app.passport.smsbind', 25 + method: 'app.bind.sendChangeBindMobileCodeOnly',
27 mobile: mobile, 26 mobile: mobile,
28 area: area, 27 area: area,
29 - udid: id,  
30 - degrees: captcha,  
31 - fromPage: PAGE,  
32 }; 28 };
33 29
34 return this.get({data: params}); 30 return this.get({data: params});
35 } 31 }
36 32
37 - certMobile(uid, mobile, code, area) { 33 + certMobile(username, password, mobile, code, area) {
38 let params = { 34 let params = {
39 - method: 'app.passport.changeMobile',  
40 - uid: uid, 35 + method: 'app.bind.bindEmailLoginMobile',
  36 + email: username,
  37 + password,
41 mobile: mobile, 38 mobile: mobile,
42 area: area, 39 area: area,
43 code: code 40 code: code
@@ -3,8 +3,6 @@ @@ -3,8 +3,6 @@
3 const CertApi = require('./cert-api'); 3 const CertApi = require('./cert-api');
4 const CaptchaImgService = require('./captcha-img-service'); 4 const CaptchaImgService = require('./captcha-img-service');
5 5
6 -const _ = require('lodash');  
7 -  
8 module.exports = class extends global.yoho.BaseModel { 6 module.exports = class extends global.yoho.BaseModel {
9 constructor(ctx) { 7 constructor(ctx) {
10 super(ctx); 8 super(ctx);
@@ -12,19 +10,24 @@ module.exports = class extends global.yoho.BaseModel { @@ -12,19 +10,24 @@ module.exports = class extends global.yoho.BaseModel {
12 this.api = new CertApi(ctx); 10 this.api = new CertApi(ctx);
13 this.captchaService = new CaptchaImgService(ctx); 11 this.captchaService = new CaptchaImgService(ctx);
14 12
15 - this.certCheck = this.api.certCheck.bind(this.api); 13 + this.sendCertMsg = this.api.sendCertMsg.bind(this.api);
  14 +
16 this.certMobile = this.api.certMobile.bind(this.api); 15 this.certMobile = this.api.certMobile.bind(this.api);
17 this.relateMobile = this.api.relateMobile.bind(this.api); 16 this.relateMobile = this.api.relateMobile.bind(this.api);
18 this.checkEmailCertTip = this.api.checkEmailCertTip.bind(this.api); 17 this.checkEmailCertTip = this.api.checkEmailCertTip.bind(this.api);
19 } 18 }
20 19
21 - async sendCertMsg(mobile, area, id, captcha) {  
22 - let result = await this.api.sendCertMsg(mobile, area, id, captcha);  
23 - let captchaNeed = await this.captchaService.try(); 20 + async certCheck(mobile, area, smsCode) {
  21 + let {code, data} = await this.api.certCheck(mobile, area, smsCode);
24 22
25 - _.set(result, 'data.needCaptcha', captchaNeed); 23 + if (!code || code !== 200) {
  24 + return {
  25 + error: new Error('error')
  26 + };
  27 + }
26 28
27 - return result; 29 + return {
  30 + result: data
  31 + };
28 } 32 }
29 -  
30 }; 33 };
@@ -78,6 +78,7 @@ router.post('/passport/autouserinfo/relateMobile', bind.relateMobile); @@ -78,6 +78,7 @@ router.post('/passport/autouserinfo/relateMobile', bind.relateMobile);
78 // 未实名认证的老邮箱用户登录 78 // 未实名认证的老邮箱用户登录
79 router.get('/passport/cert/index', cert.index); /** 输入手机号码页面 **/ 79 router.get('/passport/cert/index', cert.index); /** 输入手机号码页面 **/
80 router.get('/passport/cert/success', cert.success); /** 成功提示页面 **/ 80 router.get('/passport/cert/success', cert.success); /** 成功提示页面 **/
  81 +router.post('/passport/cert/check', cert.check);
81 router.post('/passport/cert/sendCertMsg', cert.sendCertMsg); 82 router.post('/passport/cert/sendCertMsg', cert.sendCertMsg);
82 router.post('/passport/cert/certMobile', cert.certMobile); 83 router.post('/passport/cert/certMobile', cert.certMobile);
83 84
@@ -6,9 +6,6 @@ @@ -6,9 +6,6 @@
6 6
7 <p class="safeword">为了您的账户安全,请您完善账户信息,以便为您提供更优质的服务!</p> 7 <p class="safeword">为了您的账户安全,请您完善账户信息,以便为您提供更优质的服务!</p>
8 <form action="" id="bindmobileform" method="post"> 8 <form action="" id="bindmobileform" method="post">
9 - <input type="hidden" id="username" name="username" value="{{username}}"/>  
10 - <input type="hidden" id="password" name="password" value="{{password}}"/>  
11 -  
12 <input type="hidden" value="86" id="areacode" name="area"/> 9 <input type="hidden" value="86" id="areacode" name="area"/>
13 <input type="hidden" name="refer" value="{{refer}}"> 10 <input type="hidden" name="refer" value="{{refer}}">
14 <div class="yohobindrow" style="margin-bottom: 10px;"> 11 <div class="yohobindrow" style="margin-bottom: 10px;">
@@ -46,21 +43,23 @@ @@ -46,21 +43,23 @@
46 <div class="yohobindrow"> 43 <div class="yohobindrow">
47 <div class="name phonetag">验证码</div> 44 <div class="name phonetag">验证码</div>
48 <div class="content"> 45 <div class="content">
49 - <div class="yohophonewrapper" style="width: 130px;">  
50 - <input type="text" class="validatenum phonenum" value="" id="validatenum" maxlength="4"/> 46 + <div class="yohophonewrapper" style="width: 110px;">
  47 + <input type="text" class="validatenum phonenum" value="" id="smscode" maxlength="4"/>
51 <span class="err-tip code-err-tip hide"> 48 <span class="err-tip code-err-tip hide">
52 <i></i> 49 <i></i>
53 - <em></em> 50 + <em>短信验证码错误</em>
54 </span> 51 </span>
55 </div> 52 </div>
56 </div> 53 </div>
57 <div class="validatewrapper"> 54 <div class="validatewrapper">
58 <a href="javascript:void(0)" id="sendmessage" class="yohobindbtn left" 55 <a href="javascript:void(0)" id="sendmessage" class="yohobindbtn left"
59 - style="width: 130px; margin-left: 10px; height: 48px;">发送短信验证码</a> 56 + style="width: 150px; margin-left: 10px; height: 48px;">发送短信验证码</a>
60 </div> 57 </div>
61 - <div class="hide left" id="nopermissionmessage">  
62 - <span class="second">60</span>  
63 - 秒后可重新操作 58 + <div class="hide" id="nopermissionmessage">
  59 + <div class="second-timer">
  60 + <span class="second">60</span>
  61 + 秒后可重新操作
  62 + </div>
64 </div> 63 </div>
65 </div> 64 </div>
66 </form> 65 </form>
  1 +
  2 +<div>
  3 + <div class="title"> 该手机号已被注册,是否选择绑定?</div>
  4 + <div class="title2"> 点击“继续”原注册账号将被停用。</div>
  5 +</div>
  1 +<div>
  2 + <div class="title"> 该手机号已绑定Yoho!Family其他账号,</div>
  3 + <div class="question" > 点击“继续”将解绑并绑定当前账号。</div>
  4 + <div class="question"> 是否继续?</div>
  5 + <div class="subtitle">解绑后原帐号将不能使用该手机号登录!</div>
  6 +</div>
  1 +
  2 +var Dialog = require('../../common/dialog').Dialog;
  3 +var infoTpl = require('hbs/passport/bind-info.hbs');
  4 +var infoTpl2 = require('hbs/passport/bind-info2.hbs');
  5 +
  6 +exports.showBind = function(goLoginCb, goNextCb) {
  7 + var dia = new Dialog({
  8 + className: 'bind-info-wrapper',
  9 + closeIcon: true,
  10 + content: infoTpl(),
  11 + btns: [{
  12 + id: 'login',
  13 + btnClass: ['btn-cancel'],
  14 + name: '去登录',
  15 + cb: function() {
  16 + console.log('login');
  17 + goLoginCb && goLoginCb();
  18 + }
  19 + }, {
  20 + id: 'next',
  21 + btnClass: ['btn-ok'],
  22 + name: '继续',
  23 + cb: function() {
  24 + console.log('next');
  25 + goNextCb && goNextCb();
  26 + }
  27 + }]
  28 + });
  29 +
  30 + dia.show();
  31 +};
  32 +
  33 +
  34 +exports.showBind2 = function(goLoginCb, goNextCb) {
  35 + var dia2 = new Dialog({
  36 + className: 'bind-info-wrapper',
  37 + closeIcon: true,
  38 + content: infoTpl2(),
  39 + btns: [{
  40 + id: 'login',
  41 + btnClass: ['btn-cancel'],
  42 + name: '去登录',
  43 + cb: function() {
  44 + goLoginCb && goLoginCb();
  45 + }
  46 + }, {
  47 + id: 'next',
  48 + btnClass: ['btn-ok'],
  49 + name: '继续',
  50 + cb: function() {
  51 + goNextCb && goNextCb();
  52 + }
  53 + }]
  54 + });
  55 +
  56 + dia2.show();
  57 +};
1 /** 1 /**
2 - * 第三方登录首页  
3 - * @author: wq  
4 - * @date: 2016/1/21 2 + * 邮箱登录绑定手机
  3 + * @author: htoo
  4 + * @date: 2018/1/18
5 */ 5 */
6 var $ = require('yoho-jquery'); 6 var $ = require('yoho-jquery');
7 var phoneRegx = require('../common/mail-phone-regx').phoneRegx; 7 var phoneRegx = require('../common/mail-phone-regx').phoneRegx;
@@ -12,6 +12,7 @@ var $wrapper = $('.bindwrapper'), @@ -12,6 +12,7 @@ var $wrapper = $('.bindwrapper'),
12 $nextBtn = $wrapper.find('.yohobindbtn'); 12 $nextBtn = $wrapper.find('.yohobindbtn');
13 13
14 var Alert = require('../../common/dialog').Alert; 14 var Alert = require('../../common/dialog').Alert;
  15 +var dialog = require('./dialog');
15 16
16 var nopermissionoption = $('#nopermissionmessage').html(); 17 var nopermissionoption = $('#nopermissionmessage').html();
17 var sendmessagehtml = $('.validatewrapper').html(); 18 var sendmessagehtml = $('.validatewrapper').html();
@@ -164,6 +165,20 @@ function fixAreaNum() { @@ -164,6 +165,20 @@ function fixAreaNum() {
164 }); 165 });
165 } 166 }
166 167
  168 +function goLogin() {
  169 + window.jumpUrl('/signin.html');
  170 +}
  171 +
  172 +function goBind(area, mobile, code) {
  173 + $.post('/passport/cert/certMobile', { area, mobile, code }).then(function(result) {
  174 + if (result.code !== 200) {
  175 + return window.alert(result.message); // eslint-disable-line
  176 + }
  177 +
  178 + window.jumpUrl('/passport/cert/success');
  179 + });
  180 +}
  181 +
167 182
168 /** 183 /**
169 * 点击下一步 184 * 点击下一步
@@ -172,6 +187,7 @@ function fixAreaNum() { @@ -172,6 +187,7 @@ function fixAreaNum() {
172 function nextStep() { 187 function nextStep() {
173 var mobile = ''; 188 var mobile = '';
174 var areaCode = ''; 189 var areaCode = '';
  190 + var smsCode = '';
175 191
176 $('#bindfirststep').on('click', function(e) { 192 $('#bindfirststep').on('click', function(e) {
177 var regx; 193 var regx;
@@ -180,6 +196,7 @@ function nextStep() { @@ -180,6 +196,7 @@ function nextStep() {
180 mobile = $('.phonenum').val(); 196 mobile = $('.phonenum').val();
181 areaCode = $('#areanum').text(); 197 areaCode = $('#areanum').text();
182 regx = phoneRegx['+' + areaCode]; 198 regx = phoneRegx['+' + areaCode];
  199 + smsCode = $('#smscode').val();
183 200
184 if (!isagree()) { 201 if (!isagree()) {
185 return; 202 return;
@@ -190,22 +207,39 @@ function nextStep() { @@ -190,22 +207,39 @@ function nextStep() {
190 return; 207 return;
191 } 208 }
192 209
  210 + if (!$.trim(smsCode)) {
  211 + return;
  212 + }
  213 +
193 $.ajax({ 214 $.ajax({
194 type: 'post', 215 type: 'post',
195 url: '/passport/cert/check', 216 url: '/passport/cert/check',
196 data: { 217 data: {
197 mobile: mobile, 218 mobile: mobile,
198 - area: areaCode 219 + area: areaCode,
  220 + code: smsCode
199 }, 221 },
200 dataType: 'json', 222 dataType: 'json',
201 success: function(data) { 223 success: function(data) {
  224 + var isBind, isRegister;
  225 +
  226 + if (data.code === 200) {
  227 + isBind = data.data && data.data.isBind;
  228 + isRegister = data.data && data.data.isRegister;
202 229
203 - if (data.code === 200) { // 绑定/关联  
204 - $('#bindmobileform').attr('action', data.data.next);  
205 - $('#bindmobileform').submit();  
206 - } else if (data.code === 402) {  
207 - $phoneTip.find('em').text('手机格式错误');  
208 - $phoneTip.removeClass('hide'); 230 + if (isRegister === 'Y') {
  231 + if (isBind === 'N') {
  232 + dialog.showBind(goLogin, function() {
  233 + goBind(areaCode, mobile, smsCode);
  234 + });
  235 + } else {
  236 + dialog.showBind2(goLogin, function() {
  237 + goBind(areaCode, mobile, smsCode);
  238 + });
  239 + }
  240 + } else {
  241 + goBind(areaCode, mobile, smsCode);
  242 + }
209 } else { 243 } else {
210 if (data && data.message) { 244 if (data && data.message) {
211 new Alert(data.message).show(); 245 new Alert(data.message).show();
@@ -109,14 +109,15 @@ @@ -109,14 +109,15 @@
109 content: ""; 109 content: "";
110 } 110 }
111 111
112 - #nopermissionmessage { 112 + .second-timer {
113 display: block; 113 display: block;
114 color: black; 114 color: black;
  115 + float: left;
115 background-color: #d8d8d8; 116 background-color: #d8d8d8;
116 text-align: center; 117 text-align: center;
117 font-size: 16px; 118 font-size: 16px;
118 line-height: 45px; 119 line-height: 45px;
119 - width: 130px; 120 + width: 150px;
120 margin-left: 10px; 121 margin-left: 10px;
121 height: 48px; 122 height: 48px;
122 } 123 }
@@ -798,3 +799,59 @@ @@ -798,3 +799,59 @@
798 background: resolve("passport/angle.png"); 799 background: resolve("passport/angle.png");
799 } 800 }
800 } 801 }
  802 +
  803 +.bind-info-wrapper {
  804 + .iconfont {
  805 + font-size: 25px;
  806 + }
  807 +
  808 + .title {
  809 + font-size: 20px;
  810 + margin-top: 50px;
  811 + margin-bottom: 10px;
  812 + }
  813 +
  814 + .title2 {
  815 + font-size: 20px;
  816 + margin-bottom: 55px;
  817 + }
  818 +
  819 + .question {
  820 + font-size: 20px;
  821 + margin-bottom: 10px;
  822 + }
  823 +
  824 + .subtitle {
  825 + font-size: 16px;
  826 + color: #999;
  827 + margin-top: 24px;
  828 + margin-bottom: 43px;
  829 + }
  830 +
  831 + .btn-cancel {
  832 + border-radius: 3px;
  833 + width: 120px;
  834 + height: 35px;
  835 + line-height: 35px;
  836 + color: #999;
  837 + border: solid 1px #999;
  838 + padding: 0 !important;
  839 + }
  840 +
  841 + .btn-ok {
  842 + width: 120px;
  843 + height: 35px;
  844 + color: white;
  845 + background: #444;
  846 + border-radius: 3px;
  847 + line-height: 35px;
  848 + border: solid 1px #444;
  849 + padding: 0 !important;
  850 + margin-left: 38px !important;
  851 + }
  852 +
  853 + min-width: 320px !important;
  854 + padding-left: 55px;
  855 + padding-right: 55px;
  856 + padding-bottom: 40px;
  857 +}