Authored by 姜枫

完成第三方登录绑定

@@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
10 const helpers = require(global.library + '/helpers'); 10 const helpers = require(global.library + '/helpers');
11 const RegService = require('../models/reg-service'); 11 const RegService = require('../models/reg-service');
12 const BindService = require('../models/bind-service'); 12 const BindService = require('../models/bind-service');
  13 +const AuthHelper = require('../models/auth-helper');
13 const _ = require('lodash'); 14 const _ = require('lodash');
14 15
15 const Sources = { 16 const Sources = {
@@ -90,14 +91,14 @@ const bind = { @@ -90,14 +91,14 @@ const bind = {
90 91
91 if (result.code === 200) { 92 if (result.code === 200) {
92 let nextUrl = helpers.urlFormat('/passport/bind/code', { 93 let nextUrl = helpers.urlFormat('/passport/bind/code', {
93 - isReg: res.data.is_register, // esline-disable-line 94 + isReg: result.data.is_register, // esline-disable-line
94 openId: openId, 95 openId: openId,
95 sourceType: sourceType, 96 sourceType: sourceType,
96 areaCode: areaCode, 97 areaCode: areaCode,
97 phoneNum: phoneNum 98 phoneNum: phoneNum
98 }); 99 });
99 100
100 - data.data.isReg = res.data.is_register; 101 + data.data.isReg = result.data.is_register;
101 data.data.next = nextUrl; 102 data.data.next = nextUrl;
102 } else { 103 } else {
103 data.data = result.data; 104 data.data = result.data;
@@ -112,6 +113,142 @@ const bind = { @@ -112,6 +113,142 @@ const bind = {
112 data: '' 113 data: ''
113 }); 114 });
114 } 115 }
  116 + },
  117 +
  118 + sendBindMsg: (req, res) => {
  119 + let phoneNum = req.body.phoneNum;
  120 + let areaCode = req.body.areaCode;
  121 +
  122 + if (req.xhr && _.isNumber(parseInt(phoneNum, 0)) && areaCode) {
  123 + BindService.sendBindMsg(areaCode, phoneNum).then(result => {
  124 + if (result && result.code) {
  125 + res.json(result);
  126 + } else {
  127 + res.json({ code: 400, message: '', data: '' });
  128 + }
  129 + });
  130 + } else {
  131 + res.json({ code: 400, message: '', data: '' });
  132 + }
  133 + },
  134 +
  135 + checkBindMsg: (req, res) => {
  136 + let phoneNum = req.body.phoneNum;
  137 + let code = req.body.code;
  138 + let areaCode = req.body.areaCode;
  139 +
  140 + if (_.isNumber(parseInt(phoneNum, 0)) && code && areaCode) {
  141 + BindService.checkBindMsg(areaCode, phoneNum, code).then(result => {
  142 + if (result && result.code) {
  143 + res.json(result);
  144 + } else {
  145 + res.json({ code: 400, message: '', data: '' });
  146 + }
  147 + });
  148 + } else {
  149 + res.json({ code: 400, message: '', data: '' });
  150 + }
  151 + },
  152 +
  153 + bindMobile: (req, res) => {
  154 + let phoneNum = req.body.phoneNum;
  155 + let openId = req.body.openId;
  156 + let areaCode = req.body.areaCode || '86';
  157 + let sourceType = req.body.sourceType;
  158 + let code = req.body.code;
  159 + let password = req.body.password || '';
  160 +
  161 + if (_.isNumber(parseInt(phoneNum)) && openId && sourceType && areaCode && code) {
  162 + BindService.checkBindCode(areaCode, phoneNum, code).then(result => {
  163 + if (result && result.code && result.code === 200) {
  164 + return BindService.bindMobile(openId, sourceType, phoneNum, areaCode, password);
  165 + } else {
  166 + return { code: 400, message: '短信验证码错误', data: '' };
  167 + }
  168 + }).then(result => {
  169 + let refer = req.cookies.refer;
  170 +
  171 + refer = refer ? decodeURI(refer) : helpers.urlFormat();
  172 + if (result && result.code && result.code === 200 && result.data.uid) {
  173 + AuthHelper.syncUserSession(result.data.uid, req, res);
  174 + result.data.refer = refer;
  175 + }
  176 + return result;
  177 + }).then(result => {
  178 + res.json(result);
  179 + });
  180 + } else {
  181 + res.json({ code: 400, message: '', data: '' });
  182 + }
  183 + },
  184 +
  185 + relateMobile: (req, res) => {
  186 + let phoneNum = req.body.phoneNum;
  187 + let openId = req.body.openId;
  188 + let areaCode = req.body.areaCode || '86';
  189 + let sourceType = req.body.sourceType;
  190 + let code = req.body.code;
  191 +
  192 + if (_.isNumber(parseInt(phoneNum, 0)) && openId && areaCode && sourceType && code) {
  193 + BindService.checkBindCode(areaCode, phoneNum, code).then(result => {
  194 + if (result && result.code && result.code === 200) {
  195 + return BindService.relateMobile(openId, sourceType, phoneNum, code);
  196 + } else {
  197 + return { code: 400, message: '短信验证码错误', data: '' };
  198 + }
  199 + }).then(result => {
  200 + let refer = helpers.urlFormat('/passport/bind/success', { sourceType: sourceType });
  201 +
  202 + if (result && result.code && result.code === 200 && result.data.uid) {
  203 + AuthHelper.syncUserSession(result.data.uid, req, res);
  204 + result.data.refer = refer;
  205 + }
  206 + return result;
  207 + }).then(result => {
  208 + res.json(result);
  209 + });
  210 + } else {
  211 + res.json({ code: 400, message: '', data: '' });
  212 + }
  213 + },
  214 +
  215 + successPage: (req, res) => {
  216 + res.render('bind/success', {
  217 + isPassportPage: true,
  218 + successTip: '恭喜您,第三方账号关联手机号码成功!',
  219 + goUrl: helpers.urlFormat(),
  220 + module: 'passport',
  221 + page: 'bind-success',
  222 + title: '绑定手机号'
  223 + });
  224 + },
  225 +
  226 + changeCheck: (req, res) => {
  227 + let phoneNum = req.body.phoneNum;
  228 + let areaCode = req.body.areaCode;
  229 +
  230 + if (_.isNumber(parseInt(phoneNum, 0)) && areaCode) {
  231 + BindService.changeCheck(phoneNum, areaCode).then(result => {
  232 + res.json(result);
  233 + });
  234 + } else {
  235 + res.json({ code: 400, message: '', data: '' });
  236 + }
  237 + },
  238 +
  239 + changeMobile: (req, res) => {
  240 + let uid = req.user.uid;
  241 + let phoneNum = req.body.phoneNum;
  242 + let areaCode = req.body.areaCode;
  243 + let code = req.body.code;
  244 +
  245 + if (_.isNumber(parseInt(phoneNum)) && uid && areaCode && code) {
  246 + BindService.changeMobile(uid, phoneNum, areaCode, code).then(result => {
  247 + res.json(result);
  248 + });
  249 + } else {
  250 + res.json({ code: 400, message: '', data: '' });
  251 + }
115 } 252 }
116 }; 253 };
117 254
@@ -23,6 +23,73 @@ class RegService { @@ -23,6 +23,73 @@ class RegService {
23 23
24 return api.get('', params); 24 return api.get('', params);
25 } 25 }
  26 +
  27 + static sendBindMsg(area, mobile) {
  28 + let params = {
  29 + method: 'app.passport.smsbind',
  30 + mobile: mobile,
  31 + area: area
  32 + };
  33 +
  34 + return api.get('', params);
  35 + }
  36 +
  37 + static checkBindCode(area, mobile, code) {
  38 + return api.get('', {
  39 + method: 'app.register.validRegCode',
  40 + mobile: mobile,
  41 + area: area,
  42 + code: code
  43 + });
  44 + }
  45 +
  46 + static bindMobile(openId, sourceType, mobile, area, password, nickname) {
  47 + let params = {
  48 + method: 'app.passport.bind',
  49 + mobile: mobile,
  50 + open_id: openId,
  51 + source_type: sourceType,
  52 + area: area
  53 + };
  54 +
  55 + if (password) {
  56 + params.password = password;
  57 + }
  58 +
  59 + if (nickname) {
  60 + params.nickname = nickname;
  61 + }
  62 +
  63 + return api.get('', params);
  64 + }
  65 +
  66 + static relateMobile(openId, sourceType, mobile, area) {
  67 + return api.get('', {
  68 + method: 'app.passport.relateMobile',
  69 + mobile: mobile,
  70 + openId: openId,
  71 + source_type: sourceType,
  72 + area: area
  73 + });
  74 + }
  75 +
  76 + static changeCheck(mobile, area) {
  77 + return api.get('', {
  78 + method: 'app.passport.changeCheck',
  79 + mobile: mobile,
  80 + area: area
  81 + });
  82 + }
  83 +
  84 + static changeMobile(uid, mobile, area, code) {
  85 + return api.get('', {
  86 + method: 'app.passport.changeMobile',
  87 + mobile: mobile,
  88 + uid: uid,
  89 + code: code,
  90 + area: area
  91 + });
  92 + }
26 } 93 }
27 94
28 module.exports = RegService; 95 module.exports = RegService;
@@ -10,6 +10,7 @@ const express = require('express'); @@ -10,6 +10,7 @@ const express = require('express');
10 const cRoot = './controllers'; 10 const cRoot = './controllers';
11 const login = require(cRoot + '/login'); 11 const login = require(cRoot + '/login');
12 const back = require(cRoot + '/back'); 12 const back = require(cRoot + '/back');
  13 +const bind = require(cRoot + '/bind');
13 14
14 const router = express.Router(); // eslint-disable-line 15 const router = express.Router(); // eslint-disable-line
15 16
@@ -34,6 +35,19 @@ router.get('/login/sina/callback', login.sina.callback); @@ -34,6 +35,19 @@ router.get('/login/sina/callback', login.sina.callback);
34 router.get('/login/qq', login.common.beforeLogin, login.qq.login); 35 router.get('/login/qq', login.common.beforeLogin, login.qq.login);
35 router.get('/login/qq/callback', login.qq.callback); 36 router.get('/login/qq/callback', login.qq.callback);
36 37
  38 +// 登录绑定
  39 +router.get('/bind/index', bind.indexPage);
  40 +router.post('/bind/bindCheck', bind.bindCheck);
  41 +router.get('/bind/code', bind.codePage);
  42 +router.post('/bind/sendBindMsg', bind.sendBindMsg);
  43 +router.post('/bind/bindMobile', bind.bindMobile);
  44 +
  45 +router.post('/bind/relateMobile', bind.relateMobile);
  46 +router.get('/bind/success', bind.successPage);
  47 +
  48 +router.post('/bind/changeCheck', bind.changeCheck);
  49 +router.post('/bind/changeMobile', bind.changeMobile);
  50 +
37 /** 51 /**
38 * 邮箱 52 * 邮箱
39 */ 53 */
@@ -8,44 +8,47 @@ var $ = require('yoho-jquery'), @@ -8,44 +8,47 @@ var $ = require('yoho-jquery'),
8 Handlebars = require('yoho-handlebars'), 8 Handlebars = require('yoho-handlebars'),
9 Hammer = require('yoho-hammer'); 9 Hammer = require('yoho-hammer');
10 10
11 -var $dialogWrapper,  
12 - dialogTpl,  
13 - dialogTemplate;  
14 -  
15 -function getInstance() {  
16 - if (dialogTpl === null) {  
17 - dialogTpl = '<div id="dialog-wrapper" class="dialog-wrapper">' +  
18 - '<div class="dialog-box">' +  
19 - '{{# hasHeader}}' +  
20 - '{{/ hasHeader}}' +  
21 - '<div class="dialog-content">{{dialogText}}</div>' +  
22 - '{{# hasFooter}}' +  
23 - '<div class="dialog-footer">' +  
24 - '{{# leftBtnText}}' +  
25 - '<span class="dialog-left-btn tap-hightlight">{{.}}</span>' +  
26 - '{{/ leftBtnText}}' +  
27 - '{{# rightBtnText}}' +  
28 - '<span class="dialog-right-btn tap-hightlight">{{.}}</span>' +  
29 - '{{/ rightBtnText}}' +  
30 - '</div>' +  
31 - '{{/ hasFooter}}' +  
32 - '</div>' +  
33 - '</div>';  
34 -  
35 - dialogTemplate = Handlebars.compile(dialogTpl);  
36 - }  
37 - return dialogTemplate;  
38 -} 11 +
39 12
40 // fullWithBtn是供详情页获取限购码使用的特殊参数 13 // fullWithBtn是供详情页获取限购码使用的特殊参数
41 exports.showDialog = function(data, callback, callbackForLeft, fullWithBtn) { 14 exports.showDialog = function(data, callback, callbackForLeft, fullWithBtn) {
42 15
43 - var dialogStr = dialogTemplate(data), 16 + var dialogStr,
44 $dialogBox, 17 $dialogBox,
45 defaultHideDuraton, 18 defaultHideDuraton,
  19 + $dialogWrapper,
46 dialogWrapperHammer; 20 dialogWrapperHammer;
47 21
48 - dialogTemplate = getInstance(); 22 + function getInstance() {
  23 + var dialogTpl = null,
  24 + dialogTemplate;
  25 +
  26 + if (dialogTpl === null) {
  27 + dialogTpl = '<div id="dialog-wrapper" class="dialog-wrapper">' +
  28 + '<div class="dialog-box">' +
  29 + '{{# hasHeader}}' +
  30 + '{{/ hasHeader}}' +
  31 + '<div class="dialog-content">{{dialogText}}</div>' +
  32 + '{{# hasFooter}}' +
  33 + '<div class="dialog-footer">' +
  34 + '{{# leftBtnText}}' +
  35 + '<span class="dialog-left-btn tap-hightlight">{{.}}</span>' +
  36 + '{{/ leftBtnText}}' +
  37 + '{{# rightBtnText}}' +
  38 + '<span class="dialog-right-btn tap-hightlight">{{.}}</span>' +
  39 + '{{/ rightBtnText}}' +
  40 + '</div>' +
  41 + '{{/ hasFooter}}' +
  42 + '</div>' +
  43 + '</div>';
  44 +
  45 + dialogTemplate = Handlebars.compile(dialogTpl);
  46 + }
  47 + return dialogTemplate;
  48 + }
  49 +
  50 + dialogStr = getInstance()(data);
  51 +
49 $('.dialog-wrapper').remove(); 52 $('.dialog-wrapper').remove();
50 53
51 $('body').append($(dialogStr)); 54 $('body').append($(dialogStr));
@@ -11,6 +11,29 @@ body.passport-body { @@ -11,6 +11,29 @@ body.passport-body {
11 text-align: center; 11 text-align: center;
12 padding: 0 6%; 12 padding: 0 6%;
13 13
  14 + .bind-tip {
  15 + margin-top: 10PX;
  16 + margin-bottom: 10PX;
  17 + color: #fff;
  18 + font-size: 13PX;
  19 +
  20 + .title {
  21 + font-size: 28PX;
  22 + line-height: 1.5;
  23 + }
  24 + }
  25 +
  26 + .tip {
  27 + margin-top: 30PX;
  28 + color: #fff;
  29 + font-size: 16PX;
  30 + line-height: 2;
  31 +
  32 + a {
  33 + color: #3FB274;
  34 + }
  35 + }
  36 +
14 .header { 37 .header {
15 position: relative; 38 position: relative;
16 height: 40PX; 39 height: 40PX;