| 
									
										
										
										
											2022-06-02 17:59:57 +08:00
										 |  |  |  | import errorCode from '@/utils/request/errorCode' | 
					
						
							|  |  |  |  | import { refreshToken } from '@/api/auth' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 需要忽略的提示。忽略后,自动 Promise.reject('error')
 | 
					
						
							|  |  |  |  | const ignoreMsgs = [ | 
					
						
							|  |  |  |  |   '无效的刷新令牌', // 刷新令牌被删除时,不用提示
 | 
					
						
							|  |  |  |  |   '刷新令牌已过期' // 使用刷新令牌,刷新获取新的访问令牌时,结果因为过期失败,此时需要忽略。否则,会导致继续 401,无法跳转到登出界面
 | 
					
						
							|  |  |  |  | ] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 请求队列
 | 
					
						
							|  |  |  |  | let requestList = [] | 
					
						
							|  |  |  |  | // 是否正在刷新中
 | 
					
						
							|  |  |  |  | let isRefreshToken = false | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /** | 
					
						
							|  |  |  |  |  * 响应拦截 | 
					
						
							|  |  |  |  |  * @param {Object} http | 
					
						
							|  |  |  |  |  */ | 
					
						
							|  |  |  |  | module.exports = vm => { | 
					
						
							|  |  |  |  |   uni.$u.http.interceptors.response.use( | 
					
						
							|  |  |  |  |     async res => { | 
					
						
							|  |  |  |  |       const code = res.data.code || 0 | 
					
						
							|  |  |  |  |       const msg = res.data.msg || errorCode[code] || errorCode['default'] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       if (ignoreMsgs.indexOf(msg) !== -1) { | 
					
						
							|  |  |  |  |         // 如果是忽略的错误码,直接返回 msg 异常
 | 
					
						
							|  |  |  |  |         return Promise.reject(msg) | 
					
						
							|  |  |  |  |       } else if (code === 401) { | 
					
						
							|  |  |  |  |         // 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了
 | 
					
						
							|  |  |  |  |         if (!isRefreshToken) { | 
					
						
							|  |  |  |  |           isRefreshToken = true | 
					
						
							|  |  |  |  |           // 1. 如果获取不到刷新令牌,则只能执行登出操作
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:55:55 +00:00
										 |  |  |  |           if (!vm.$store.getters.refreshToken) { | 
					
						
							| 
									
										
										
										
											2022-06-02 17:59:57 +08:00
										 |  |  |  |             vm.$store.commit('CLEAR_LOGIN_INFO') | 
					
						
							|  |  |  |  |             return Promise.reject(res) | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  |           // 2. 进行刷新访问令牌
 | 
					
						
							|  |  |  |  |           try { | 
					
						
							| 
									
										
										
										
											2023-01-09 02:59:27 +00:00
										 |  |  |  |             let param = {} | 
					
						
							|  |  |  |  |             let refreshToken =  uni.getStorageSync('REFRESH_TOKEN'); | 
					
						
							|  |  |  |  |             param.refreshToken = refreshToken; | 
					
						
							|  |  |  |  |             const refreshTokenRes = await refreshToken(param) | 
					
						
							| 
									
										
										
										
											2022-06-02 17:59:57 +08:00
										 |  |  |  |             // 2.1 刷新成功,则回放队列的请求 + 当前请求
 | 
					
						
							|  |  |  |  |             vm.$store.commit('SET_TOKEN', refreshTokenRes.data) | 
					
						
							|  |  |  |  |             requestList.forEach(cb => cb()) | 
					
						
							|  |  |  |  |             return uni.$u.http.request(res.config) | 
					
						
							|  |  |  |  |           } catch (e) { | 
					
						
							|  |  |  |  |             // 为什么需要 catch 异常呢?刷新失败时,请求因为 Promise.reject 触发异常。
 | 
					
						
							|  |  |  |  |             // 2.2 刷新失败,只回放队列的请求
 | 
					
						
							|  |  |  |  |             requestList.forEach(cb => cb()) | 
					
						
							|  |  |  |  |             // 登出。即不回放当前请求!不然会形成递归
 | 
					
						
							|  |  |  |  |             vm.$store.commit('CLEAR_LOGIN_INFO') | 
					
						
							|  |  |  |  |             return Promise.reject(res) | 
					
						
							|  |  |  |  |           } finally { | 
					
						
							|  |  |  |  |             requestList = [] | 
					
						
							|  |  |  |  |             isRefreshToken = false | 
					
						
							|  |  |  |  |           } | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |           // 添加到队列,等待刷新获取到新的令牌
 | 
					
						
							|  |  |  |  |           return new Promise(resolve => { | 
					
						
							|  |  |  |  |             requestList.push(() => { | 
					
						
							|  |  |  |  |               res.config.header.Authorization = 'Bearer ' + vm.$store.getters.accessToken // 让每个请求携带自定义token 请根据实际情况自行修改
 | 
					
						
							|  |  |  |  |               resolve(uni.$u.http.request(res.config)) | 
					
						
							|  |  |  |  |             }) | 
					
						
							|  |  |  |  |           }) | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |       } else if (code === 500) { | 
					
						
							|  |  |  |  |         uni.$u.toast(msg) | 
					
						
							|  |  |  |  |         return Promise.reject(res) | 
					
						
							|  |  |  |  |       } else if (code === 901) { | 
					
						
							|  |  |  |  |         uni.$u.toast('演示模式,无法进行写操作') | 
					
						
							|  |  |  |  |         return Promise.reject(res) | 
					
						
							|  |  |  |  |       } else if (code !== 0) { | 
					
						
							|  |  |  |  |         if (msg === '无效的刷新令牌') { | 
					
						
							|  |  |  |  |           // hard coding:忽略这个提示,直接登出
 | 
					
						
							|  |  |  |  |           console.log(msg) | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |           uni.$u.toast(msg) | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         return Promise.reject(res) | 
					
						
							|  |  |  |  |       } else { | 
					
						
							|  |  |  |  |         return res.data | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     err => { | 
					
						
							|  |  |  |  |       console.log(err) | 
					
						
							|  |  |  |  |       let { message } = err | 
					
						
							|  |  |  |  |       if (!message) { | 
					
						
							|  |  |  |  |         message = '系统发生未知错误' | 
					
						
							|  |  |  |  |       }else if (message === 'Network Error') { | 
					
						
							|  |  |  |  |         message = '后端接口连接异常' | 
					
						
							|  |  |  |  |       } else if (message.includes('timeout')) { | 
					
						
							|  |  |  |  |         message = '系统接口请求超时' | 
					
						
							|  |  |  |  |       } else if (message.includes('Request failed with status code')) { | 
					
						
							|  |  |  |  |         message = '系统接口' + message.substring(message.length - 3) + '异常' | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |       uni.$u.toast(message) | 
					
						
							|  |  |  |  |       return Promise.reject(err) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   ) | 
					
						
							|  |  |  |  | } |