request.js 16 KB

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