十年河东,十年河西,莫欺少钱穷
学无止境,精益求精
个人是个二把手,随笔记录,用于记录学习 ,供以后参考用。
场景:如果无需登录,通过获取用户的基本信息来获取Token,那么,当Token过期时,我们只需重新获取用户基本信息,在拿到Token即可。
如果有登陆页面,一旦Token过期,我们则跳转到登录页面即可。
系统初始化时,我们将Token赋值为空,过期时间赋值为:1900-01-01
onLaunch: function (options) { let that=this; wx.setStorageSync(\'token\', \'\'); wx.setStorageSync(\'tokenOverTime\', "1900-01-01"); that.GetNavigationBarInfo(options); that.autoUpdate(); },
App.JS全部代码如下,主要用于初始化Token值及过期时间,获取系统导航栏相关数据及小程序新版本自动更新
// app.js App({ globalData: { environment:\'dev\',// dev uat prd statusBarHeight: 0, //状态栏高度 menuButtonHeight: 0, //胶囊按钮高度 navigationBarHeight: 0, //计算得出的导航栏高度 navigationBarAndStatusBarHeight: 0, //导航栏和状态栏高度之和 platform: "", //手机型号 android 或 IOS isShare:false, //是否由分享而来 }, /** * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次) */ onLaunch: function (options) { let that=this; wx.setStorageSync(\'token\', \'\'); wx.setStorageSync(\'tokenOverTime\', "1900-01-01"); that.GetNavigationBarInfo(options); that.autoUpdate(); }, GetNavigationBarInfo:function(options){ let that = this; // 判断是否由分享进入小程序 从分享进入小程序时 返回上一级按钮不应该存在 if (options.scene == 1007 || options.scene == 1008) { tthathis.globalData.isShare = true; } else { that.globalData.isShare = false; }; const { statusBarHeight, platform } = wx.getSystemInfoSync();//获取系统信息 const { top, height } = wx.getMenuButtonBoundingClientRect(); //console.log(wx.getSystemInfoSync()) that.globalData.platform=platform; //状态栏高度 that.globalData.statusBarHeight = statusBarHeight; // 胶囊按钮高度 一般是32px 如果获取不到就使用32px that.globalData.menuButtonHeight = height ? height : 32; // 判断胶囊按钮信息是否成功获取 if (top && top !== 0 && height && height !== 0) { // 导航栏高度 that.globalData.navigationBarHeight = (top - statusBarHeight) * 2 + height } else { //个别手机获取不到 根据机型进行赋值 that.globalData.navigationBarHeight = platform === \'android\' ? 48 : 40 } //用于绝对定位 占用空间 that.globalData.navigationBarAndStatusBarHeight= that.globalData.navigationBarHeight+that.globalData.statusBarHeight; }, autoUpdate: function() { var self = this // 获取小程序更新机制兼容 if (wx.canIUse(\'getUpdateManager\')) { const updateManager = wx.getUpdateManager() //1. 检查小程序是否有新版本发布 updateManager.onCheckForUpdate(function(res) { //console.log(res) // 请求完新版本信息的回调 if (res.hasUpdate) { //检测到新版本,需要更新,给出提示 wx.showModal({ title: \'更新提示\', content: \'检测到新版本,是否下载新版本并重启小程序?\', success: function(res) { if (res.confirm) { //2. 用户确定下载更新小程序,小程序下载及更新静默进行 self.downLoadAndUpdate(updateManager) } else if (res.cancel) { //用户点击取消按钮的处理,如果需要强制更新,则给出二次弹窗,如果不需要,则这里的代码都可以删掉了 wx.showModal({ title: \'温馨提示~\', content: \'本次版本更新涉及到新的功能添加,旧版本无法正常访问的哦~\', showCancel:false,//隐藏取消按钮 confirmText:"确定更新",//只保留确定更新按钮 success: function(res) { if (res.confirm) { //下载新版本,并重新应用 self.downLoadAndUpdate(updateManager) } } }) } } }) } }) } else { // 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示 wx.showModal({ title: \'提示\', content: \'当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。\' }) } }, /** * 下载小程序新版本并重启应用 */ downLoadAndUpdate: function (updateManager){ var self=this wx.showLoading(); //静默下载更新小程序新版本 updateManager.onUpdateReady(function () { wx.hideLoading() //新的版本已经下载好,调用 applyUpdate 应用新版本并重启 updateManager.applyUpdate() }) updateManager.onUpdateFailed(function () { // 新的版本下载失败 wx.showModal({ title: \'已经有新版本了哟~\', content: \'新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~\', }) }) }, })
首先,我们看下无登录页面的封装【我这里模拟获取Token的信息是使用用户名及密码的方式,真正的无登录场景时,获取Token一般会使用用户基本信息及openID】。
import * as common from "../../utils/config/config" const ApiUrl = common.config.swagger.apiUrl; var dayjs = require(\'dayjs\') export const request = (parm) => { let tokenOverTime = wx.getStorageSync(\'tokenOverTime\'); let bol = dayjs().isBefore(dayjs(tokenOverTime)); if (!bol) { return new Promise((resolve, reject) => { wx.request({ url: ApiUrl + \'/Api/V1/Login/UserLogin\', //获取Token的接口 data: { "userName": "admin", "userPwd": "123456" }, method: "POST", header: { \'content-type\': \'application/json\' // 默认值 }, success(res) { if (res.statusCode == 200 && res.data&&res.data.data && res.data.data.token) { let newToken = \'Bearer \' + res.data.data.token; // //假设我们的Token过期时间时120分钟,留一分钟的余地 let newTokenOverTime = dayjs().add(119, \'minute\').format("YYYY-MM-DD HH:mm:ss"); //假设我们的Token过期时间时120分钟,留一分钟的余地 wx.setStorageSync(\'token\', newToken); wx.setStorageSync(\'tokenOverTime\', newTokenOverTime); resolve(res.data); } else { reject(res.data) } } }) }).then(A => { return new Promise((resolve, reject) => { let token = wx.getStorageSync(\'token\'); parm.header = { "Authorization": token }; parm.url = ApiUrl + parm.url; wx.request({ ...parm, // 展开对象 success(res) { if (res.statusCode == 200 && res.data && res.data.resultCode == 0) { resolve(res.data); } else if (res.statusCode == 200 && res.data && res.data.resultCode == -1) { wx.showModal({ title: \'系统异常\', content: res.data.resultMessage, cancel: false }) reject(res.data); } else if (res.statusCode >= 500 && res.statusCode < 600) { wx.showModal({ title: \'系统错误\', content: \'网络请求错误\', cancel: false }) reject(res.data); } else { reject(res.data); } } }) }) }) } else { let token = wx.getStorageSync(\'token\'); return new Promise((resolve, reject) => { parm.header = { "Authorization": token }; parm.url = ApiUrl + parm.url; wx.request({ ...parm, // 展开对象 success(res) { if (res.statusCode == 200 && res.data && res.data.resultCode == 0) { resolve(res.data); } else if (res.statusCode == 200 && res.data && res.data.resultCode == -1) { wx.showModal({ title: \'系统异常\', content: res.data.resultMessage, cancel: false }) reject(res.data); } else if (res.statusCode >= 500 && res.statusCode < 600) { wx.showModal({ title: \'系统错误\', content: \'网络请求错误\', cancel: false }) reject(res.data); } else { reject(res.data); } } }) }) } }
注释如下:
import * as common from "../../utils/config/config"
const ApiUrl = common.config.swagger.apiUrl;
主要获取请求的Url,及Api的基础网址。
var dayjs = require(\'dayjs\')
dayJs 主要用于处理时间。
wx.request({ url: ApiUrl + \'/Api/V1/Login/UserLogin\', //获取Token的接口 data: { "userName": "user", "userPwd": "123456" },
获取Token的接口,在无登录页面小程序中,一般都是先获取用户基本信息,OpenId后,再通过传递这些信息获取Token。
整个Request 返回 ProMise对象,因此,在调用时,我们只需用Then方法接收返回的结果即可。
调用如下:
getdata() { let that = this; let search = { "pageNumber": 1, "pageSize": 10 } request.request({ url: "/api/V2/Finance/SearchFinanceGroupInfo", data: search, method: "POST" }).then(result => { console.log(result); }); }
以上便是无登录页的封装及调用。
2、有登陆页面的封装就很简单了,一旦Token过期,则直接跳转至登录页,如下:
import * as common from "../../utils/config/config" const ApiUrl = common.config.swagger.apiUrl; var dayjs = require(\'dayjs\') export const request = (parm) => { let tokenOverTime = wx.getStorageSync(\'tokenOverTime\'); let bol = dayjs().isBefore(dayjs(tokenOverTime)); if (!bol) { //Token过期,跳转至登录页 return new Promise((resolve, reject) => { resolve("tokenTimeOut") wx.showModal({ title: \'提示\', content: \'登录超时,请重新登录\', showCancel: false, success: function (res) { if (res.confirm) { wx.reLaunch({ url: \'/pages/login/account/account\', }) } } }) }).catch(value => { console.log(value); }) } else { let token = wx.getStorageSync(\'token\'); return new Promise((resolve, reject) => { parm.header = { "Authorization": token }; parm.url = ApiUrl + parm.url; wx.request({ ...parm, // 展开对象 success(res) { if (res.statusCode == 200 && res.data && res.data.resultCode == 0) { resolve(res.data); } else if (res.statusCode == 200 && res.data && res.data.resultCode == -1) { wx.showModal({ title: \'系统异常\', content: res.data.resultMessage, cancel: false }) reject(res.data); } else if (res.statusCode >= 500 && res.statusCode < 600) { wx.showModal({ title: \'系统错误\', content: \'网络请求错误\', cancel: false }) reject(res.data); } else { reject(res.data); } } }) }) } }
附注,config.js 如下:
var app = getApp(); export let config = new class { constructor() { if (app.globalData.environment == "prd") { this.swagger = { imgUrl: \'https://xxx.com/images/user/\', // 图片-正式服务器 apiUrl: \'https://xxx.com/pingtaiBackend\', } } else if (app.globalData.environment == "uat") { this.swagger = { imgUrl: \'https://xxx.com/SIT/images/user/\', // 图片-UAT服务器 apiUrl: \'https://xxx.com/SIT/pingtaiBackend\', } } else { this.swagger = { imgUrl: \'https://xxx.com/DEV/images/user/\', // 图片-测试服务器 apiUrl: \'https://xxx.com/DEV/pingtaiBackend\' } } } swagger = { } };
没什么好说了,要想看的懂,必须熟练ES6 / Promise的使用及DayJS,小程序开发组件库。
@天才卧龙的博客
请发表评论