import { common } from '../utils'; import { useSmallProgramLogin } from '../hook'; import store from '../store'; let _app; /** * HTTP POST 请求封装 * complete:是否成功失败都往下执行 */ const httpPost = (url: string, data: any, options: any = {}, complete = undefined) => { let has = getApp().globalData.accountInfo.miniProgram.envVersion != 'develop'; // 如果不等于开发版本,默认启用请求加密 let querData: any = {}; // 判断当前请求接口不需要加密请求 if (common.isNotEmpty(getApp().globalData.noNeedSecretKeyApiArr)) { for (let i of getApp().globalData.noNeedSecretKeyApiArr) { if (url.indexOf(i) != '-1') { has = false; break; } } } // 新增判断请求的url 如果不存在callApiJSON,callApi.do请求,全部不加密(后续callApi.do接口前端也统一加密) if (url.indexOf('callApiJSON') == -1 && url.indexOf('callApi.do') == -1) { has = false; } let showLoading = true; if (options != undefined && options.showLoading != undefined) { showLoading = options.showLoading; } if (showLoading) { common.showLoading(); } let header: any = { 'content-type': 'application/json', token: store.state.token, 'call-appId': uni.getStorageSync('frontEndConfig').fixedAppjsGlobalData.appId, }; // 如果has 为true 代表当前请求接口需要加密 且获取的加密秘钥不为空 if (has && common.isNotEmpty(getApp().globalData.apiSecretKey)) { (header.appId = 'KASIET_alismaillpro'), (querData.data = common.desEncrypt(JSON.stringify(data), getApp().globalData.apiSecretKey)); } if (options) { const extOptions = [ 'showLoading', // 显示加载中 'onChunkReceived', // 分块传输监听 'timeout', // 超时时间, 默认取/app.json里的networkTimeout配置 'responseType', // 响应结果 ]; Object.keys(options).forEach((key) => { if (!extOptions.includes(key)) { header[key] = options[key]; } }); } return new Promise((resolve, reject) => { const enableChunked = options && typeof options.onChunkReceived == 'function'; const requestOptions: any = { url: url, data: common.isEmpty(querData) ? data : querData, method: 'POST', header: header, enableChunked: enableChunked, // 新增分块数据 success(res) { if (showLoading) { common.hideLoading(); } if (!complete) { if (options && options.construction) { resolve({ data: { Data: res.data, RespCode: 10000 } }); } else { resolve(res); } } }, fail(error) { if (showLoading) { common.hideLoading(); } if (!complete) { reject(error); } console.error(error); common.showToast(`连接超时,请重试`); }, complete(res) { if (complete) { resolve(res); } }, }; if (options && options.timeout != undefined && options.timeout != null) { requestOptions.timeout = options.timeout; } if (options && options.responseType != undefined && options.responseType != null) { requestOptions.responseType = options.responseType; } const wxRequest = uni.request(requestOptions); if (enableChunked) { wxRequest.onChunkReceived(options.onChunkReceived); } }); }; /** * 微信请求post方法封装 * url * data 以对象的格式传入 * 后端返回 401 token超时时,会重新发起调用登陆 */ const doPost = async (url: string, data: any, options: any = {}, complete = undefined) => { const response = httpPost(url, data, options, complete); let loginAgain = false; await response.then((resp: any) => { if (resp.data.RespCode == 401) { loginAgain = true; } }); // token未超时,直接返回 if (!loginAgain) { return response; } // token超时时,调用接口重新登录 if (uni.getStorageSync('isCall') != 1) { // 防止页面并发调用登录接口 uni.setStorageSync('isCall', 1); uni.setStorageSync('data_expiration', 0); // 获取登录失败轮询次数,,默认5次 let retry = getApp().globalData.retryNum; while (retry > 0) { await useSmallProgramLogin(_app).then((resp: any) => { if (resp.data.RespCode != '10000') { // 登录失败,需轮询,次数减一 retry--; } else { // 登录成功 retry = 0; // uni.clearStorageSync() } }); if (retry != 0) { // 需要重试时,先休眠300毫秒 await sleep(300); } } } // 接口调用重试次数,默认判断5次,每次间隔500毫秒 let retry = getApp().globalData.retryNum; while (retry > 0) { if (uni.getStorageSync('isCall') != 1) { // 如果已经重新登录成功,返回重新请求接口结果 return httpPost(url, data, options); } else { // 还未登录成功,休眠500毫秒再判断 await sleep(500); retry--; } } // 重试5次后,再次重新发起请求 return httpPost(url, data, options); }; /** * 微信请求get方法封装 * url * data 以对象的格式传入 * 后端返回 401 token超时时,会重新发起调用登陆 */ const doGet = async (url: string, data: any, options: any = {}) => { const response = httpGet(url, data, options); let loginAgain = false; await response.then((resp: any) => { if (resp.data.RespCode == 401) { loginAgain = true; } }); // token未超时,直接返回 if (!loginAgain) { return response; } // token超时时,调用接口重新登录 if (uni.getStorageSync('isCall') != 1) { // 防止页面并发调用登录接口 uni.setStorageSync('isCall', 1); uni.setStorageSync('data_expiration', 0); // 获取登录失败轮询次数,默认5次 let retry = getApp().globalData.retryNum; while (retry > 0) { await useSmallProgramLogin(_app).then((resp: any) => { if (resp.data.RespCode != '10000') { // 登录失败,需轮询,次数减一 retry--; } else { // 登录成功 retry = 0; } }); if (retry != 0) { // 需要重试时,先休眠300毫秒 await sleep(300); } } } // 接口调用重试次数,默认判断5次,每次间隔500毫秒 let retry = getApp().globalData.retryNum; while (retry > 0) { if (uni.getStorageSync('isCall') != 1) { // 如果已经重新登录成功,返回重新请求接口结果 return httpGet(url, data, options); } else { // 还未登录成功,休眠500毫秒再判断 await sleep(500); retry--; } } // 重试5次后,再次重新发起请求 return httpGet(url, data, options); }; // 新增 httpGet 基础方法 const httpGet = (url: string, data: any, options: any = {}) => { let showLoading = true; if (options != undefined && options.showLoading != undefined) { showLoading = options.showLoading; } if (showLoading) { common.showLoading(); } let header = { 'content-type': 'application/json', token: getApp().globalData.token || uni.getStorageSync('token'), 'call-appId': uni.getStorageSync('frontEndConfig').fixedAppjsGlobalData.appId, }; if (options) { Object.keys(options).forEach((key) => { if (key != 'showLoading') { header[key] = options[key]; } }); } return new Promise((resolve, reject) => { uni.request({ url: url, data: data, method: 'GET', header: header, success(res) { if (showLoading) { common.hideLoading(); } if (options && options.construction) { resolve({ data: { Data: res.data, RespCode: 10000 } }); } else { resolve(res); } }, fail(error) { if (showLoading) { common.hideLoading(); } reject(error); common.showToast(`连接超时,请重试`); }, }); }); }; //模拟线程休眠,需配合 async和await使用 const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); export default { doPost, doGet, };