request.js 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import Taro from '@tarojs/taro'
  2. import * as apis from '@/constants/api'
  3. // import login from '@/utils/login'
  4. import store from '@/store'
  5. import rtLog from './rtLog'
  6. const CODE_SUCCESS = 1000
  7. const CODE_UNLOGIN = 1001
  8. const CODE_AUTH_EXPIRED = 1002
  9. const accountInfo = wx.getAccountInfoSync();
  10. const appId = accountInfo.miniProgram.appId
  11. const { dispatch } = store
  12. const updateSpin = spinning => dispatch({ type: 'SET_SPINNING', payload: spinning })
  13. export { apis };
  14. export const getStorage = function (key) {
  15. return Taro.getStorage({ key }).then(res => res.data).catch(() => '')
  16. }
  17. export const setStorage = function (key, data) {
  18. return Taro.setStorage({ key, data })
  19. }
  20. /**
  21. * 简易封装网络请求
  22. * // NOTE 需要注意 RN 不支持 *StorageSync,此处用 async/await 解决
  23. * @param {*} options
  24. */
  25. export const fetch = async (options) => {
  26. const opts = optionBuilder(options)
  27. const { spin } = opts[1]
  28. if (spin) {
  29. updateSpin(true)
  30. }
  31. return Taro.request(opts[0])
  32. .then((res) => {
  33. if (spin) {
  34. updateSpin(false)
  35. }
  36. return reqSuccess(res, opts)
  37. })
  38. .catch((err) => {
  39. if (spin) {
  40. updateSpin(false)
  41. }
  42. return reqFail(err, opts)
  43. })
  44. }
  45. export const uploadFiles = async (files) => {
  46. const uploads = []
  47. const token = await getStorage('token')
  48. const authHeader = token ? { 'authorization': `Bearer ${token}` } : {}
  49. for (var i = 0; i < files.length; i++) {
  50. uploads[i] = new Promise((resolve, reject) => {
  51. wx.uploadFile({
  52. url: apis.API_UPLOAD_IMAGE,
  53. filePath: files[i],
  54. header: {
  55. ...authHeader,
  56. 'appId': appId,
  57. 'x-action': 'miniapp'
  58. },
  59. name: 'file',
  60. success: function (res) {
  61. // debugger
  62. const _data = JSON.parse(res.data)
  63. if (_data.code !== CODE_SUCCESS) {
  64. reject(new Error(_data.message))
  65. }
  66. resolve(_data.data)
  67. },
  68. fail(err) {
  69. reject(err)
  70. }
  71. })
  72. })
  73. }
  74. return Promise.all(uploads)
  75. }
  76. export function optionBuilder(options) {
  77. const { url, payload = {}, method = 'GET', showToast = true, autoLogin = true, header, spin = false } = options
  78. const showMessage = Object.prototype.hasOwnProperty.call(payload, 'showToast') ? payload.showToast : showToast
  79. const consultant = Taro.getStorageSync('consultantId') || ''
  80. const recommender = Taro.getStorageSync('recommender') || ''
  81. return [
  82. {
  83. url,
  84. method,
  85. data: payload,
  86. header: {
  87. 'content-type': 'application/json',
  88. 'authorization': `Bearer ${Taro.getStorageSync('token')}`,
  89. 'appId': appId,
  90. 'x-action': 'miniapp',
  91. 'x-version': Version,
  92. 'x-consultant': consultant,
  93. 'x-recommender': recommender,
  94. ...header || {},
  95. }
  96. },
  97. {
  98. showMessage,
  99. autoLogin,
  100. spin,
  101. }
  102. ]
  103. }
  104. export function reqSuccess(res, opts) {
  105. const [, settings] = opts || []
  106. const { showMessage, autoLogin = true } = settings || {}
  107. if (res.statusCode === 500) {
  108. Taro.showToast({
  109. title: "请检查网络",
  110. icon: 'none'
  111. })
  112. console.error(res)
  113. throw new Error('请检查网络')
  114. }
  115. const { data, code, message } = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
  116. if (code === CODE_SUCCESS) {
  117. return data
  118. } else {
  119. const isExpired = (code === CODE_AUTH_EXPIRED || code === CODE_UNLOGIN)
  120. const defaultMsg = isExpired ? '登录失效' : message
  121. if (isExpired && autoLogin) {
  122. // token失效,重新登录后,跳转到首页
  123. login({}, () => {
  124. Taro.switchTab({
  125. url: '/pages/project/index'
  126. })
  127. })
  128. } else {
  129. if (showMessage) {
  130. Taro.showToast({
  131. title: defaultMsg,
  132. icon: 'none'
  133. })
  134. }
  135. }
  136. if (showMessage) {
  137. Taro.showToast({
  138. title: message,
  139. icon: 'none'
  140. })
  141. }
  142. throw res.data
  143. }
  144. }
  145. export function reqFail(err, opts) {
  146. const [reqParams, settings] = opts || []
  147. const { showMessage } = settings || {}
  148. rtLog.error('[request]', "==================================")
  149. rtLog.error('[request]', err)
  150. rtLog.error('[request]', reqParams.url)
  151. rtLog.error('[request]', wx.getLaunchOptionsSync())
  152. rtLog.error('[request]', "==================================")
  153. let errMessage = `请求失败: ${err.errMsg}`
  154. if (err.errMsg) {
  155. errMessage = '请检查网络'
  156. }
  157. if (err.message) {
  158. console.error('请求失败', err.message)
  159. errMessage = err.message.indexOf('java') > -1 ? '服务内部错误' : err.message
  160. }
  161. if (showMessage) {
  162. Taro.showToast({
  163. title: errMessage,
  164. icon: 'none',
  165. duration: 3000
  166. })
  167. }
  168. throw new Error(errMessage)
  169. }