login.js 9.48 KB
import { LoginService } from './loginService.js'
import event from '../../utils/event.js'

const login = new LoginService().yohoApi();

const USER_GET_PHONENUMBER_ERROR = 'user-get-phonenumber-error';
const USER_LOGIN_CALLBACK = 'user-login-callback';
const USER_LOGIN_SUCCESS = 'user-login-success';
const MY_USER_LOGIN_SUCCESS = 'my-user-login-success';
const USER_CHANGE_LOGIN_STATUS = 'change-login-status';

export const loginAction = (callBack) => {
  return wx.login({
    success(res) {
      if (res.code) {
        login.checkLogin(res.code).then((data) => {
          // 获取 srd_session
          const loginData = data;
          handleLoginData(loginData);
          if (callBack) {
            callBack(null, data);
          }
        }).catch((error) => {
          if (callBack) {
            callBack(error);
          }
        });
      }
    },
    fail(error) {
      callBack(error);
    }
  })
};

const handleLoginData = (loginData) => {
  // 上报接口返回的结果,线上debug用
  // 缓存 srd_session
  setStorageWithValueForKey('srd_session', loginData.srd_session);
  // 缓存 openid
  setStorageWithValueForKey('openid', loginData.openid);
  // 如果 unionid 不存在(未使用过任何有货微信产品的全新用户),调用getUnionID函数,再次获取unionID
  if (loginData.unionid) {
    // 对于已经授权过的用户,拿到unionid之后获取一次userinfo更新个人信息
    setStorageWithValueForKey('unionid', loginData.unionid);
  }
}

/**
 * 判断微信用户是否绑定
 * @param srd_session
 * @param result
 * @returns {Promise.}
 */
export const decodeUnionId = (srd_session, result) => {
  let res = result.detail;
  let fromPage = result.currentTarget.dataset.from;
  let globalData = getGlobalData();
  // 存储 userInfo
  if (res && res.userInfo) {
    setStorageWithValueForKey('userInfo', res.userInfo);
  } else {
    return;
  }
  const nickName = res.userInfo.nickName;
  const avatarUrl = res.userInfo.avatarUrl;
  if (!srd_session) return;
  return login.decodeUserInfo(srd_session, res.encryptedData, res.iv).then((data) => {
    let union_id;
    // 本地保存 union_id
    if (data.union_id) {
      const userInfo = wx.getStorageSync('userInfo');
      userInfo.union_id = data.union_id;
      setStorageWithValueForKey('userInfo', userInfo);
      union_id = data.union_id;
    } else {
      union_id = globalData.union_id;
    }
    if (!union_id) {
      throw new Error('授权失败,请使用手机号登录');
    }
    // 网络上传头像,union_id,昵称
    login.sendWeChatUserDataWithUnionId(data.union_id, nickName, avatarUrl).catch(error => {
    });
    return { 
      union_id: union_id, 
      userInfo: res.userInfo
    };
  });
};

/**
 * 判断微信用户是否绑定
 * @param unionID
 * @param userInfo
 * @returns {Promise.}
 */
export const wechatUserIsBind = (union_id, userInfo) => {
  const globalData = getGlobalData();
  return login.wechatUserIsBind(union_id, userInfo.nickName).then(data => {
    if (!isStringEmpty(data.is_bind) && data.is_bind === "Y") {
      const newUserInfo = {
        is_bind: data.is_bind,
        mobile: data.mobile,
        session_key: data.session_key,
        uid: data.uid,
        ssouid: data.ssouid,
        union_id: union_id
      };
      const assignUserInfo = Object.assign(newUserInfo, userInfo);
      setStorageWithValueForKey('userInfo', assignUserInfo);
      setStorageWithValueForKey('session_key', data.session_key);
      globalData.userInfo = assignUserInfo;

      login.sendWeChatUserData(data.uid, userInfo.nickName, userInfo.avatarUrl).catch(error => {});
      console.log('login ------------ globalData: ', globalData);
      return Promise.resolve({
        code: 10003,
        data: userInfo,
        message: '微信用户已绑定手机号'
      });
    } else {
      console.log('login ------------ globalData: ', globalData);
      return Promise.resolve({
        code: 10004,
        message: '微信用户未绑定手机号'
      });
    }
  });
}

const setStorageWithValueForKey = (key, value) => {
  const globalData = getGlobalData();
  wx.setStorage({
    key: key,
    data: value,
  })
  globalData[key] = value;
}

const getStorageWithValueForKey = (key) => {
  wx.getStorage({
    key: key,
    success: function(res) {
      
    },
  })
}

const getGlobalData = () => {
  const app = getApp();
  let globalData;
  if (app && app.globalData) {
    // 原生小程序的 globalData 获取方式
    globalData = app && app.globalData;
  } else {
    // Taro 下 globalData 获取方式
    globalData = app && app.props && app.props.globalData;
  }
  return globalData;
}

const isStringEmpty = (str) => {
  if (str === undefined || str === null || str === '') {
    return true
  } else {
    return false
  }
}

const checkEventName = (eventName, fromPage) => {
  if (fromPage) {
    return `${fromPage}-${eventName}`;
  }
  return eventName;
}

export const getUserInfo = (e) => {
  const fromPage = e.currentTarget.dataset.from;
  if (e.detail.errMsg === 'getUserInfo:ok') {
    loginAction((error, loginData) => {
      if (error) { 
        event.emit(checkEventName(USER_GET_PHONENUMBER_ERROR, fromPage), error.message);
        return;
      }
      decodeUnionId(loginData.srd_session, e).then(data => {
        if (!data.union_id) throw new Error('union_id is null');
        wechatUserIsBind(data.union_id, data.userInfo).then(message => {
          if (message.code === 10003) {
            event.emit(checkEventName(USER_LOGIN_SUCCESS, fromPage));
            setTimeout(() => {
              event.emit(MY_USER_LOGIN_SUCCESS);
            }, 1000);
            wx.showToast({
              icon: 'none',
              title: '登录成功!',
              duration: 3000
            });
          } else if (message.code === 10004) {
            event.emit(checkEventName(USER_CHANGE_LOGIN_STATUS, fromPage), {
              text: '绑定手机号',
              tips: '还差一步,绑定手机号码,加入Yoho!Family'
            });
            wx.showToast({
              icon: 'none',
              title: '该微信号未绑定yoho手机账号,请再次单击绑定手机号',
              duration: 3000
            });
          }
          event.emit(checkEventName(USER_LOGIN_CALLBACK, fromPage), message);
        }).catch(error => {
          event.emit(checkEventName(USER_LOGIN_CALLBACK, fromPage), error);
          event.emit(checkEventName(USER_GET_PHONENUMBER_ERROR, fromPage), error.message);
        });
      }).catch(error => {
        event.emit(checkEventName(USER_LOGIN_CALLBACK, fromPage), error);
        event.emit(checkEventName(USER_GET_PHONENUMBER_ERROR, fromPage), error.message);
      });
    });
  } else {
    loginAction((error, loginAction) => {
      event.emit(checkEventName(USER_GET_PHONENUMBER_ERROR, fromPage), e.detail.errMsg);
    });
  }
}

export const getPhoneNumber = (e) => {
  const fromPage = e.currentTarget.dataset.from;
  if (e.detail.errMsg === 'getPhoneNumber:ok') {
    const srd_session = wx.getStorageSync('srd_session');
    const globalData = getGlobalData();
    const res = e.detail;
    let phoneNumber;
    let countryCode;
    let union_id;
    return login.decodeUserInfo(srd_session, res.encryptedData, res.iv).then(data => {
      phoneNumber = data.phoneNumber;
      countryCode = data.countryCode;
      union_id = globalData.userInfo.union_id;
      if (countryCode && phoneNumber) {
        return login.bindMiniAppByAuto(union_id, phoneNumber, countryCode);
      }
      throw new Error('手机号获取失败,请重新获取');
    }).then(result => {
      if (result.is_register !== undefined && result.is_register === 0) {
        const newUserInfo = {
          is_bind: result.is_bind,
          mobile: result.profile,
          session_key: result.session_key,
          uid: result.uid,
          ssouid: result.ssouid,
          union_id: union_id,
          vip: result.vip
        };

        let userInfo = wx.getStorageSync('userInfo');
        userInfo = Object.assign(userInfo, newUserInfo);
        setStorageWithValueForKey('userInfo', userInfo);
        setStorageWithValueForKey('session_key', result.session_key);
        event.emit(checkEventName(USER_LOGIN_SUCCESS, fromPage));
        setTimeout(() => {
          event.emit(MY_USER_LOGIN_SUCCESS);
        }, 1000);
        wx.showToast({
          icon: 'none',
          title: '手机号授权成功!\r\n为享受更多权益,已为您注册有货会员!',
          duration: 3000
        });
      }
    }).catch(error => {
      event.emit(checkEventName(USER_GET_PHONENUMBER_ERROR, fromPage), error.message);
    });
  } else {
    event.emit(checkEventName(USER_GET_PHONENUMBER_ERROR, fromPage), e.detail.errMsg);
  }
}

export const getLoginButtonType = () => {
  const globalData = getGlobalData();

  if (globalData && globalData.userInfo && globalData.userInfo.uid) {
    return ''; // 已经是登录状态,合法用户
  }

  let isUnionID = globalData.userInfo && globalData.userInfo.union_id;// 如果有unionID情况
  let isPhoneNumber = isUnionID ? !(globalData.userInfo && globalData.userInfo.uid) : false; // 如果有unionID且没有uid,可以获取手机号自动绑定登录

  if (!isUnionID) {
    event.emit('change-login-status', {
      text: '微信登录',
      tips: ''
    });
    return 'getUserInfo';
  } else if (isPhoneNumber) {
    event.emit('change-login-status', {
      text: '绑定手机号',
      tips: '还差一步,绑定手机号码,加入Yoho!Family'
    });
    return 'getPhoneNumber';
  }

  return ''; // 已经是登录状态,合法用户
}