request.ts 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. import { common } from '../utils';
  2. import { useSmallProgramLogin } from '../hook';
  3. import store from '../store';
  4. let _app;
  5. /**
  6. * HTTP POST 请求封装
  7. * complete:是否成功失败都往下执行
  8. */
  9. const httpPost = (url: string, data: any, options: any = {}, complete = undefined) => {
  10. let has = getApp().globalData.accountInfo.miniProgram.envVersion != 'develop'; // 如果不等于开发版本,默认启用请求加密
  11. let querData: any = {};
  12. // 判断当前请求接口不需要加密请求
  13. if (common.isNotEmpty(getApp().globalData.noNeedSecretKeyApiArr)) {
  14. for (let i of getApp().globalData.noNeedSecretKeyApiArr) {
  15. if (url.indexOf(i) != '-1') {
  16. has = false;
  17. break;
  18. }
  19. }
  20. }
  21. // 新增判断请求的url 如果不存在callApiJSON,callApi.do请求,全部不加密(后续callApi.do接口前端也统一加密)
  22. if (url.indexOf('callApiJSON') == -1 && url.indexOf('callApi.do') == -1) {
  23. has = false;
  24. }
  25. let showLoading = true;
  26. if (options != undefined && options.showLoading != undefined) {
  27. showLoading = options.showLoading;
  28. }
  29. if (showLoading) {
  30. common.showLoading();
  31. }
  32. console.log('request', store.state);
  33. let header: any = {
  34. 'content-type': 'application/json',
  35. token: store.state.base.token,
  36. 'call-appId': uni.getStorageSync('frontEndConfig').fixedAppjsGlobalData.appId,
  37. };
  38. // 如果has 为true 代表当前请求接口需要加密 且获取的加密秘钥不为空
  39. if (has && common.isNotEmpty(getApp().globalData.apiSecretKey)) {
  40. (header.appId = 'KASIET_alismaillpro'),
  41. (querData.data = common.desEncrypt(JSON.stringify(data), getApp().globalData.apiSecretKey));
  42. }
  43. if (options) {
  44. const extOptions = [
  45. 'showLoading', // 显示加载中
  46. 'onChunkReceived', // 分块传输监听
  47. 'timeout', // 超时时间, 默认取/app.json里的networkTimeout配置
  48. 'responseType', // 响应结果
  49. ];
  50. Object.keys(options).forEach((key) => {
  51. if (!extOptions.includes(key)) {
  52. header[key] = options[key];
  53. }
  54. });
  55. }
  56. return new Promise((resolve, reject) => {
  57. const enableChunked = options && typeof options.onChunkReceived == 'function';
  58. const requestOptions: any = {
  59. url: url,
  60. data: common.isEmpty(querData) ? data : querData,
  61. method: 'POST',
  62. header: header,
  63. enableChunked: enableChunked, // 新增分块数据
  64. success(res) {
  65. if (showLoading) {
  66. common.hideLoading();
  67. }
  68. if (!complete) {
  69. if (options && options.construction) {
  70. resolve({ data: { Data: res.data, RespCode: 10000 } });
  71. } else {
  72. resolve(res);
  73. }
  74. }
  75. },
  76. fail(error) {
  77. if (showLoading) {
  78. common.hideLoading();
  79. }
  80. if (!complete) {
  81. reject(error);
  82. }
  83. console.error(error);
  84. common.showToast(`连接超时,请重试`);
  85. },
  86. complete(res) {
  87. if (complete) {
  88. resolve(res);
  89. }
  90. },
  91. };
  92. if (options && options.timeout != undefined && options.timeout != null) {
  93. requestOptions.timeout = options.timeout;
  94. }
  95. if (options && options.responseType != undefined && options.responseType != null) {
  96. requestOptions.responseType = options.responseType;
  97. }
  98. const wxRequest = uni.request(requestOptions);
  99. if (enableChunked) {
  100. wxRequest.onChunkReceived(options.onChunkReceived);
  101. }
  102. });
  103. };
  104. /**
  105. * 微信请求post方法封装
  106. * url
  107. * data 以对象的格式传入
  108. * 后端返回 401 token超时时,会重新发起调用登陆
  109. */
  110. const doPost = async (url: string, data: any, options: any = {}, complete = undefined) => {
  111. const response = httpPost(url, data, options, complete);
  112. let loginAgain = false;
  113. await response.then((resp: any) => {
  114. if (resp.data.RespCode == 401) {
  115. loginAgain = true;
  116. }
  117. });
  118. // token未超时,直接返回
  119. if (!loginAgain) {
  120. return response;
  121. }
  122. // token超时时,调用接口重新登录
  123. if (uni.getStorageSync('isCall') != 1) {
  124. // 防止页面并发调用登录接口
  125. uni.setStorageSync('isCall', 1);
  126. uni.setStorageSync('data_expiration', 0);
  127. // 获取登录失败轮询次数,,默认5次
  128. let retry = getApp().globalData.retryNum;
  129. while (retry > 0) {
  130. await useSmallProgramLogin(_app).then((resp: any) => {
  131. if (resp.data.RespCode != '10000') {
  132. // 登录失败,需轮询,次数减一
  133. retry--;
  134. } else {
  135. // 登录成功
  136. retry = 0;
  137. // uni.clearStorageSync()
  138. }
  139. });
  140. if (retry != 0) {
  141. // 需要重试时,先休眠300毫秒
  142. await sleep(300);
  143. }
  144. }
  145. }
  146. // 接口调用重试次数,默认判断5次,每次间隔500毫秒
  147. let retry = getApp().globalData.retryNum;
  148. while (retry > 0) {
  149. if (uni.getStorageSync('isCall') != 1) {
  150. // 如果已经重新登录成功,返回重新请求接口结果
  151. return httpPost(url, data, options);
  152. } else {
  153. // 还未登录成功,休眠500毫秒再判断
  154. await sleep(500);
  155. retry--;
  156. }
  157. }
  158. // 重试5次后,再次重新发起请求
  159. return httpPost(url, data, options);
  160. };
  161. /**
  162. * 微信请求get方法封装
  163. * url
  164. * data 以对象的格式传入
  165. * 后端返回 401 token超时时,会重新发起调用登陆
  166. */
  167. const doGet = async (url: string, data: any, options: any = {}) => {
  168. const response = httpGet(url, data, options);
  169. let loginAgain = false;
  170. await response.then((resp: any) => {
  171. if (resp.data.RespCode == 401) {
  172. loginAgain = true;
  173. }
  174. });
  175. // token未超时,直接返回
  176. if (!loginAgain) {
  177. return response;
  178. }
  179. // token超时时,调用接口重新登录
  180. if (uni.getStorageSync('isCall') != 1) {
  181. // 防止页面并发调用登录接口
  182. uni.setStorageSync('isCall', 1);
  183. uni.setStorageSync('data_expiration', 0);
  184. // 获取登录失败轮询次数,默认5次
  185. let retry = getApp().globalData.retryNum;
  186. while (retry > 0) {
  187. await useSmallProgramLogin(_app).then((resp: any) => {
  188. if (resp.data.RespCode != '10000') {
  189. // 登录失败,需轮询,次数减一
  190. retry--;
  191. } else {
  192. // 登录成功
  193. retry = 0;
  194. }
  195. });
  196. if (retry != 0) {
  197. // 需要重试时,先休眠300毫秒
  198. await sleep(300);
  199. }
  200. }
  201. }
  202. // 接口调用重试次数,默认判断5次,每次间隔500毫秒
  203. let retry = getApp().globalData.retryNum;
  204. while (retry > 0) {
  205. if (uni.getStorageSync('isCall') != 1) {
  206. // 如果已经重新登录成功,返回重新请求接口结果
  207. return httpGet(url, data, options);
  208. } else {
  209. // 还未登录成功,休眠500毫秒再判断
  210. await sleep(500);
  211. retry--;
  212. }
  213. }
  214. // 重试5次后,再次重新发起请求
  215. return httpGet(url, data, options);
  216. };
  217. // 新增 httpGet 基础方法
  218. const httpGet = (url: string, data: any, options: any = {}) => {
  219. let showLoading = true;
  220. if (options != undefined && options.showLoading != undefined) {
  221. showLoading = options.showLoading;
  222. }
  223. if (showLoading) {
  224. common.showLoading();
  225. }
  226. let header = {
  227. 'content-type': 'application/json',
  228. token: getApp().globalData.token || uni.getStorageSync('token'),
  229. 'call-appId': uni.getStorageSync('frontEndConfig').fixedAppjsGlobalData.appId,
  230. };
  231. if (options) {
  232. Object.keys(options).forEach((key) => {
  233. if (key != 'showLoading') {
  234. header[key] = options[key];
  235. }
  236. });
  237. }
  238. return new Promise((resolve, reject) => {
  239. uni.request({
  240. url: url,
  241. data: data,
  242. method: 'GET',
  243. header: header,
  244. success(res) {
  245. if (showLoading) {
  246. common.hideLoading();
  247. }
  248. if (options && options.construction) {
  249. resolve({ data: { Data: res.data, RespCode: 10000 } });
  250. } else {
  251. resolve(res);
  252. }
  253. },
  254. fail(error) {
  255. if (showLoading) {
  256. common.hideLoading();
  257. }
  258. reject(error);
  259. common.showToast(`连接超时,请重试`);
  260. },
  261. });
  262. });
  263. };
  264. //模拟线程休眠,需配合 async和await使用
  265. const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
  266. export default {
  267. doPost,
  268. doGet,
  269. };