#主要的封装是wxRequest、wxRequestGet、wxRequestPost、wxRequestPromise、headers这几个函数,由于太过赘余不进行截图展示,可以看utils.js
#wxRequest方法
wxRequest其实跟原始的wx.request没有太大的不同,相当于一个中间键,可以更灵活的配置,可维护性更高,一致请求,首先来解析一些wxRequest,以下简介的说明下
获取本地存储的token(ssoAuthToken),如果token存在就设置header,直接请求接口,不存在就重新刷新token之后,再请求该接口
isLoading是用来判断某些接口是否需要wx.showLoading(加载中),就可能我不是所有的接口都需要loading的提示,只是部分请求时长比较久的接口需要,所以我们存了一个需要loading的数组,判断请求的接口url是否存在这个数组中,存在就显示loading,而这个数组的数据都是从api.js里面拿出来的,如图一所示,我们每个API都是以对象的方式存的,为什么这样做呢,主要是想灵活点,例如我可能需要调不同的服务器的接口,那么我就可以配置多一个baseUrl的字段,调接口就传多一个baseUrl,如果没有传就使用默认的服务器域名
always方法其实是相当于请求失败的一个拦截器,请求失败后做什么事情
#wxRequestPromise方法
是加入Promise的一个操作,方便我们做链式调用,最后执行resolve或reject方法,返回一个Promise对象,供我们使用.then
#演示不同的请求方法代码片段
#util.wxRequest util.wxRequest({ url: api.queryServiceAreaByName.url, data: queryServiceAreaByName, method: 'POST', success: function (res) { console.log(res); } })
#util.wxRequest
util.wxRequest({url: api.queryServiceAreaByName.url,data: queryServiceAreaByName,method: 'POST',success: function (res) {console.log(res);}})
#util.wxRequestPost
util.wxRequestPost({url: api.getEvaluateList.url,data,}).then(res => res.data.data).then(data => {console.log('data', data);})
#util.wxRequestPost util.wxRequestPost({ url: api.getEvaluateList.url, data, }) .then(res => res.data.data) .then(data => { console.log('data', data); })
#图一
const config = require('../config/config.js');
const dayjs = require("./dayjs");
const api = require("./api.js");
const app = getApp();const loadingApi = [api.queryServiceAreaInPoint.url,api.queryConstructionInPoint.url,api.queryServiceAreaByName.url,api.queryServiceAreaWithPoint.url,api.getUserDetails.url,api.addEvaluateItem.url,api.queryServiceAreaDetailInMap.url,api.queryOrderByPhone.url
];const formatTime = date => {const year = date.getFullYear()const month = date.getMonth() + 1const day = date.getDate()const hour = date.getHours()const minute = date.getMinutes()const second = date.getSeconds()return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}const formatNumber = n => {n = n.toString()return n[1] ? n : '0' + n
}function headers(header) {header = header || {};//小应用特殊头header['X-Requested-isWXAPP'] = 'YES';//session_id , vmc_uid 处理var session_id = wx.getStorageSync('_SID'),vmc_uid = wx.getStorageSync('_VMC_UID');var ownshop = wx.getStorageSync('own_shop');// SIDif (session_id)header['X-WxappStorage-SID'] = session_id;if (ownshop) {header['X-REQUESTED-HEADER-VSHOPID'] = ownshop;}// UIDif (vmc_uid)header['X-WxappStorage-VMC-UID'] = vmc_uid;if (wx.getStorageSync('merchant_id')) {header['X-WxappStorage-MCH-ID'] = wx.getStorageSync('merchant_id');}if (config.RUN_ON_SAAS && wx.getExtConfig) {var ext_vars = wx.getExtConfigSync();// SAAS RUN TYPEheader['x-requested-saas-mode'] = 'APP';header['x-requested-saas-app'] = ext_vars.host_pre;header['x-requested-saas-client'] = ext_vars.client_id;header['x-requested-saas-order'] = ext_vars.order_id;}return header;
}function wxRequest(params) {let ssoAuthToken = wx.getStorageSync('sso_auth_token') || null;let isLoading = loadingApi.includes(params.url);if (!params.header) {params.header = {};}// loading加载if (isLoading) {wx.showLoading({title: '加载中',})}// 如果没有baseUrl使用config上配置的,如果有使用传入的if (!params.baseUrl) {params.url = config.BASE_URL + params.url;} else {params.url = params.baseUrl + params.url;}headers(params.header);//content-typeparams.header['content-type'] = params.header['content-type'] ? params.header['content-type'] : 'application/json';if (ssoAuthToken) {params.header['accessToken'] = ssoAuthToken.accessToken;params.header['refreshToken'] = ssoAuthToken.refreshToken;let serviceAreaIds = ssoAuthToken.serviceAreas.map(item => item.id);if (params.data.serviceAreaIdList) {params.header['serviceAreaIds'] = params.data.serviceAreaIdList[0];} else {params.header['serviceAreaIds'] = serviceAreaIds[0];}}// 拿到接口数据后进行处理,相当于拦截器var always = function (res) {console.log('util.js:always')if (res.data && !res.data.success) {var res_redirect = res.data.redirect;if (res_redirect && res_redirect.match && res_redirect.match(/passport-login/i)) {//服务端登录状态丢失,重新登录delete (app.globalData.member);return checkMember(function () {wx.showModal({title: '已刷新用户登录状态',content: '请重新进入',showCancel: false,success: function (res) {wx.navigateBack();}});});}}};if (params.success) {var _tmp = params.success;params.success = null;params.success = function (res) {always(res);_tmp(res);if (isLoading) {// setTimeout(function () {wx.hideLoading();// }, 1000)}};} else {params.success = function (res) {always(res);};}// 获取ssoAuthToken,如果ssoAuthToken里的accessToken、refreshToken过期了,刷新后再请求接口 if (ssoAuthToken) {let timestamp = dayjs(new Date()).valueOf();if (ssoAuthToken.expiresIn < timestamp) {// 这里过期的时候可能执行多次,因为一个页面可能调了多个接口,可以做500ms的队列if (app && app.globalData) {app.globalData.loginModal.getTokenByRefreshToken(params);}} else {wx.request(params);}} else {wx.request(params);}
}// promise 封装 wxRequest
const wxRequestPromise = (method) =>(params) => new Promise((resolve, reject) => {if (!params.url) throw 'params url not found'params.method = methodparamsFn(params, 'success', resolve)paramsFn(params, 'fail', reject)console.log('params', params);wxRequest(params)})const paramsFn = (params, fnName, cb) => {const fn = params[fnName] || (() => { })params[fnName] = nullparams[fnName] = (res) => {fn(res)cb(res)}
}function wxUpload(params) {if (!params.header) {params.header = {};}headers(params.header);//content-typeparams.header['content-type'] = 'multipart/form-data';wx.uploadFile(params);
}
const checkMemberHook = function (page_ins, page_callback_fn) {let the_member = app.globalData.member;try {page_ins.setData({'member': the_member,});} catch (e) {//TODO}typeof page_callback_fn == 'function' && page_callback_fn(the_member);
}function checkMember(callback, is_retry) {var _this = this;clearTimeout(app.getMemberTimer);app.getMemberTimer = setTimeout(function () {console.log('begin getMember at ' + new Date());app.getMember(function (member) {if (member.member_id) {return checkMemberHook(_this, callback);}wxRequest({url: config.BASE_URL + '/openapi/toauth/callback/wechat_toauth_wxapppam/callback',method: 'POST',data: member,success: function (res) {if (!res.data.result || res.data.result != 'success') {console.info('oauth server callback res error:');console.info(res);wx.showModal({title: '授权失败',content: res.data.data || '',showCancel: (!is_retry),confirmText: (!is_retry ? '重试' : '确定'),success: function (res) {if (!is_retry && res.confirm) {checkMember.apply(_this, [callback, true]);}}});} else {// app.globalData.member.member_id = res.data.data.member_id;// app.globalData.member.openid = res.data.data.openid;Object.assign(app.globalData.member, res.data.data);checkMemberHook(_this, callback);}},complete: function () {}});});}, 0);
}function formatArea(area_str = '') {var match = area_str.match(/mainland:([^:]+)/);if (match) {return match[1].split('/').join('-');}
}function fix_img_url(url) {if (url.match(/^http([s]*):/)) {return url;}return 'https:' + url;
}//倒计时
function count_down(that, intDiff) {function cd() {var day = 0,hour = 0,minute = 0,second = 0; //时间默认值if (intDiff > 0) {day = Math.floor(intDiff / (60 * 60 * 24)).toString();hour = (Math.floor(intDiff / (60 * 60)) - (day * 24)).toString();minute = (Math.floor(intDiff / 60) - (day * 24 * 60) - (hour * 60)).toString();second = (Math.floor(intDiff) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)).toString();}if (day <= 9)day = '0' + day;if (hour <= 9)hour = '0' + hour;if (minute <= 9)minute = '0' + minute;if (second <= 9)second = '0' + second;if (day == 0 && hour == 0 && minute == 0 && second == 0) {clearInterval(cd);}that.setData({countdown: {days: day,hours: hour,minutes: minute,seconds: second,}});intDiff -= 1;}setInterval(cd, 1000)
};function scene_parse(scene) {if (scene) {try {var scene_obj = JSON.parse(decodeURIComponent(scene));} catch (e) {return false;}if (typeof scene_obj == 'object') {return scene_obj;}return false;}return false;
}/*获取当前页带参数的url*/
function getCurrentPageUrlWithArgs() {var pages = getCurrentPages() //获取加载的页面var currentPage = pages[pages.length - 1] //获取当前页面的对象var url = currentPage.route //当前页面urlvar options = currentPage.options //如果要获取url中所带的参数可以查看options//拼接url的参数var urlWithArgs = url + '?'for (var key in options) {var value = options[key]urlWithArgs += key + '=' + value + '&'}urlWithArgs = urlWithArgs.substring(0, urlWithArgs.length - 1)return urlWithArgs
}function gotoIndex() {wx.switchTab({url: "/pages/index/index"});
}function merchantShare(url) {let merchant_id;if (wx.getStorageSync('merchant_id')) {merchant_id = wx.getStorageSync('merchant_id');} else {merchant_id = 0;}if (url.indexOf("?") != -1) {url += '&merchant_id=' + merchant_id} else {url += '?merchant_id=' + merchant_id}return url;
}function getQuery(url, query) {if (url.indexOf('?') < 0)return;var arr = url.split('?');var query_arr = arr[1].split('&');for (var i = 0; i < query_arr.length; i++) {let single_arr = query_arr[i].split('=');console.log('single_arr', single_arr);if (!single_arr[1]) continue;query[single_arr[0]] = single_arr[1];}return query;
}function setTabBarBadge() {wxRequest({url: config.BASE_URL + '/openapi/cart/count',success: function (res) {try {if (res.data.data.quantity > 0) {wx.setTabBarBadge({index: 1,text: res.data.data.quantity.toString(),success: function () {},fail: function () {},complete: function (e) {}})} else {wx.removeTabBarBadge({index: 1,success: function () {},fail: function () {},complete: function (e) {}})}} catch (e) {console.log(e)}}});
}// 过滤显示服务区的拥有服务图标
function filterServiceProvidedIcon(params) {if (!params) {return []}var IconObj = {//餐饮 coffeeActivecatering: 'coffeeActive',//住宿 oilActiveaccommodation: 'oilActive',//购物 shoppingActiveshopping: 'shoppingActive',//卫生间 toiletActivetoilet: 'toiletActive',//停车场 parkparking_lot: 'park',//加油站 gasfuel_filling: 'gas',//充电桩 chargerecharge: 'charge',//加气站 naturalGasair_entrapping: 'naturalGas',//维修 maintainmaintenance: 'maintain',//其他服务 more}var originIcon = params.split(',')var fileterIcon = originIcon.map(element => IconObj[element])return fileterIcon.filter(ele => ele)
}function setHtmlSnip(keyword, text) {return '<div>' + text.replace(new RegExp(keyword, 'g'), `<span style="color: blue">${keyword}</span>`) + '</div>'
}const wxRequestGet = wxRequestPromise('GET')
const wxRequestPost = wxRequestPromise('POST')function getUserInfo() {return new Promise((resolve, reject) => {const wxUserInfo = wx.getStorageSync('wx_userinfo') || {}if (wxUserInfo.nickName) {resolve(wxUserInfo)} else {wx.getUserInfo({success: (result) => {wx.setStorage({data: { ...wxUserInfo, ...result.userInfo },key: 'wx_userinfo',})resolve(result.userInfo)},complete: () => resolve({}),})}})
}const buriedPoint = async (data = {}) => {const { scene } = wx.getLaunchOptionsSync()const wxUserInfo = await getUserInfo()// console.log('wxUserInfo', wxUserInfo);data = {...data,buriedPointType: data.path ? 0 : 1,type: Number(scene !== 1001),nickName: wxUserInfo.nickName || '',phoneNumber: wxUserInfo.phoneNumber || '',}console.log('buriedPoint', data);return wxRequestPost({url: api.buriedPoint.url,data,})
}const checkLogin = () => new Promise((resolve, reject) => {const app = getApp()if (app.globalData.checkLogin) {resolve()} else {const cb = app.checkLoginReadyCallbackapp.checkLoginReadyCallback = () => {typeof cb === 'function' && cb()resolve()};}
})const getTime= function(value, flag) {let theTime = parseInt(value);// 秒let middle= 0;// 分let hour= 0;// 小时let result = ""if(theTime > 60) {middle= parseInt(theTime/60);theTime = parseInt(theTime%60);if(middle> 60) {hour= parseInt(middle/60);middle= parseInt(middle%60);}if(flag) {result = ""+parseInt(theTime)+"秒"}} else {result = ""+parseInt(theTime)+"秒"}if(middle > 0) {result = ""+parseInt(middle)+"分钟"+result;}if(hour> 0) {result = ""+parseInt(hour)+"小时"+result;}return result;
}function enclosureJHpay(params) {var _this = this;let userInfo = wx.getStorageSync('wx_userinfo');return wxRequestPost({url: api.enclosureJHpay.url,data: {...params,appId: config.APPID,openId: userInfo.openId}}).then(res => {let payParams = res.data.data;return new Promise((resolve, reject) => {console.log(res)wx.requestPayment({timeStamp: payParams.timeStamp,nonceStr: payParams.nonceStr,package: payParams.mypackage,signType: payParams.signType,paySign: payParams.paySign,success: function (res) {console.log(res);resolve(res);},fail: function (err) {console.log(err);reject(err)}})})})
}function getQueryString(urlStr) {let urlParams = {};let str = urlStr.substr(urlStr.indexOf("?")+1); //从第一个字符开始 因为第0个是?号 获取所有除问号的所有符串let strs = str.split("&");for (let i = 0; i < strs.length; i++) {let sTemp = strs[i].split("=");urlParams[sTemp[0]]=(sTemp[1]);}return urlParams
}module.exports = {formatTime: formatTime,headers: headers,wxRequest: wxRequest,wxUpload: wxUpload,checkMember: checkMember,formatArea: formatArea,fixImgUrl: fix_img_url,countdown: count_down,sceneParse: scene_parse,getCurrentPageUrlWithArgs: getCurrentPageUrlWithArgs,gotoIndex: gotoIndex,merchantShare: merchantShare,getQuery: getQuery,setTabBarBadge: setTabBarBadge,filterServiceProvidedIcon: filterServiceProvidedIcon,wxRequestGet,wxRequestPost,buriedPoint,checkLogin,getUserInfo,setHtmlSnip: setHtmlSnip,getTime: getTime,enclosureJHpay: enclosureJHpay,getQueryString: getQueryString
}