bind.js 11.2 KB
/**
 * 手机号绑定功能
 *
 * @author JiangFeng<jeff.jiang@yoho.cn>
 * @date 2016/06/21
 */

'use strict';

const helpers = global.yoho.helpers;
const RegServiceModel = require('../models/reg-service');
const BindServiceModel = require('../models/bind-service');
const AuthHelperModel = require('../models/auth-helper');
const _ = require('lodash');

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

const bind = {
    indexPage: (req, res) => {
        // 如果没有originalUrl,判定为非法链接
        if (req.session.originalUrl !== 'true') {
            return res.redirect('//m.yohobuy.com');
        }
        let refer = req.get('Referer');

        if (refer) {
            res.cookie('refer', encodeURI(refer), {
                domain: 'yohobuy.com'
            });
        }

        let openId = req.query.openId;
        let sourceType = req.query.sourceType;
        let serviceUrl = helpers.urlFormat('/service/im');

        res.render('bind/index', {
            captchaShow: req.yoho.captchaShow,
            bindIndex: true, // js标识
            backUrl: helpers.urlFormat('/signin.html'), // 返回的URL链接
            showHeaderImg: true, // 控制显示头部图片
            isPassportPage: true, // 模板中模块标识
            sourceType: sourceType, // 第三方登录来源
            platform: Sources[sourceType],
            isWechatLogin: sourceType === 'wechat',
            openId: openId, // openId
            areaCode: '+86', // 默认区号
            countrys: req.ctx(RegServiceModel).getAreaData(), // 国别码
            serviceUrl: serviceUrl, // 在线客服
            module: 'passport',
            page: 'bind',
            title: '绑定手机号',
            width750: true
        });
    },

    codePage: (req, res) => {
        let openId = req.query.openId;
        let sourceType = req.query.sourceType;
        let areaCode = req.query.areaCode || '86';
        let isReg = req.query.isReg;
        let phoneNum = req.query.phoneNum;

        res.render('bind/code', {
            captchaShow: req.yoho.captchaShow,
            backUrl: helpers.urlFormat('/signin.html'),
            showHeaderImg: true,
            isPassportPage: true,
            sourceType: sourceType,
            openId: openId,
            isReg: isReg,
            areaCode: areaCode,
            phoneNum: phoneNum,
            relateCode: isReg === '3',
            bindCode: isReg !== '3',
            module: 'passport',
            page: isReg === '3' ? 'relate' : 'bind-code',
            title: '验证手机'
        });
    },

    bindCheck: (req, res, next) => {
        let phoneNum = req.body.phoneNum;
        let openId = req.body.openId;
        let areaCode = req.body.areaCode || '86';
        let sourceType = req.body.sourceType;

        if (_.isNumber(parseInt(phoneNum, 0)) && openId && areaCode && sourceType) {
            req.ctx(BindServiceModel).bindCheck(phoneNum, openId, sourceType, areaCode).then(result => {
                let data = {
                    code: result.code,
                    message: result.message,
                    data: {}
                };

                if (result.code === 200) {
                    let nextUrl = helpers.urlFormat('/passport/bind/code', {
                        is_register: result.data.is_register,
                        openId: openId,
                        sourceType: sourceType,
                        areaCode: areaCode,
                        phoneNum: phoneNum
                    });

                    data.data.is_register = result.data.is_register;
                    data.data.next = nextUrl;
                } else {
                    data.data = result.data;
                }

                res.json(data);
            }).catch(next);
        } else {
            res.json({
                code: 400,
                message: '',
                data: ''
            });
        }
    },

    sendBindMsg: (req, res, next) => {
        let phoneNum = req.body.phoneNum;
        let areaCode = req.body.areaCode || '86';
        let udid = req.sessionID;
        let captcha = req.body.captcha;

        if (req.xhr && _.isNumber(parseInt(phoneNum, 0)) && areaCode) {
            if (req.body.geetest_challenge) {
                captcha = req.body.geetest_challenge; // TODO 使用极验证传特殊的值
            }
            req.ctx(BindServiceModel).sendBindMsg({
                area: areaCode,
                mobile: phoneNum,
                udid,
                captcha
            }).then(result => {
                if (result && result.code) {
                    res.json(result);
                } else {
                    res.json({ code: 400, message: '', data: '' });
                }
            }).catch(next);
        } else {
            res.json({ code: 400, message: '', data: '' });
        }
    },

    checkBindMsg: (req, res, next) => {
        let phoneNum = req.body.phoneNum;
        let code = req.body.code;
        let areaCode = req.body.areaCode;

        if (_.isNumber(parseInt(phoneNum, 0)) && code && areaCode) {
            req.ctx(BindServiceModel).checkBindMsg(areaCode, phoneNum, code).then(result => {
                if (result && result.code) {
                    res.json(result);
                } else {
                    res.json({ code: 400, message: '', data: '' });
                }
            }).catch(next);
        } else {
            res.json({ code: 400, message: '', data: '' });
        }
    },

    bindMobile: (req, res, next) => {
        let phoneNum = req.body.phoneNum;
        let openId = req.body.openId;
        let areaCode = req.body.areaCode || '86';
        let sourceType = req.body.sourceType;
        let code = req.body.code;
        let password = req.body.password || '';
        let from = req.cookies.from || 'yohobuy';

        if (_.isNumber(parseInt(phoneNum, 0)) && openId && sourceType && areaCode && code) {
            req.ctx(BindServiceModel).checkBindCode(areaCode, phoneNum, code).then(result => {
                if (result && result.code && result.code === 200) {
                    return req.ctx(BindServiceModel).bindMobile(openId, sourceType, phoneNum, areaCode, password, from);
                } else {
                    return { code: 400, message: '短信验证码错误', data: '' };
                }
            }).then(result => {
                let refer = helpers.urlFormat('/passport/bind/success?type=bind');

                if (result && result.code && result.code === 200 && result.data.uid) {
                    return req.ctx(AuthHelperModel).syncUserSession(result.data.uid, req, res, result.data.session_key)
                        .then((authData) => {
                            result.data.refer = _.get(authData, 'refer') || refer;
                            return result;
                        });
                } else {
                    return { code: 400, message: '绑定失败', data: '' };
                }

            }).then(result => {
                res.json(result);
            }).catch(next);
        } else {
            res.json({ code: 400, message: '', data: '' });
        }
    },

    relateMobile: (req, res, next) => {
        let phoneNum = req.body.phoneNum;
        let openId = req.body.openId;
        let areaCode = req.body.areaCode || '86';
        let sourceType = req.body.sourceType;
        let code = req.body.code;

        if (_.isNumber(parseInt(phoneNum, 0)) && openId && areaCode && sourceType && code) {
            req.ctx(BindServiceModel).checkBindCode(areaCode, phoneNum, code).then(result => {
                if (result && result.code && result.code === 200) {
                    return req.ctx(BindServiceModel).relateMobile(openId, sourceType, phoneNum, areaCode);
                } else {
                    return { code: 400, message: '短信验证码错误', data: '' };
                }
            }).then(result => {
                let refer = helpers.urlFormat('/passport/bind/success', { sourceType: sourceType });

                if (result && result.code && result.code === 200 && result.data.uid) {
                    return req.ctx(AuthHelperModel).syncUserSession(result.data.uid, req, res, result.data.session_key)
                        .then((authData) => {
                            result.data.refer = _.get(authData, 'refer') || refer;
                            return result;
                        });
                } else {
                    return { code: 400, message: '关联失败', data: '' };
                }

            }).then(result => {
                res.json(result);
            }).catch(next);
        } else {
            res.json({ code: 400, message: '', data: '' });
        }
    },

    passwordPage: (req, res) => {
        let openId = req.query.openId;
        let sourceType = req.query.sourceType;
        let areaCode = req.query.areaCode || '86';
        let phoneNum = req.query.phoneNum;
        let code = req.query.code;

        res.render('bind/password', {
            module: 'passport',
            page: 'bind-password',
            bindPwd: true, // js标识
            backUrl: helpers.urlFormat('/signin.html'), // 返回的URL链接
            showHeaderImg: true, // 控制显示头部图片
            isPassportPage: true, // 模板中模块标识
            sourceType: sourceType, // 第三方登录来源
            openId: openId, // openId
            areaCode: areaCode, // 国别码
            phoneNum: phoneNum, // 国别码
            code: code // 验证码
        });
    },

    successPage: (req, res) => {
        let refer = req.cookies.refer;
        let type = req.query.type;

        if (!refer || /signin|login/.test(refer)) {
            refer = helpers.urlFormat('/?go=1');
        }

        // 微信免单活动,判断来源地址 2.16.12.28 by jing.li@yoho.cn
        res.cookie('bindUrl', 'http://m.yohobuy.com/passport/bind/success?type=bind');

        res.render('bind/success', {
            isPassportPage: true,
            successTip: type === 'bind' ? '恭喜您,第三方账号绑定手机号码成功!' : '恭喜您,第三方账号关联手机号码成功!',
            goUrl: refer,
            module: 'passport',
            page: 'bind-success',
            title: '绑定手机号'
        });
    },

    changeCheck: (req, res, next) => {
        let phoneNum = req.body.phoneNum;
        let areaCode = req.body.areaCode;

        if (_.isNumber(parseInt(phoneNum, 0)) && areaCode) {
            req.ctx(BindServiceModel).changeCheck(phoneNum, areaCode).then(result => {
                res.json(result);
            }).catch(next);
        } else {
            res.json({ code: 400, message: '', data: '' });
        }
    },

    changeMobile: (req, res, next) => {
        let uid = req.user.uid;
        let phoneNum = req.body.phoneNum;
        let areaCode = req.body.areaCode;
        let code = req.body.code;

        if (_.isNumber(parseInt(phoneNum, 0)) && uid && areaCode && code) {
            req.ctx(BindServiceModel).changeMobile(uid, phoneNum, areaCode, code).then(result => {
                res.json(result);
            }).catch(next);
        } else {
            res.json({ code: 400, message: '', data: '' });
        }
    }
};

module.exports = bind;