request.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. import Vue from 'vue';
  2. import { popAll } from './formId.js';
  3. import apiUrl from './apiUrl.js';
  4. // import deepMerge from "./deepMerge";
  5. const request = async function (args) {
  6. const header = {
  7. 'X-App-Platform': (args.header && args.header['X-App-Platform']) ? args.header['X-App-Platform'] : Vue.prototype.$platform,
  8. 'X-Form-Id-List': JSON.stringify(popAll()),
  9. 'X-Requested-With': (args.header && args.header['X-Requested-With']) ? args.header['X-Requested-With'] : 'XMLHttpRequest',
  10. 'X-App-Version': Vue.prototype.$appVersion,
  11. 'content-type': 'application/x-www-form-urlencoded',
  12. // #ifdef MP-TOUTIAO
  13. 'X-tt-platform': Vue.prototype.$store.state.gConfig.systemInfo.appName
  14. // #endif
  15. };
  16. await Vue.prototype.$store.dispatch('user/loadAccessTokenFormCache');
  17. if (Vue.prototype.$store.state.user && Vue.prototype.$store.state.user.accessToken) {
  18. header['X-Access-Token'] = Vue.prototype.$store.state.user.accessToken;
  19. }
  20. if (Vue.prototype.$store.state.user && Vue.prototype.$store.state.user.tempParentId !== 0) {
  21. header['X-User-Id'] = Vue.prototype.$store.state.user.tempParentId + '';
  22. }
  23. //多商户Token
  24. let obj = {};
  25. args.url.replace(/([^=&]+)=([^&]*)/g, function (m, key, value) {
  26. obj[decodeURIComponent(key)] = decodeURIComponent(value);
  27. });
  28. if (Vue.prototype.$utils.objectValues(apiUrl.mch).indexOf(obj.r) !== -1) {
  29. const mch_storage = uni.getStorageSync('MCH2019');
  30. header['Mch-Access-Token'] = mch_storage.token;
  31. }
  32. const [error, response] = await uni.request({
  33. url: args.url,
  34. method: args.method || 'get',
  35. data: args.data,
  36. header: header,
  37. });
  38. if (error) {
  39. let msg = {
  40. code: 400,
  41. msg: error.errMsg,
  42. data: error,
  43. };
  44. alertError(msg);
  45. return Promise.reject(msg);
  46. } else {
  47. return distinguishStatusCode(response);
  48. }
  49. };
  50. // #ifndef MP-ALIPAY
  51. const reloadPage = function () {
  52. let pages = getCurrentPages();
  53. let page = pages[pages.length - 1];
  54. let options = page.options || {};
  55. let route = page.route || '';
  56. if (route.indexOf('/') !== 0) {
  57. route = '/' + route;
  58. }
  59. let query = '';
  60. for (let k in options) {
  61. query = query + `${k}=${options[k]}&`;
  62. }
  63. uni.redirectTo({
  64. url: route + (query ? `?${query}` : ``),
  65. });
  66. };
  67. // #endif
  68. const alertError = function (error) {
  69. let confirmText = '刷新页面';
  70. // #ifdef MP-ALIPAY
  71. confirmText = '确认';
  72. // #endif
  73. uni.showModal({
  74. title: '网络错误',
  75. content: '网络开了小差,请刷新重试下哦~',
  76. cancelText: '复制错误',
  77. confirmText: confirmText,
  78. success: (e) => {
  79. if (e.cancel) {
  80. let data = `code: ${error.code}, \r\nmsg: ${error.msg}, \r\ndetail: `
  81. + (error.data ? (typeof error.data === 'string' ? error.data : JSON.stringify(error.data)) : null);
  82. uni.setClipboardData({
  83. data: data
  84. });
  85. }
  86. if (e.confirm) {
  87. // #ifndef MP-ALIPAY
  88. reloadPage();
  89. // #endif
  90. }
  91. },
  92. });
  93. };
  94. const distinguishDataCode = function (response) {
  95. if (response.data) {
  96. let {msg, code} = response.data;
  97. if (code >= 400) {
  98. alertError({
  99. code: code,
  100. msg: msg,
  101. data: response.data.error || (response.data.data || msg),
  102. });
  103. return Promise.reject(msg);
  104. } else if (code === -1) {
  105. Vue.prototype.$store.dispatch('user/logout');
  106. Vue.prototype.$store.dispatch('user/accessToken');
  107. return Promise.reject(msg);
  108. } else if (code === -2) {
  109. uni.redirectTo({
  110. url: '/pages/disabled/disabled?text=' + response.data.data.text
  111. });
  112. } else if (code === -3) {
  113. uni.redirectTo({
  114. url: '/plugins/mch/mch/login/login'
  115. });
  116. return Promise.reject(msg);
  117. } else {
  118. return Promise.resolve(response.data);
  119. }
  120. } else {
  121. return Promise.reject({
  122. code: 200,
  123. msg: '数据不存在',
  124. data: response,
  125. });
  126. }
  127. };
  128. const distinguishStatusCode = function (response) {
  129. let msg = {
  130. code: 500,
  131. msg: '服务器内部错误',
  132. data: response,
  133. };
  134. switch (response.statusCode) {
  135. case 200:
  136. return distinguishDataCode(response);
  137. case 404:
  138. msg = {
  139. code: 404,
  140. msg: '资源获取不到',
  141. data: response,
  142. };
  143. break;
  144. case 500:
  145. msg = {
  146. code: 500,
  147. msg: '服务器内部错误',
  148. data: response,
  149. };
  150. break;
  151. case 503:
  152. msg = {
  153. code: 503,
  154. msg: '服务不可用',
  155. data: response,
  156. };
  157. break;
  158. case 504:
  159. msg = {
  160. code: 504,
  161. msg: '网关超时',
  162. data: response,
  163. };
  164. break;
  165. case 400:
  166. msg = {
  167. code: 400,
  168. msg: '服务器不理解请求的语法',
  169. data: response,
  170. };
  171. break;
  172. case 403:
  173. msg = {
  174. code: 403,
  175. msg: '服务器拒绝请求',
  176. data: response,
  177. };
  178. break;
  179. case 405:
  180. msg = {
  181. code: 405,
  182. msg: '方法禁用',
  183. data: response,
  184. };
  185. break;
  186. case 406:
  187. msg = {
  188. code: 406,
  189. msg: '无法使用请求的内容特性响应请求的网页',
  190. data: response,
  191. };
  192. break;
  193. case 407:
  194. msg = {
  195. code: 407,
  196. msg: '需要代理授权',
  197. data: response,
  198. };
  199. break;
  200. case 408:
  201. msg = {
  202. code: 408,
  203. msg: '请求超时',
  204. data: response,
  205. };
  206. break;
  207. case 409:
  208. msg = {
  209. code: 409,
  210. msg: '冲突',
  211. data: response,
  212. };
  213. break;
  214. case 410:
  215. msg = {
  216. code: 410,
  217. msg: '已删除',
  218. data: response,
  219. };
  220. break;
  221. case 411:
  222. msg = {
  223. code: 411,
  224. msg: '需要有效长度',
  225. data: response,
  226. };
  227. break;
  228. case 412:
  229. msg = {
  230. code: 412,
  231. msg: '服务器未满足请求者在请求中设置的其中一个前提条件',
  232. data: response,
  233. };
  234. break;
  235. case 413:
  236. msg = {
  237. code: 413,
  238. msg: '请求实体过大',
  239. data: response,
  240. };
  241. break;
  242. case 414:
  243. msg = {
  244. code: 414,
  245. msg: '求情URI过长',
  246. data: response,
  247. };
  248. break;
  249. case 415:
  250. msg = {
  251. code: 415,
  252. msg: '不支持的媒体类型',
  253. data: response,
  254. };
  255. break;
  256. case 416:
  257. msg = {
  258. code: 416,
  259. msg: '请求范围不符合要求',
  260. data: response,
  261. };
  262. break;
  263. case 417:
  264. msg = {
  265. code: 417,
  266. msg: '未满足期望值',
  267. data: response,
  268. };
  269. break;
  270. default:
  271. break;
  272. }
  273. alertError(msg);
  274. return Promise.reject(msg);
  275. };
  276. export default request;
  277. //
  278. //
  279. // class Request {
  280. // // 设置全局默认配置
  281. // setConfig(customConfig) {
  282. // // 深度合并对象,否则会造成对象深层属性丢失
  283. // this.config = deepMerge(this.config, customConfig);
  284. // }
  285. //
  286. // request(options = {}) {
  287. // // 检查请求拦截
  288. // if (this.interceptor.request && typeof this.interceptor.request === 'function') {
  289. // let tmpConfig = {};
  290. // let interceptorRequest = this.interceptor.request(options);
  291. // if (interceptorRequest === false) {
  292. // // 返回一个处于pending状态中的Promise,来取消原promise,避免进入then()回调
  293. // return new Promise(()=>{});
  294. // }
  295. // this.options = interceptorRequest;
  296. // }
  297. // options.dataType = options.dataType || this.config.dataType;
  298. // options.responseType = options.responseType || this.config.responseType;
  299. // options.url = options.url || '';
  300. // options.params = options.params || {};
  301. // options.header = Object.assign(this.config.header, options.header);
  302. // options.method = options.method || this.config.method;
  303. //
  304. // return new Promise((resolve, reject) => {
  305. // options.complete = (response) => {
  306. // // 请求返回后,隐藏loading(如果请求返回快的话,可能会没有loading)
  307. // uni.hideLoading();
  308. // // 清除定时器,如果请求回来了,就无需loading
  309. // clearTimeout(this.config.timer);
  310. // this.config.timer = null;
  311. // if (this.config.originalData) {
  312. // // 判断是否存在拦截器
  313. // if (this.interceptor.response && typeof this.interceptor.response === 'function') {
  314. // let resInterceptors = this.interceptor.response(response);
  315. // // 如果拦截器不返回false,就将拦截器返回的内容给this.$u.post的then回调
  316. // if (resInterceptors !== false) {
  317. // resolve(resInterceptors);
  318. // } else {
  319. // // 如果拦截器返回false,意味着拦截器定义者认为返回有问题,直接接入catch回调
  320. // reject(response);
  321. // }
  322. // } else {
  323. // // 如果要求返回原始数据,就算没有拦截器,也返回最原始的数据
  324. // resolve(response);
  325. // }
  326. // } else {
  327. // if (response.statusCode === 200) {
  328. // if (this.interceptor.response && typeof this.interceptor.response === 'function') {
  329. // let resInterceptors = this.interceptor.response(response.data);
  330. // if (resInterceptors !== false) {
  331. // resolve(resInterceptors);
  332. // } else {
  333. // reject(response.data);
  334. // }
  335. // } else {
  336. // // 如果不是返回原始数据(originalData=false),且没有拦截器的情况下,返回纯数据给then回调
  337. // resolve(response.data);
  338. // }
  339. // } else {
  340. // // 不返回原始数据的情况下,服务器状态码不为200,modal弹框提示
  341. // if(response.errMsg) {
  342. // uni.showModal({
  343. // title: response.errMsg
  344. // });
  345. // }
  346. // reject(response)
  347. // }
  348. // }
  349. // }
  350. //
  351. // // 判断用户传递的URL是否/开头,如果不是,加上/,这里使用了uView的test.js验证库的url()方法
  352. // options.url = Vue.prototype.$validation.url(options.url) ? options.url : (this.config.baseUrl + (options.url.indexOf('/') === 0 ?
  353. // options.url : '/' + options.url));
  354. // // 是否显示loading
  355. // // 加一个是否已有timer定时器的判断,否则有两个同时请求的时候,后者会清除前者的定时器id
  356. // // 而没有清除前者的定时器,导致前者超时,一直显示loading
  357. // if(this.config.showLoading && !this.config.timer) {
  358. // this.config.timer = setTimeout(() => {
  359. // uni.showLoading({
  360. // title: this.config.loadingText,
  361. // mask: this.config.loadingMask
  362. // })
  363. // this.config.timer = null;
  364. // }, this.config.loadingTime);
  365. // }
  366. // uni.request(options);
  367. // })
  368. // }
  369. //
  370. // constructor() {
  371. // this.config = {
  372. // baseUrl: '', // 请求的根域名
  373. // // 默认的请求头
  374. // header: {
  375. // 'X-App-Platform': Vue.prototype.$platform,
  376. // 'X-Form-Id-List': JSON.stringify(popAll()),
  377. // 'X-Requested-With': 'XMLHttpRequest',
  378. // 'X-App-Version': Vue.prototype.$appVersion,
  379. // 'content-type': 'application/x-www-form-urlencoded'
  380. // },
  381. // method: 'POST',
  382. // // 设置为json,返回后uni.request会对数据进行一次JSON.parse
  383. // dataType: 'json',
  384. // // 此参数无需处理,因为5+和支付宝小程序不支持,默认为text即可
  385. // responseType: 'text',
  386. // showLoading: true, // 是否显示请求中的loading
  387. // loadingText: '请求中...',
  388. // loadingTime: 800, // 在此时间内,请求还没回来的话,就显示加载中动画,单位ms
  389. // timer: null, // 定时器
  390. // originalData: false, // 是否在拦截器中返回服务端的原始数据,见文档说明
  391. // loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透
  392. // }
  393. //
  394. // // 拦截器
  395. // this.interceptor = {
  396. // // 请求前的拦截
  397. // request: function(config) {
  398. // // //多商户Token
  399. // // let obj = {};
  400. // // config.url.replace(/([^=&]+)=([^&]*)/g, function (m, key, value) {
  401. // // obj[decodeURIComponent(key)] = decodeURIComponent(value);
  402. // // });
  403. // // if (Vue.prototype.$utils.objectValues(apiUrl.mch).indexOf(obj.r) !== -1) {
  404. // // const mch_storage = uni.getStorageSync('MCH2019');
  405. // // config.header['Mch-Access-Token'] = mch_storage.token;
  406. // // }
  407. // return config;
  408. // },
  409. // // 请求后的拦截
  410. // response: null
  411. // }
  412. //
  413. // }
  414. // }
  415. //
  416. // export {
  417. // Request
  418. // }