微信小程序登录处理 以及 wx.request的封装


相信大家做小程序的, 对微信登录的机制都有一定的了解以及想法了;
大家八仙过海 各显神通,下面这篇文章,只是我对其的了解
如果大家有好的想法 !!!请一定 与 我交流!!!

I、处理登录的逻辑

关于会遇到的问题以及处理

  1. 首先登录是个异步事件;
    既然是异步事件, 那么我们肯定要在回调函数中进行处理
    这样的话就要涉及到wx.request的封装;我们在下面讲

  2. 关于code的获取
    登录需要用户点击微信自带的button才能获取到

    <button class='login-btn' open-type="getUserInfo" bindgetuserinfo="getUserInfo" type="warn" size="default" loading="{{loading}}" bindtap="primary"> 一键登录 </button>
    
  3. 关于权限判断,以及如何判断
    咱们不能所有接口都需要登录, 那样的话连审核都过不了;
    这里同样需要对wx.requesrt进行封装;下面讲

  4. 登录的处理逻辑图:
    微信小程序登录逻辑图

II、wx.request的封装逻辑

1. wx.request的封装

  1. 基础层
    a. 调用扩展层的处理函数
    b. wx.request请求

  2. 扩展层
    // beforeRequest 处理有无网络状态
    // handleRequestInportData 处理请求参数
    // showMask 处理遮罩层
    // stopLoading 停止各种的loading
    // handleResponse 处理返回结果

2. wx.request的封装逻辑图

在这里插入图片描述

III、关于登录 对wx.request的封装

跟后端约定好返回码 做对应的操作;
我们这边规定 如果返回 code 等于 401 || code 等于 403的话就表示没有登录

if (res.data.code == '401' || res.data.code == '403') {
      console.error('没登录,去登录,并且设置状态')
      wx.removeStorageSync('accessToken');		// 清空之前的token
      if (that.globalData.isLogging) return true;		// 正在登录中
      that.globalData.isLogging = true;		// 没在登录中 进入登录状态,并且设置isLogging
      // 登录失效且不在白名单 
      if (!CONFIG['API_WHITE_LIST'].includes(thisUrl)) {
        // 跳到登录
        let pages = getCurrentPages();
        for (let i in pages) {
          if (pages[i].route == '/pages/login/login') {
            // console.log(i)
            wx.navigateBack({
              delta: pages.length - (i + 1)
            })
            return true;
          }
        }
        wx.navigateTo({ url: '/pages/login/login' });
        return true;
      }
      return;
    }

IV、相关代码

1. wx.request关于基础层的封装

// 基础层: 
  // 基于微信的request进行二次封装,myRequest是基础层
  // beforeRequest 处理有无网络状态
  // handleRequestInportData 处理请求参数
  // showMask 处理遮罩层
  // stopLoading 停止各种的loading
  // handleResponse 处理返回结果
  
  myRequest: function (url, data, methods, callback, loadType, errorFun, headers) {
    let _this = this;
    // 检查是拥有网络 没有网络 就return;
    if (_this.beforeRequest(url)) {
      console.log('beforeRequest return ' + _this.globalData.isLogging); 
      return;
    }
    // console.log(this.globalData)
    // 参数处理
    let theData = this.handleRequestInportData(url, data, methods, callback, loadType, errorFun, headers, _this);
    // 处理遮罩层
    this.showMask(theData.loadType);

    // 是否是启用模拟数据
    if (DEBUG) {
      let responseData = myData.getData(url, data);
      setTimeout(() => {
        console.log('DEBUG response : ')
        console.log(responseData.data)
        _this.stopLoading();
        callback(responseData)
        // _this.handleResponse(responseData, theData);
      }, 800)
    }else{
    // 开始请求
      wx.request({
        url: theData.url,
        data: {
          ...theData.data,
          ..._this.globalData.otherParams
        },
        method: theData.methods,
        header: theData.headers,
        success: function (res) {
          // 处理返回结果
          _this.handleResponse(res, theData, _this, url);
        },
        fail: function (err) {
          _this.stopLoading();
        },
        complete: function () {
        }
      })
    }
    // 请求结束
  },

2. wx.request 扩展层的封装


// 在请求发起之前需要做的事情 处理有无网络状态
  beforeRequest: function(tempUrl) {
    let _this = this;
    wx.getNetworkType({
      success: function (res) {
        if (res.networkType == 'none') {
          return true;
        }
      }
    })
  },

  // 处理请求参数:
  handleRequestInportData: (
    url,
    data,
    methods = 'post',
    callback = () => console.log('未传入回调callback'),
    loadType = 'mask',
    errorFun = (err) => {
      wx.hideLoading();
      wx.showToast({
        title: err.message,
        icon: 'none',
        // icon: 'success',
        mask: true,
        duration: 2000
      })
      console.log('未传入回调 errorFun')
    },
    headers = {},
    that
  ) => {
    let requestData = {};
    if (!url) {
      console.error('传入myRequest的URL不可为空');
      return;
    }
    // data.Authorization = 'Bearer ' + that.globalData.accessToken
    // console.error('Authorization: ' + data.Authorization);
    headers = {
      'content-type': 'application/json',
      'Authorization': 'Bearer ' + that.globalData.accessToken,
      'enctype': 'raw'
    }
    data.referrer_uid = that.globalData.referrer_uid != 0 ? that.globalData.referrer_uid : 0;

    requestData.url = InterFace[url];
    requestData.data = data;
    requestData.methods = methods;
    requestData.callback = callback;
    requestData.loadType = loadType;
    requestData.errorFun = errorFun;
    requestData.headers = headers;
    return requestData;
  },



  // 处理返回结果:
  handleResponse: (res, theData, that, tempUrl) => {
    let _this = this;
    that.stopLoading();
    if (res.data.code == '401' || res.data.code == '403') {
      console.error('没登录,去登录,并且设置状态')
      // console.error(that.globalData.isLogging)
      wx.removeStorageSync('accessToken');
      // 正在登录中 设置 isLogging
      if (that.globalData.isLogging) return true;
      that.globalData.isLogging = true;
      // 登录失效且不在白名单 !wx.getStorageSync('accessToken') && !API_WHITE_LIST.includes(tempUrl)
      if (!CONFIG['API_WHITE_LIST'].includes(tempUrl)) {
        // 跳到登录
        let pages = getCurrentPages();
        // Tips: 判断页面栈中是否有login
        for (let i in pages) {
          if (pages[i].route == '/pages/login/login') {
            wx.navigateBack({
              delta: pages.length - (i + 1)
            })
            return true;
          }
        }
        wx.navigateTo({ url: '/pages/login/login' });
        return true;
      }
      return;
    }
    if (res.data.status == 200 && res.data.code != 0) {
      // 调用错误处理函数
      theData.errorFun(res.data)
      return;
    } else if (res.data.code == '503' || res.data.code == '500') {
      // 故障页面
      wx.reLaunch({
        url: '/pages/error/error'
      })
      return;
    }
    // 正常情况下, 回调
    if (res.data.status == 200 && res.data.code == 0) {
      theData.callback(res.data);
      return;
    }
  },


  // 展示遮罩层:
  showMask: (loadType) =>{
    if(loadType == 'none') return;
    if(loadType == 'top'){
      wx.showNavigationBarLoading()
      return;
    }
    wx.showLoading({
      title: '加载中',
      mask: true,
    })
  },
  

  /*
  * 停止各种loading状态
  * @function stopLoading
  * @params {}
  * @barth {Constantine, 2017-11-13 17:19:15}
  */
  stopLoading: () => {
    wx.hideLoading();
    wx.hideNavigationBarLoading()
    wx.stopPullDownRefresh()
  },

3. 登录页面代码

<!--pages/login/login.wxml-->
<nav title="选择登录方式"></nav>
<view class='cul-null'>抱歉您还未登录呢, 请点击下方授权按钮登录</view>
<view class='cul-null' style='margin-top: 0; margin-bottom: 80rpx;'>以使用更多功能</view>
<!-- <view></view> -->


<button class='login-btn' open-type="getUserInfo" bindgetuserinfo="getUserInfo" type="warn" size="default" loading="{{loading}}" bindtap="primary"> 一键登录 </button>
<button class='login-btn' plain="{{true}}" type="default" size="default" bindtap="jumpTo" data-url='/pages/loginOld/loginOld'> 手机登录 </button>
// pages/login/login.js
   /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    app.globalData.isLogging = false;
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    app.globalData.isLogging = false;
  },
  
  // 发起登录
  getUserInfo: function (e) {
    console.log(e)
    this.setData({
      loading: true
    })
    let encryptedData = e.detail.encryptedData;
    let iv = e.detail.iv;

    console.log('login in')
    let _this = this;

    wx.login({
      success: ret => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
        var CODE = ret.code;
        app.globalData.otherParams.wxcode = ret.code;
        app.myRequest('login', {
          wxcode: CODE,
          info: e.detail.userInfo,
          allInfo: e.detail,
        },
          'get',
          function (data) {
            console.log(data)
            if(data.data.has_reg == false){
              _this.userRegister(encryptedData, iv, data.data.openid)
              console.error('没有注册过')
            }else{
              console.error('注册过')
              wx.showToast({
                title: '已有账号,登录中',
                icon: 'none',
                mask: true,
                duration: 1500
              })
              _this.saveData(data);
              _this.setData({
                loading: false,
                userInfo: data.data.memberProfile,
                hasUserInfo: true
              })
              if (!data.data.has_phone){
                // TODO: 判断用户有没有手机号,没有调用接口绑定,并且完善密码
              }
              setTimeout(() => {
                wx.navigateBack({
                  delta: 1
                })
              }, 800)
            }
            // _this.globalData.token = data.api_token;
            // _this.globalData.shareToken = data.data.share_token
          })
        console.log('login', ret)
      }
    })
  },

4.关于登录按钮的样式

不满意的话你可以让微信自带的buttom opacity = 0
然后自己写一个想要的样式放在自带的buttom的下面

猜你喜欢

转载自blog.csdn.net/weixin_37880401/article/details/89141182