bind.js 12.4 KB
/**
 * 第三方登录后绑定
 *
 * @author: jiangfeng<jeff.jiang@yoho.cn>
 */

'use strict';

const _ = require('lodash');
const helpers = global.yoho.helpers;
const passportHelper = require('../models/passport-helper');
const BindService = require('../models/bind-service');
const LoginService = require('../models/login-service');
const UserService = require('../models/user-service');

// const UserService = require('../models/user-service');
const simpleHeaderModel = require('../../../doraemon/models/simple-header');

const Sources = {
    qq: 'QQ',
    sina: '微博',
    alipay: '支付宝',
    wechat: '微信',
    renren: '人人',
    douban: '豆瓣'
};

const bind = {
    indexPage: (req, res) => {
        let openId = req.query.openId;
        let sourceType = req.query.sourceType;

        res.render('bind', {
            thirdLogin: true,
            openId: openId,
            sourceType: sourceType,
            region: passportHelper.getCountry(),
            serviceUrl: helpers.urlFormat('/help', {
                category_id: 9
            }),
            simpleHeader: simpleHeaderModel.setSimpleHeaderData(),
            module: 'passport',
            page: 'bind',
            title: '联合登录补全信息'
        });
    },
    captchaSuccess: (req, res, next) => {
        req.session.type = 'relateStep1';
        return next();
    },
    noregist: (req, res) => {
        let mobile = req.body.mobile;
        let sourceType = req.body.sourceType;
        let openId = req.body.openId;
        let area = req.body.area;

        res.render('bind/noregist', {
            enablePerfectInformation: true,
            mobile: mobile,
            sourceType: sourceType,
            openId: openId,
            area: area,
            module: 'passport',
            page: 'noregist',
            simpleHeader: simpleHeaderModel.setSimpleHeaderData(),
            title: '登录绑定'
        });

    },
    relate: (req, res, next) => {
        let mobile = req.body.mobile;
        let sourceType = req.body.sourceType;
        let openId = req.body.openId;
        let area = req.body.area;

        if (req.session.type !== 'relateStep1') {
            return next();
        }

        req.ctx(UserService).getUserInfo(area, mobile).then(user => {
            let data = _.assign(user, {
                phoneNum: mobile,
                areaCode: area,
                openId: openId,
                sourceType: sourceType,
                changeHref: helpers.urlFormat('/passport/thirdlogin/index', {openId: openId, sourceType: sourceType}),
                simpleHeader: simpleHeaderModel.setSimpleHeaderData(),
                module: 'passport',
                page: 'relate',
                title: '账号关联'
            });

            res.render('bind/relate', data);
        }).catch(next);
    },
    bindSuccess: (req, res) => {
        let sourceType = _.trim(req.query.sourceType);
        let sourceInfo = sourceType.split('_');
        let sourceName = Sources[sourceInfo[0]];
        let isRelate = (sourceInfo[1] === 'relate');
        let data = {
            thirdLogin: true,
            goShopping: helpers.urlFormat('/'),
            sourceName: sourceName,
            relate: isRelate,
            module: 'passport',
            page: 'bind-success',
            simpleHeader: simpleHeaderModel.setSimpleHeaderData(),
            title: '绑定手机号'
        };

        req.session.type = '';

        res.render('bind/success', data);
    },
    _bindCheck: (req, mobile, openId, area, sourceType) => {
        return req.ctx(BindService).bindCheck(mobile, openId, sourceType, area).then(result => {
            if (!result || !result.code) {
                return {code: 400, message: '', data: ''};
            } else if (result.code === 200 && result.data.is_register === 0) {
                let nextUrl = helpers.urlFormat('/passport/thirdlogin/noregist');

                // 绑定流程:code=200 未注册,可绑定
                return {code: 200, message: result.message, data: {next: nextUrl}};
            } else if (result.code === 200 && result.data.is_register === 1) {
                return req.ctx(UserService).getUserInfo(area, mobile).then(user => {
                    // 绑定流程:code=201 已注册 绑定过其他第三方
                    return {code: 201, message: result.message, data: {user: user}};
                });
            } else if (result.code === 200 && result.data.is_register === 3) {
                // 关联流程
                return req.ctx(UserService).getUserInfo(area, mobile).then(user => {
                    return {code: 203, message: result.message, data: {user: user}};
                });
            } else if (result.code === 506 || result.code === 505) {
                return req.ctx(UserService).getUserInfo(area, mobile).then(user => {
                    // 绑定流程:code=506 手机号码注册过,而且该手机号码也已经绑定过该类型第三方
                    // code=505 手机号码注册过,而且该第三方也已经绑定过手机号
                    return {code: 205, message: result.message, data: {user: user}};
                });
            } else {
                return {code: result.code, message: result.message, data: result.data ? result.data : ''};
            }
        });
    },
    bindCheck: (req, res, next) => {
        let mobile = req.body.mobile;
        let openId = req.body.openId;
        let area = req.body.area || '86';
        let sourceType = req.body.sourceType;

        if (req.session.type !== 'relateStep1') {
            return res.json({code: 400, message: '非法请求'});
        }

        if (mobile && openId && area && sourceType) {

            /**
             * 接口绑定返回值:
             * code:200,is_register=0     // 绑定流程:未注册,可绑定
             * code:200,is_register=1     // 绑定流程:已注册绑定过其他第三方
             * code:200:is_register=3     // 关联流程
             * code:505                   // 手机号码注册过,而且该第三方也已经绑定过手机号
             * code:506                   // 手机号码注册过,而且该手机号码也已经绑定过该类型第三方
             */

            bind._bindCheck(req, mobile, openId, area, sourceType).then(result => {
                return res.json(result);
            }).catch(next);
        } else {
            return res.json({code: 400, message: '', data: ''});
        }
    },
    bindCheckSendMsg: (req, res, next) => {
        let mobile = req.body.mobile;
        let openId = req.body.openId;
        let area = req.body.area || '86';
        let sourceType = req.body.sourceType;

        req.session.captchaCount = 4; // 防止用户多次单击下一步,而发送短信

        if (req.session.type !== 'relateStep1') {
            return res.json({code: 400, message: '非法请求'});
        }

        if (mobile && openId && area && sourceType) {

            /**
             * 接口绑定返回值:
             * code:200,is_register=0     // 绑定流程:未注册,可绑定
             * code:200,is_register=1     // 绑定流程:已注册绑定过其他第三方
             * code:200:is_register=3     // 关联流程
             * code:505                   // 手机号码注册过,而且该第三方也已经绑定过手机号
             * code:506                   // 手机号码注册过,而且该手机号码也已经绑定过该类型第三方
             */
            bind._bindCheck(req, mobile, openId, area, sourceType).then(result => {
                if (result.code === 201) {
                    req.ctx(BindService).sendBindMsg(area, mobile).then(d => {
                        if (d && d.code) {
                            return res.json(result);
                        } else {
                            return res.json({code: 400, message: '', data: ''});
                        }
                    }).catch(next);
                } else {
                    return res.json(result);
                }
            }).catch(next);
        } else {
            return res.json({code: 400, message: '', data: ''});
        }
    },
    sendBindMsg: (req, res, next) => {
        let mobile = req.body.mobile;
        let area = req.body.area;

        if (req.session.type !== 'relateStep1') {
            return res.json({code: 400, message: '非法请求'});
        }

        req.ctx(BindService).sendBindMsg(area, mobile).then(result => {
            if (result && result.code) {
                return res.json(result);
            } else {
                return res.json({code: 400, message: '', data: ''});
            }
        }).catch(next);
    },
    checkBindMsg: (req, res, next) => {
        let mobile = req.body.mobile;
        let area = req.body.area;
        let code = req.body.code;

        req.ctx(BindService).checkBindCode(area, mobile, code).then(result => {
            if (result && result.code) {
                return res.json(result);
            } else {
                return res.json({code: 400, message: '', data: ''});
            }
        }).catch(next);
    },
    bindMobile: (req, res, next) => {
        let mobile = _.trim(req.body.mobile);
        let area = _.trim(req.body.area) || '86';
        let openId = _.trim(req.body.openId);
        let sourceType = _.trim(req.body.sourceType);
        let code = _.trim(req.body.code);
        let password = _.trim(req.body.password) || '';

        req.ctx(BindService).checkBindCode(area, mobile, code).then(result => {
            if (result && result.code !== 200) {
                return {code: 402, message: '短信验证码不正确', data: ''};
            } else {
                return req.ctx(BindService).bindMobile(openId, sourceType, mobile, area, password);
            }
        }).then(result => {
            if (result && result.code) {
                if (result.code === 200 && result.data && result.data.uid) {
                    let refer = helpers.urlFormat('/passport/thirdlogin/bindsuccess', {
                        sourceType: sourceType + '_bind'
                    });

                    return req.ctx(LoginService).syncUserSession(result.data, req, res).then(() => {
                        return {code: 200, message: result.message, data: {refer: refer}};
                    });
                } else {
                    return {code: result.code, message: result.message, data: {refer: ''}};
                }
            } else {
                return {code: 400, message: '', data: ''};
            }
        }).then(result => {
            return res.json(result);
        }).catch(next);
    },
    relateMobile: (req, res, next) => {
        let mobile = req.body.mobile;
        let openId = req.body.openId;
        let areaCode = req.body.areaCode || '86';
        let sourceType = req.body.sourceType;
        let code = req.body.code;

        if (_.toNumber(mobile) && openId && areaCode && sourceType && code) {
            req.ctx(BindService).checkBindCode(areaCode, mobile, code).then(result => {
                if (result && result.code && result.code === 200) {
                    return req.ctx(BindService).relateMobile(openId, sourceType, mobile, areaCode);
                } else {
                    return {code: 402, message: '短信验证码错误', data: ''};
                }
            }).then(result => {
                if (result && result.code) {
                    if (result.code === 200 && result.data && result.data.uid) {
                        let refer = helpers.urlFormat('/passport/thirdlogin/bindsuccess', {
                            sourceType: sourceType + '_relate'
                        });

                        return req.ctx(LoginService).syncUserSession(
                            result.data,
                            req,
                            res
                        ).then(() => {
                            return {code: 200, message: result.message, data: {refer: refer}};
                        });
                    } else {
                        return {code: result.code, message: result.message, data: {refer: ''}};
                    }
                } else {
                    return {code: 400, message: '', data: ''};
                }
            }).then(result => {
                return res.json(result);
            }).catch(next);
        } else {
            return res.json({code: 400, message: '', data: ''});
        }
    }
};

module.exports = bind;