微信小程序的经常使用受权-记录系列(1)

一、微信受权头像昵称等

先上代码,新版本getUserProfile:vue

wxml
<button wx:if="{{canIUseGetUserProfile}}" class="authBtn" bindtap="getUserProfile">当即受权</button>
js:
data: {    
    userInfo: {},   
    hasUserInfo: false,    
    canIUseGetUserProfile: false,
},
onLoad() {    
    //用来判断是否兼容新旧版本    
    let that = this;    
    if (app.globalData.userInfo) {      
        this.setData({        
            userInfo: app.globalData.userInfo,        
            hasUserInfo: true      
        })    
    }else if (wx.getUserProfile) {       
        this.setData({        
            canIUseGetUserProfile: true      
        })    
    } else {      
        // 在没有 open-type=getUserInfo 版本的兼容处理      
        wx.getUserInfo({        
            success: res => {          
                app.globalData.userInfo = res.userInfo;       
                this.setData({            
                    userInfo: res.userInfo,            
                    hasUserInfo: true          
                })        
            }     
        })    
    }
  },
  getUserProfile(e) {    
        let code = "";    
        let that = this;
    //先获取code和后台进行交换,由于会异步因此用了setTimeout    
        wx.login({      
            success(res) {        
                code = res.code;      
            }    
        });    
        setTimeout(() => {      
            wx.getUserProfile({        
                desc: '用于完善会员资料', // 声明获取用户我的信息后的用途,后续会展现在弹窗中,请谨慎填写        
                success: (res1) => {
                  //拿到用户头像昵称等信息          
                    that.setData({            
                        userInfo: res1.userInfo,            
                        hasUserInfo: true,          
                    })
                  //调接口存到数据库,并弹出获取手机号的弹框          
                    wx.request({            
                        url: 'https:njlingshi.com/api/weChatAuth?code='+code,            
                        method: "POST",            
                        success(res2) {              
                            that.setData({                
                                showPhoneModal: true,//展现获取手机号的弹框                
                                codeKey: res2.data.data.codeKey,//存储key和用户加密信息后面用到                
                                userInfoEncrypt: {                  
                                    "encryptedData": res1.encryptedData,                  
                                    "iv": res1.iv                
                                }              
                            })            
                        }          
                     })        
                   }      
                })    
           })  
    },
复制代码

旧版本getUserInfo:ios

wxml
<button wx:else class="authBtn" open-type="getUserInfo" bindgetuserinfo="getUserInfo">当即受权</button>
js:
//data部分和上面同样
getUserInfo(e) {    
    //在这里就能够拿到用户加密信息encryptedData和iv等
    // 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将再也不弹出弹窗,并直接返回匿名的用户我的信息    
    this.setData({      
        userInfo: e.detail.userInfo,      
        hasUserInfo: true    
    })    
    wx.login({      
        success(res) {        
            if (res.code) {          
                wx.request({            
                    url: 'https:njlingshi.com/api/weChatAuth?code='+code,            
                    method: "POST",            
                    success(res) {              
                        that.setData({                
                            showPhoneModal: true,//展现获取手机号的弹框                
                            "codeKey": res.data.data.codeKey,                
                            "userInfoEncrypt": {
                                //存储key和用户加密信息后面用到                  
                                "encryptedData": e.detail.encryptedData,                  
                                "iv": e.detail.iv                
                             }              
                        })            
                      }          
                   })        
                }      
          }    
      });  
},
复制代码

区别:

一、getUserProfile页面产生点击事件后才可调用,每次请求都会弹出受权窗口,须要在wx.getUserProfile({})方法执行后拿到用户信息git

getUserInfo在按钮点击的时候就能够拿到信息,目前不推荐使用了。数据库

二、记住这时候接口若是提示解密失败、微信解密验签失败是后端的锅不要背,硬气点!json

三、tips:小程序在最后审核上线的时候会卡登陆,若是你进页面必需要受权登陆才行可能会不经过,这个要先沟通好,首页等接口不须要token也能够访问。axios

二、受权获取手机号码

wxml:
<button class="authBtn" open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">获取手机号码</button>

js:getPhoneNumber(e) {    
    let that = this;    
    if (!e.detail.iv) {//判断是否容许受权,拿到加密信息,展现受权弹框      
        this.setData({        
            showPhoneModal: false      
        })      
        return;    
    }    
    wx.request({        
        url: 'https:njlingshi.com/api/miniProgramLogin',      
        method: "POST",      
        data: {//传入接口须要用到的各类参数          
            "codeKey": that.data.codeKey,          
            "userInfoEncrypt": that.data.userInfoEncrypt,          
            "userPhoneEncrypt": {            
                encryptedData: e.detail.encryptedData,            
                iv: e.detail.iv          
            }      
        },      
        success(res) {        
            if(res.statusCode == 200) {          
                app.globalData.token = res.data.data.token;//存入token和用户信息在全局变量中 
                app.globalData.userInfo = res.data.data;          
                that.setData({showPhoneModal: false})          
                wx.setStorage({            
                    key: "token",            
                    data: res.data.data.token          
                })          
                wx.setStorage({            
                    key: "userinfo",            
                    data: res.data.data          
                })          
                wx.showLoading({title: '加载中'});          
                setTimeout(()=>{wx.hideLoading();},1500)          
                //能够在这里调用界面须要token的接口        
            }else {          
                wx.showToast({            
                    icon:'error',            
                    title: res.data.message,          
                })        
            }      
        }    
    })  
},
复制代码

三、受权获取地址位置

app.json中加入  
"permission": {    
        "scope.userLocation": {      
        "desc": "你的位置信息将用于小程序位置效果展现"    
}},

app.js
onShow() {
   //获取用户当前位置    
    wx.getLocation({      
        type: 'gcj02',      
        success (res) {//记录经纬度方便后面其余界面用到        
            that.globalData.userLat = res.latitude;        
            that.globalData.userLong = res.longitude;      
        }    
    })
},
globalData: {    
    userLat: '',//用户所在经纬度    
    userLong: '',
}
复制代码

算出用户当前位置与目的位置的距离

app.js中写公共方法

// 计算距离函数  
Rad(d) {    //根据经纬度判断距离    
    return d * Math.PI / 180.0;  
},  
getDistance(lat1, lng1, lat2, lng2) {    
    // lat1用户的纬度    // lng1用户的经度    // lat2商家的纬度    // lng2商家的经度    
    var radLat1 = this.Rad(lat1);    
    var radLat2 = this.Rad(lat2);    
    var a = radLat1 - radLat2;    
    var b = this.Rad(lng1) - this.Rad(lng2);    
    var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));   
    s = s * 6378.137;    
    s = Math.round(s * 10000) / 10000;    
    s = s.toFixed(1) + 'km' //保留两位小数    
    return s  
},
js中使用示例:
app.getDistance(app.globalData.userLat,app.globalData.userLong,"31.929074190568766","118.8757504898559");
复制代码

四、封装请求接口

我的认为这样操做,在必定程度上作到了请求拦截,至关于vue的axios的请求拦截小程序

app.js

wxRequest(method, url, data, callback, errFun) {    
    let baseUrl = 'https://njlingshi.com';//这里千万不要写不少前缀否则后面接口不同很麻烦   
    wx.request({      
      url: baseUrl+url,      
      method: method,      
      data: data,      
      header: {        
          'content-type': method == 'GET' || method == 'POST'?'application/json':'application/x-www-form-urlencoded',        
          'Accept': 'application/json',        
          'Authorization': this.globalData.token      
      },      
      dataType: 'json',      
      success: function (res) {        
             if(res.statusCode == 200) {          
                  callback(res.data);        
             }else if(
                  res.statusCode == 401){//这里根据状况改401状态码,我这里代码登陆失效 
                      wx.showToast({            
                         icon: "none",            
                         title: '请登陆!',          
                      })          
                     wx.removeStorageSync('token');        
              }else {//剩余状况就是接口报错须要提醒了          
                      wx.showToast({            
                          icon: "none",            
                          title: res.data.errMsg ? res.data.errMsg : res.data.message,    
                      })        
               }      
       },      
      fail: function (err) {        
             console.log(err)        
             errFun(err);      
      }    
  })  
},
js调用:
    let that = this;    
    app.wxRequest('GET', '/api/getHotList',{}, (res) => {        
         this.setData({          
             hotList: res.data && res.data.length > 0 ? res.data : []        
         })    
    }, (err) => {        
         console.log(err)    
    })
复制代码

五、一些简单的小坑避免指南

  • 一、wx.showToast文字展现不全,吧icon去掉,就能够展现最多两行字了,若是仍是不够展现,本身能够写个组件用后端

  • 二、wxml须要对数组用到indexOfapi

  • 一、定义一个common.wxs在utils中数组

  • function indexOf(arr, value) {    
           if (arr.indexOf(value) < 0) {        
                return false;    
           } else {        
                return true;    
           }
      }
      module.exports.indexOf = indexOf;
    复制代码
  • wxml: 

    {{item}} {{item}} {{item}} //这样就能够在页面中使用indexOf啦,否则界面不支持,呜呜呜,太难了,才发现的坑
  • 公共样式能够写在app.wxss中,减小重复样式;公共的js能够放在app.js中

先写这么多,后期再更新,以为有用的朋友点个赞呀~

相关文章
相关标签/搜索