bind.js 11.8 KB
/**
 * 第三方登录后绑定
 *
 * @author: TaoHuang
 */

'use strict';

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

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

const DEFAULT_URL = '//img10.static.yhbimg.com/headimg/2013/11/28/09/01cae078abe5fe320c88cdf4c220212688.gif?imageView/2/w/100/h/100'; //eslint-disable-line

/**
 * 首页
 */
const indexPage = (req, res) => {
    let openId = req.query.openId;
    let sourceType = req.query.sourceType;

    res.display('bind/index', Object.assign({
        module: 'passport',
        page: 'bind',
        title: '联合登录补全信息',
        defaultHeader: false
    }, {
        openId: openId,
        sourceType: sourceType,
        country: { list: PassportHelper.getCountry() },
        local: '+86',
        countryName: { text: '中国' },
        imgCaptcha: helpers.urlFormat('/passport/images', { t: Date.now() })
    }));
};

/**
 * 设置密码
 */
const bindSetPwdPage = (req, res) => {
    let mobile = req.query.thirdPart.mobile;
    let sourceType = req.query.thirdPart.sourceType;
    let openId = req.query.thirdPart.openId;
    let area = req.query.thirdPart.area;

    res.display('bind/bind-set-pwd', Object.assign({
        module: 'passport',
        page: 'bind-set-pwd',
        title: '登录绑定',
        defaultHeader: false
    }, {
        mobile: mobile,
        sourceType: sourceType,
        openId: openId,
        area: area
    }));

};

/**
 * 绑定确认页面
 */
const bindConfirmPage = (req, res) => {
    let thirdPart = req.query.thirdPart;
    let user = req.query.user;
    let avatar = user.headImg || DEFAULT_URL;

    res.display('bind/bind-confirm', Object.assign({
        module: 'passport',
        page: 'bind-confirm',
        title: '绑定确认',
        defaultHeader: false
    }, {
        avatar: avatar,
        name: user.username || '咸鸭蛋',
        bindSuccess: helpers.urlFormat('/thirdlogin/bindSuccess', {
            sourceType: thirdPart.sourceType
        }),
        bindUrl: helpers.urlFormat('/passport/thirdlogin/index', {
            openId: thirdPart.openId,
            sourceType: thirdPart.sourceType
        }),
        loginUrl: helpers.urlFormat('/passport/login'),
        mobile: thirdPart.mobile,
        openId: thirdPart.openId,
        area: thirdPart.area,
        code: thirdPart.code,
        sourceType: thirdPart.sourceType
    }));
};

/**
 * 绑定成功页面
 */
const bindSuccessPage = (req, res) => {
    let sourceType = _.trim(req.query.sourceType);
    let sourceInfo = sourceType.split('_');
    let sourceName = Sources[sourceInfo[0]];

    res.display('bind/bind-success', Object.assign({
        module: 'passport',
        page: 'bind-success',
        title: '绑定手机号',
        defaultHeader: false
    }, {
        goShopping: helpers.urlFormat('/'),
        sourceName: sourceName
    }));
};

/**
 * 已绑定过手机页面
 */
const bindedPage = (req, res) => {
    let thirdPart = req.query.thirdPart;
    let user = req.query.user;
    let avatar = user.headImg || DEFAULT_URL;

    res.display('bind/bind-done', Object.assign({
        module: 'passport',
        page: 'bind-success',
        title: '绑定手机号',
        defaultHeader: false
    }, {
        avatar: avatar,
        name: user.username || '咸鸭蛋',
        loginUrl: helpers.urlFormat('/passport/login'),
        bindUrl: helpers.urlFormat('/passport/thirdlogin/index', {
            openId: thirdPart.openId,
            sourceType: thirdPart.sourceType
        })
    }));
};

/**
 * 关联成功页面
 */
const relateSuccessPage = (req, res) => {
    let sourceType = _.trim(req.query.sourceType);
    let sourceInfo = sourceType.split('_');
    let sourceName = Sources[sourceInfo[0]];

    res.display('bind/relate-success', Object.assign({
        module: 'passport',
        page: 'relate-success',
        title: '关联手机号',
        defaultHeader: false
    }, {
        goShopping: helpers.urlFormat('/'),
        sourceName: sourceName
    }));
};

/**
 * 关联手机号确定页面
 */
const relateConfirmPage = (req, res) => {
    let thirdPart = req.query.thirdPart;
    let user = req.query.user;
    let avatar = user.headImg || DEFAULT_URL;

    res.display('bind/relate-confirm', Object.assign({
        module: 'passport',
        page: 'relate-confirm',
        title: '关联确认',
        defaultHeader: false
    }, {
        avatar: avatar,
        name: user.username || '咸鸭蛋',
        relateUrl: helpers.urlFormat('/passport/thirdlogin/index', {
            openId: thirdPart.openId,
            sourceType: thirdPart.sourceType
        }),
        signinUrl: helpers.urlFormat('/passport/login'),
        mobile: thirdPart.mobile,
        area: thirdPart.area,
        sourceType: thirdPart.sourceType,
        openId: thirdPart.openId
    }));
};

/**
 * 检查手机号和第三方绑定情况
 */
const 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 (mobile && openId && area && sourceType) {
        /**
         * 接口绑定返回值:
         * code:200,is_register=0     // 绑定流程:未注册,可绑定
         * code:200,is_register=1     // 绑定流程:已注册绑定过其他第三方
         * code:200:is_register=3     // 关联流程
         * code:505                   // 手机号码注册过,而且该第三方也已经绑定过手机号
         * code:506                   // 手机号码注册过,而且该手机号码也已经绑定过该类型第三方
         */
        BindService.bindCheckAsync(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/bindSetPwd');

                // 绑定流程:code=200 未注册,可绑定
                return { code: 200, message: result.message, data: { next: nextUrl } };
            } else if (result.code === 200 && result.data.is_register === 1) {
                return UserService.getUserInfoAsync(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 UserService.getUserInfoAsync(area, mobile).then(user => {
                    return { code: 203, message: result.message, data: { user: user } };
                });
            } else if (result.code === 506 || result.code === 505) {
                return UserService.getUserInfoAsync(area, mobile).then(user => {
                    // 绑定流程:code=201 已注册 绑定过其他第三方
                    return { code: 205, message: result.message, data: { user: user } };
                });
            } else {
                return { code: result.code, message: result.message, data: result.data ? result.data : '' };
            }
        }).then(result => {
            res.json(result);
        }).catch(next);
    } else {
        res.json({ code: 400, message: '', data: '' });
    }
};

/**
 * 发送绑定短信页面
 */
const sendBindMsg = (req, res, next) => {
    let mobile = req.body.mobile;
    let area = req.body.area;
    let verifyCode = req.body.verifyCode;

    if (req.session.autouserinfoMobile && req.session.autouserinfoMobile !== mobile || verifyCode !== req.session.captcha) {//eslint-disable-line
        req.session.autouserinfoMobile = '';
        req.session.captcha = '';
        return res.json({
            code: 400,
            message: '验证码失效'
        });
    }
    BindService.sendBindMsgAsync(area, mobile).then(result => {
        if (result && result.code) {
            req.session.autouserinfoMobile = mobile;
            req.session.thirdBind = {
                mobile: mobile
            };
            res.json(result);
        } else {
            res.json({ code: 400, message: '', data: '' });
        }
    }).catch(next);
};

/**
 * 验证绑定短信
 */
const checkBindMsg = (req, res, next) => {
    let mobile = req.body.mobile;
    let area = req.body.area;
    let code = req.body.code;

    BindService.checkBindCodeAsync(area, mobile, code).then(result => {
        if (result && result.code) {
            res.json(result);
        } else {
            res.json({ code: 400, message: '', data: '' });
        }
    }).catch(next);
};

/**
 * 绑定第三方到手机号
 */
const 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 password = _.trim(req.body.password) || '';

    if (req.session.thirdBind && req.session.thirdBind.mobile === mobile) {
        BindService.bindMobileAsync(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 LoginService.syncUserSession(result.data.uid, req, res, result.data.session_key).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 => {
            res.json(result);
        }).catch(next);
    } else {
        res.json({ code: 400, message: '', data: '' });
    }
};

/**
 * 关联第三方到手机号
 */
const 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;

    if (req.session.thirdBind && req.session.thirdBind.mobile === mobile) {
        BindService.relateMobileAsync(openId, sourceType, mobile, areaCode).then(result => {
            if (result && result.code) {
                if (result.code === 200 && result.data && result.data.uid) {
                    let refer = helpers.urlFormat('/passport/thirdlogin/relatesuccess', {
                        sourceType: sourceType + '_bind'
                    });

                    return LoginService.syncUserSession(result.data.uid, req, res, result.data.session_key).then(() => {
                        req.session.thirdBind = '';
                        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 => {
            res.json(result);
        }).catch(next);
    } else {
        res.json({ code: 400, message: '', data: '' });
    }
};

module.exports = {
    indexPage,
    bindSetPwdPage,
    bindConfirmPage,
    bindSuccessPage,
    bindedPage,
    relateConfirmPage,
    relateSuccessPage,
    bindCheck,
    sendBindMsg,
    checkBindMsg,
    bindMobile,
    relateMobile
};