MES手机端
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

request.config.js 6.8 KiB

vor 3 Wochen
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /**
  2. * 通用uni-app网络请求
  3. * 基于 Promise 对象实现更简单的 request 使用方式,支持请求和响应拦截
  4. */
  5. import indexConfig from '@/config/index.config.js'
  6. import store from '@/store/index.js'
  7. export default {
  8. config: {
  9. baseUrl: indexConfig.baseUrl,
  10. header: {
  11. 'Content-Type': 'application/json;charset=UTF-8',
  12. 'Content-Type': 'application/x-www-form-urlencoded'
  13. },
  14. data: {},
  15. method: "GET",
  16. dataType: "json",
  17. /* 如设为json,会对返回的数据做一次 JSON.parse */
  18. responseType: "text",
  19. success() {},
  20. fail() {},
  21. complete() {}
  22. },
  23. interceptor: {
  24. request: null,
  25. response: null
  26. },
  27. request(options) {
  28. if (!options) {
  29. options = {}
  30. }
  31. options.baseUrl = options.baseUrl || this.config.baseUrl
  32. options.dataType = options.dataType || this.config.dataType
  33. options.url = options.baseUrl + options.url
  34. options.data = options.data || {}
  35. options.method = options.method || this.config.method
  36. const token = uni.getStorageSync('token')
  37. // token处理
  38. if (token) {
  39. // 可以在此通过vm引用vuex中的变量,具体值在vm.$store.state中
  40. let _token = {
  41. 'token': token
  42. }
  43. options.header = Object.assign({}, options.header, _token)
  44. }
  45. return new Promise((resolve, reject) => {
  46. let _config = null
  47. options.complete = (response) => {
  48. let statusCode = response.statusCode
  49. response.config = _config
  50. if (this.interceptor.response) {
  51. let newResponse = this.interceptor.response(response)
  52. if (newResponse) {
  53. response = newResponse
  54. }
  55. }
  56. // 统一的响应日志记录
  57. // _reslog(response)
  58. // 返回结果
  59. if (statusCode === 200) { //成功
  60. // 处理响应结果
  61. if (response.data) {
  62. let serviceCode = response.data.code
  63. if (serviceCode !== 200) {
  64. handleServiceError(serviceCode, response.data.message)
  65. reject(response.data)
  66. } else {
  67. resolve(response.data.queryData);
  68. }
  69. }
  70. } else {
  71. reject(response)
  72. }
  73. }
  74. _config = Object.assign({}, this.config, options)
  75. _config.requestId = new Date().getTime()
  76. if (this.interceptor.request) {
  77. this.interceptor.request(_config)
  78. }
  79. // 统一的请求日志记录
  80. _reqlog(_config)
  81. uni.request(_config);
  82. });
  83. },
  84. get(url, data, options) {
  85. if (!options) {
  86. options = {}
  87. }
  88. options.url = url
  89. options.data = data
  90. options.method = 'GET'
  91. options.header = {
  92. 'Content-Type': 'application/x-www-form-urlencoded'
  93. }
  94. return this.request(options)
  95. },
  96. post(url, data, options) {
  97. if (!options) {
  98. options = {}
  99. }
  100. options.url = url
  101. options.data = data
  102. options.method = 'POST'
  103. options.header = {
  104. 'Content-Type': 'application/json;charset=UTF-8',
  105. }
  106. return this.request(options)
  107. },
  108. put(url, data, options) {
  109. if (!options) {
  110. options = {}
  111. }
  112. options.url = url
  113. options.data = data
  114. options.method = 'PUT'
  115. if (!options.header) {
  116. options.header = {
  117. 'Content-Type': 'application/json;charset=UTF-8',
  118. }
  119. }
  120. return this.request(options)
  121. },
  122. delete(url, data, options) {
  123. if (!options) {
  124. options = {}
  125. }
  126. options.url = url
  127. options.data = data
  128. options.method = 'DELETE'
  129. return this.request(options)
  130. }
  131. }
  132. /**
  133. * 请求接口日志记录
  134. */
  135. function _reqlog(req) {
  136. if (process.env.NODE_ENV === 'development') {
  137. console.log("【" + req.requestId + "】 地址:" + req.url)
  138. if (req.data) {
  139. console.log("【" + req.requestId + "】 请求参数:" + JSON.stringify(req.data))
  140. }
  141. }
  142. //TODO 调接口异步写入日志数据库
  143. }
  144. /**
  145. * 响应接口日志记录
  146. */
  147. function _reslog(res) {
  148. let _statusCode = res.statusCode;
  149. if (process.env.NODE_ENV === 'development') {
  150. console.log("【" + new Date().toTimeString() + "】 结果:" + JSON.stringify(res.data))
  151. }
  152. //TODO 除了接口服务错误外,其他日志调接口异步写入日志数据库
  153. switch (_statusCode) {
  154. case 200:
  155. break;
  156. case 401:
  157. break;
  158. case 404:
  159. break;
  160. default:
  161. break;
  162. }
  163. }
  164. // 这里的目的是会话过期(token过期),续期会话即可
  165. function handleRefreshToken() {
  166. // 判断是否有其他请求正在执行
  167. const isOnRefreshToken = uni.getStorageSync('isOnRefreshToken')
  168. if (isOnRefreshToken) {
  169. return true
  170. }
  171. // 没有从请求中读取到有效token
  172. const userInfo = uni.getStorageSync('userInfo')
  173. // 如果userInfo存在,那么直接续期token即可,刷新token也相当于进行了一次登录信息刷新
  174. if (userInfo) {
  175. // 正在刷新,记录一个状态,避免多次请求
  176. uni.setStorageSync('isOnRefreshToken', true)
  177. uni.showLoading()
  178. uni.request({
  179. url: indexConfig.baseUrl + '/user/refresh/token',
  180. data: {
  181. userId: userInfo.id,
  182. device: 'wechat'
  183. },
  184. success(res) {
  185. let newToken = res.data.queryData.token
  186. let newUserInfo = res.data.queryData.userInfo
  187. let permissions = res.data.queryData.permissions
  188. let roles = res.data.queryData.roles
  189. uni.setStorageSync('userInfo', newUserInfo); //更新用户信息
  190. uni.setStorageSync('roles', roles);
  191. uni.setStorageSync('permissions', permissions);
  192. store.dispatch('refreshToken', newToken).then(() => {
  193. uni.hideLoading()
  194. uni.showToast({
  195. title: '已为您续期会话,3s后刷新',
  196. icon: 'none',
  197. duration: 3000,
  198. })
  199. setTimeout(() => {
  200. // 获取当前页面
  201. // 获取当前页面的实例对象
  202. const currentPage = getCurrentPages()[getCurrentPages().length - 1];
  203. // 获取当前页面的路径
  204. const currentPath = '/' + currentPage.route;
  205. // relaunch当前界面,相当于刷新
  206. uni.redirectTo({
  207. url: currentPath
  208. })
  209. }, 3000)
  210. })
  211. },
  212. fail(e) {
  213. uni.hideLoading()
  214. console.log(e);
  215. },
  216. complete() {
  217. // 无论成功与否都要删除这个状态,防止影响其他异常返回结果处理
  218. uni.removeStorageSync('isOnRefreshToken')
  219. }
  220. })
  221. return true
  222. }
  223. return false
  224. }
  225. function handleServiceError(code, message) {
  226. if (code === -2 || code === -3 || code === -4 || code === -5) {
  227. if (!handleRefreshToken()) {
  228. store.dispatch('clear').then(() => {
  229. // 跳转在路由钩子中统一控制
  230. uni.showToast({
  231. title: '登录状态异常,请重新登录',
  232. icon: 'none',
  233. duration: 2000
  234. })
  235. })
  236. }
  237. } else if (code === -1) {
  238. if (!handleRefreshToken()) {
  239. store.dispatch('clear').then(() => {
  240. // 跳转在路由钩子中统一控制
  241. uni.showToast({
  242. title: '请您在登录后使用',
  243. icon: 'none',
  244. duration: 2000
  245. })
  246. })
  247. }
  248. } else if (code === 500) {
  249. uni.showModal({
  250. title: '提示',
  251. content: '服务器错误,系统异常,请稍后重试',
  252. showCancel: false,
  253. confirmText: 'Error',
  254. success(res) {
  255. if (res.confirm) {
  256. // 重定向到登录页面
  257. uni.showToast({
  258. title: '系统错误',
  259. icon: 'none'
  260. })
  261. }
  262. }
  263. })
  264. }
  265. }