You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

191 lines
6.0 KiB

  1. import deepMerge from "../function/deepMerge";
  2. import validate from "../function/test";
  3. var token = uni.getStorageSync('weapp_session_login_data');
  4. class Request {
  5. // 设置全局默认配置
  6. setConfig(customConfig) {
  7. // 深度合并对象,否则会造成对象深层属性丢失
  8. this.config = deepMerge(this.config, customConfig);
  9. }
  10. // 主要请求部分
  11. request(options = {}) {
  12. // 检查请求拦截
  13. if (this.interceptor.request && typeof this.interceptor.request === 'function') {
  14. let tmpConfig = {};
  15. let interceptorReuest = this.interceptor.request(options);
  16. if (interceptorReuest === false) {
  17. return false;
  18. }
  19. this.options = interceptorReuest;
  20. }
  21. options.dataType = options.dataType || this.config.dataType;
  22. options.responseType = options.responseType || this.config.responseType;
  23. options.url = options.url || '';
  24. options.params = options.params || {};
  25. options.header = Object.assign(this.config.header, options.header);
  26. options.method = options.method || this.config.method;
  27. return new Promise((resolve, reject) => {
  28. options.complete = (response) => {
  29. // 请求返回后,隐藏loading(如果请求返回快的话,可能会没有loading)
  30. uni.hideLoading();
  31. // 清除定时器,如果请求回来了,就无需loading
  32. clearTimeout(this.config.timer);
  33. this.timer = null;
  34. // 判断用户对拦截返回数据的要求,如果originalData为true,返回所有的数据(response)到拦截器,否则只返回response.data
  35. if(this.config.originalData) {
  36. // 判断是否存在拦截器
  37. if (this.interceptor.response && typeof this.interceptor.response === 'function') {
  38. let resInterceptors = this.interceptor.response(response);
  39. // 如果拦截器不返回false,就将拦截器返回的内容给this.$u.post的then回调
  40. if (resInterceptors !== false) {
  41. resolve(resInterceptors);
  42. } else {
  43. // 如果拦截器返回false,意味着拦截器定义者认为返回有问题,直接接入catch回调
  44. reject(response);
  45. }
  46. } else {
  47. // 如果要求返回原始数据,就算没有拦截器,也返回最原始的数据
  48. resolve(response);
  49. }
  50. } else {
  51. if (response.statusCode == 200) {
  52. if (this.interceptor.response && typeof this.interceptor.response === 'function') {
  53. let resInterceptors = this.interceptor.response(response.data);
  54. if (resInterceptors !== false) {
  55. resolve(resInterceptors);
  56. } else {
  57. reject(response.data);
  58. }
  59. } else {
  60. // 如果不是返回原始数据(originalData=false),且没有拦截器的情况下,返回纯数据给then回调
  61. resolve(response.data);
  62. }
  63. } else if(response.statusCode == 401){
  64. uni.showToast({
  65. title: response.data.msg,
  66. icon:'none',
  67. duration: 2000
  68. });
  69. uni.clearStorageSync();
  70. uni.reLaunch({
  71. url: '/pages/index/guide'
  72. });
  73. reject(response)
  74. }else{
  75. // 不返回原始数据的情况下,服务器状态码不为200,modal弹框提示
  76. if(response.errMsg) {
  77. uni.showModal({
  78. title: response.errMsg,
  79. cancelColor:"#999999",
  80. });
  81. }
  82. reject(response)
  83. }
  84. }
  85. }
  86. // 判断用户传递的URL是否/开头,如果不是,加上/,这里使用了uView的test.js验证库的url()方法
  87. options.url = validate.url(options.url) ? options.url : (this.config.baseUrl + (options.url.indexOf('/') == 0 ?
  88. options.url : '/' + options.url));
  89. // 是否显示loading
  90. // 加一个是否已有timer定时器的判断,否则有两个同时请求的时候,后者会清除前者的定时器id
  91. // 而没有清除前者的定时器,导致前者超时,一直显示loading
  92. if(this.config.showLoading && !this.config.timer) {
  93. this.config.timer = setTimeout(() => {
  94. uni.showLoading({
  95. title: this.config.loadingText,
  96. mask: this.config.loadingMask
  97. })
  98. this.config.timer = null;
  99. }, this.config.loadingTime);
  100. }
  101. uni.request(options);
  102. })
  103. }
  104. constructor() {
  105. this.config = {
  106. baseUrl: '', // 请求的根域名
  107. // 默认的请求头
  108. header: {},
  109. method: 'POST',
  110. // 设置为json,返回后uni.request会对数据进行一次JSON.parse
  111. dataType: 'json',
  112. // 此参数无需处理,因为5+和支付宝小程序不支持,默认为text即可
  113. responseType: 'text',
  114. showLoading: true, // 是否显示请求中的loading
  115. loadingText: '请求中...',
  116. loadingTime: 800, // 在此时间内,请求还没回来的话,就显示加载中动画,单位ms
  117. timer: null, // 定时器
  118. originalData: false, // 是否在拦截器中返回服务端的原始数据,见文档说明
  119. loadingMask: true, // 展示loading的时候,是否给一个透明的蒙层,防止触摸穿透
  120. }
  121. // 拦截器
  122. this.interceptor = {
  123. // 请求前的拦截
  124. request: null,
  125. // 请求后的拦截
  126. response: null
  127. }
  128. // get请求
  129. this.get = (url, data = {}, header = {
  130. 'Authorization': 'Bearer '+token.token,
  131. 'content-type': 'application/json',
  132. // application/x-www-form-urlencoded
  133. }) => {
  134. return this.request({
  135. method: 'GET',
  136. url,
  137. header,
  138. data
  139. })
  140. }
  141. // post请求
  142. this.post = (url, data = {}, header = {
  143. 'Authorization': 'Bearer '+token.token,
  144. 'content-type': 'application/json'
  145. }) => {
  146. return this.request({
  147. url,
  148. method: 'POST',
  149. header,
  150. data
  151. })
  152. }
  153. // put请求,不支持支付宝小程序(HX2.6.15)
  154. this.put = (url, data = {}, header = {
  155. 'Authorization': 'Bearer '+token.token,
  156. 'content-type': 'application/json'
  157. }) => {
  158. return this.request({
  159. url,
  160. method: 'PUT',
  161. header,
  162. data
  163. })
  164. }
  165. // delete请求,不支持支付宝和头条小程序(HX2.6.15)
  166. this.delete = (url, data = {}, header = {
  167. 'Authorization': 'Bearer '+token.token,
  168. 'content-type': 'application/json'
  169. }) => {
  170. return this.request({
  171. url,
  172. method: 'DELETE',
  173. header,
  174. data
  175. })
  176. }
  177. }
  178. }
  179. export default new Request