耀实惠小程序
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.

290 lines
7.5 KiB

  1. import {
  2. API_URL
  3. } from '@/env'
  4. export default class Request {
  5. config = {
  6. baseUrl: API_URL,
  7. header: {
  8. 'content-type': 'application/x-www-form-urlencoded',
  9. 'platform': uni.getStorageSync('platform'),
  10. },
  11. method: 'GET',
  12. dataType: 'json',
  13. // #ifndef MP-ALIPAY || APP-PLUS
  14. responseType: 'text',
  15. // #endif
  16. custom: {},
  17. // #ifdef MP-ALIPAY
  18. timeout: 30000,
  19. // #endif
  20. // #ifdef APP-PLUS
  21. sslVerify: true
  22. // #endif
  23. }
  24. static posUrl(url) { /* 判断url是否为绝对路径 */
  25. return /(http|https):\/\/([\w.]+\/?)\S*/.test(url)
  26. }
  27. static addQueryString(params) {
  28. let paramsData = ''
  29. Object.keys(params).forEach(function(key) {
  30. paramsData += key + '=' + encodeURIComponent(params[key]) + '&'
  31. })
  32. return paramsData.substring(0, paramsData.length - 1)
  33. }
  34. /**
  35. * @property {Function} request 请求拦截器
  36. * @property {Function} response 响应拦截器
  37. * @type {{request: Request.interceptor.request, response: Request.interceptor.response}}
  38. */
  39. interceptor = {
  40. /**
  41. * @param {Request~requestCallback} cb - 请求之前拦截,接收一个函数config, cancel=> {return config}第一个参数为全局config,第二个参数为函数调用则取消本次请求
  42. */
  43. request: (cb) => {
  44. if (cb) {
  45. this.requestBeforeFun = cb
  46. }
  47. },
  48. /**
  49. * @param {Request~responseCallback} cb 响应拦截器对响应数据做点什么
  50. * @param {Request~responseErrCallback} ecb 响应拦截器对响应错误做点什么
  51. */
  52. response: (cb, ecb) => {
  53. if (cb && ecb) {
  54. this.requestComFun = cb
  55. this.requestComFail = ecb
  56. }
  57. }
  58. }
  59. requestBeforeFun(config) {
  60. return config
  61. }
  62. requestComFun(response) {
  63. return response
  64. }
  65. requestComFail(response) {
  66. return response
  67. }
  68. /**
  69. * 自定义验证器如果返回true 则进入响应拦截器的响应成功函数(resolve)否则进入响应拦截器的响应错误函数(reject)
  70. * @param { Number } statusCode - 请求响应体statusCode只读
  71. * @return { Boolean } 如果为true, resolve, 否则 reject
  72. */
  73. validateStatus(statusCode) {
  74. return statusCode === 200
  75. }
  76. /**
  77. * @Function
  78. * @param {Request~setConfigCallback} f - 设置全局默认配置
  79. */
  80. setConfig(f) {
  81. this.config = f(this.config)
  82. }
  83. /**
  84. * @Function
  85. * @param {Object} options - 请求配置项
  86. * @prop {String} options.url - 请求路径
  87. * @prop {Object} options.data - 请求参数
  88. * @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型
  89. * @prop {Object} [options.dataType = config.dataType] - 如果设为 json会尝试对返回的数据做一次 JSON.parse
  90. * @prop {Object} [options.header = config.header] - 请求header
  91. * @prop {Object} [options.method = config.method] - 请求方法
  92. * @returns {Promise<unknown>}
  93. */
  94. async request(options = {}) {
  95. options.baseUrl = this.config.baseUrl
  96. options.dataType = options.dataType || this.config.dataType
  97. // #ifndef MP-ALIPAY || APP-PLUS
  98. options.responseType = options.responseType || this.config.responseType
  99. // #endif
  100. // #ifdef MP-ALIPAY
  101. options.timeout = options.timeout || this.config.timeout
  102. // #endif
  103. options.url = options.url || ''
  104. options.data = options.data || {}
  105. options.params = options.params || {}
  106. options.header = options.header || this.config.header
  107. options.method = options.method || this.config.method
  108. options.custom = { ...this.config.custom,
  109. ...(options.custom || {})
  110. }
  111. // #ifdef APP-PLUS
  112. options.sslVerify = options.sslVerify === undefined ? this.config.sslVerify : options.sslVerify
  113. // #endif
  114. // uni.showToast({
  115. // icon: "loading",
  116. // image: "/static/imgs//logo/logo.gif"
  117. // })
  118. return new Promise((resolve, reject) => {
  119. let next = true
  120. let handleRe = {}
  121. options.complete = (response) => {
  122. response.config = handleRe
  123. if (this.validateStatus(response.statusCode)) { // 成功
  124. response = this.requestComFun(response)
  125. resolve(response.data)
  126. } else if (401 === response.statusCode) {
  127. // token 过期 直接跳登录页
  128. response = this.requestComFun(response)
  129. resolve(response.data)
  130. } else if (500 === response.statusCode) {
  131. resolve(response.data)
  132. }else if ( 901 === response.statusCode) {
  133. response = this.requestComFun(response)
  134. resolve(response.data)
  135. }else if (902 === response.statusCode) {
  136. response = this.requestComFun(response)
  137. resolve(response.data)
  138. }else if (903 === response.statusCode) {
  139. response = this.requestComFun(response)
  140. resolve(response.data)
  141. }else {
  142. response = this.requestComFail(response)
  143. reject(response)
  144. }
  145. }
  146. const cancel = (t = 'handle cancel', config = options) => {
  147. const err = {
  148. errMsg: t,
  149. config: config
  150. }
  151. reject(err)
  152. next = false
  153. }
  154. handleRe = { ...this.requestBeforeFun(options, cancel)
  155. }
  156. const _config = { ...handleRe
  157. }
  158. if (!next) return
  159. delete _config.custom
  160. let mergeUrl = Request.posUrl(_config.url) ? _config.url : (_config.baseUrl + _config.url)
  161. if (JSON.stringify(_config.params) !== '{}') {
  162. const paramsH = Request.addQueryString(_config.params);
  163. mergeUrl += mergeUrl.indexOf('?') === -1 ? `?${paramsH}` : `&${paramsH}`
  164. }
  165. _config.url = mergeUrl
  166. uni.request(_config)
  167. })
  168. }
  169. get(url, options = {}) {
  170. return this.request({
  171. url,
  172. method: 'GET',
  173. ...options
  174. })
  175. }
  176. post(url, data, options = {}) {
  177. return this.request({
  178. url,
  179. data,
  180. method: 'POST',
  181. ...options
  182. })
  183. }
  184. upload(url, {
  185. // #ifdef APP-PLUS
  186. files,
  187. // #endif
  188. // #ifdef MP-ALIPAY
  189. fileType,
  190. // #endif
  191. filePath,
  192. name,
  193. header,
  194. formData,
  195. custom
  196. }) {
  197. return new Promise((resolve, reject) => {
  198. let next = true
  199. let handleRe = {}
  200. const globalHeader = { ...this.config.header
  201. }
  202. delete globalHeader['content-type']
  203. const pubConfig = {
  204. baseUrl: this.config.baseUrl,
  205. url,
  206. // #ifdef APP-PLUS
  207. files,
  208. // #endif
  209. // #ifdef MP-ALIPAY
  210. fileType,
  211. // #endif
  212. filePath,
  213. method: 'UPLOAD',
  214. name,
  215. header: header || globalHeader,
  216. formData,
  217. custom: { ...this.config.custom,
  218. ...(custom || {})
  219. },
  220. complete: (response) => {
  221. response.config = handleRe
  222. if (response.statusCode === 200) { // 成功
  223. response = this.requestComFun(response)
  224. resolve(response)
  225. } else {
  226. response = this.requestComFail(response)
  227. reject(response)
  228. }
  229. }
  230. }
  231. const cancel = (t = 'handle cancel', config = pubConfig) => {
  232. const err = {
  233. errMsg: t,
  234. config: config
  235. }
  236. reject(err)
  237. next = false
  238. }
  239. handleRe = { ...this.requestBeforeFun(pubConfig, cancel)
  240. }
  241. const _config = { ...handleRe
  242. }
  243. if (!next) return
  244. delete _config.custom
  245. _config.url = Request.posUrl(_config.url) ? _config.url : (_config.baseUrl + _config.url)
  246. uni.uploadFile(_config)
  247. })
  248. }
  249. }
  250. /**
  251. * setConfig回调
  252. * @return {Object} - 返回操作后的config
  253. * @callback Request~setConfigCallback
  254. * @param {Object} config - 全局默认config
  255. */
  256. /**
  257. * 请求拦截器回调
  258. * @return {Object} - 返回操作后的config
  259. * @callback Request~requestCallback
  260. * @param {Object} config - 全局config
  261. * @param {Function} [cancel] - 取消请求钩子调用会取消本次请求
  262. */
  263. /**
  264. * 响应拦截器回调
  265. * @return {Object} - 返回操作后的response
  266. * @callback Request~responseCallback
  267. * @param {Object} response - 请求结果 response
  268. */
  269. /**
  270. * 响应错误拦截器回调
  271. * @return {Object} - 返回操作后的response
  272. * @callback Request~responseErrCallback
  273. * @param {Object} response - 请求结果 response
  274. */