diff --git a/utils/request/index.js b/utils/request/index.js index 9e43882..48625d3 100644 --- a/utils/request/index.js +++ b/utils/request/index.js @@ -6,6 +6,70 @@ import { useUserStore } from '@/store/user' */ let isRedirectingToLogin = false +/** + * 检测网络状态 + * @returns {Promise} 返回网络信息,如果无网络则reject + * @throws {Object} 网络不可用或检测失败时抛出错误 + */ +async function checkNetworkStatus() { + try { + const networkInfo = await new Promise((resolve, reject) => { + uni.getNetworkType({ + success: resolve, + fail: reject + }) + }) + + // 如果没有网络连接,抛出错误 + if (networkInfo.networkType === 'none') { + uni.$uv.toast('网络连接不可用,请检查网络设置') + return Promise.reject({ + errMsg: '网络连接不可用', + networkType: 'none' + }) + } + + return networkInfo + } catch (error) { + console.error('获取网络状态失败:', error) + uni.$uv.toast('无法检测网络状态,请检查网络连接') + return Promise.reject({ + errMsg: '无法检测网络状态', + error + }) + } +} + +/** + * 处理认证错误 + * @param {number} statusCode - HTTP状态码 + * @param {number} code - 响应数据中的code(可选,用于响应拦截器) + */ +function handleAuthError(statusCode, code = null) { + // 使用响应数据中的code(如果提供),否则使用statusCode + const errorCode = code !== null ? code : statusCode + + // 401: 未授权,需要重新登录 + if (errorCode === 401) { + const userStore = useUserStore() + userStore.logout() + + // 防止重复跳转 + if (!isRedirectingToLogin) { + isRedirectingToLogin = true + uni.$uv.toast('登录已过期,请重新登录') + setTimeout(() => { + uni.reLaunch({ url: '/pages/login/index' }) + isRedirectingToLogin = false + }, 200) + } + } + // 403: 无权限,只提示,不跳转 + else if (errorCode === 403) { + uni.$uv.toast('没有权限') + } +} + export const Request = () => { // 初始化请求配置 uni.$uv.http.setConfig((config) => { @@ -16,32 +80,13 @@ export const Request = () => { }) // 请求拦截 - uni.$uv.http.interceptors.request.use(async (config) => { // 可使用async await 做异步操作 + uni.$uv.http.interceptors.request.use(async (config) => { // 检测网络状态 try { - const networkInfo = await new Promise((resolve, reject) => { - uni.getNetworkType({ - success: resolve, - fail: reject - }) - }) - - // 如果没有网络连接,阻止请求并提示 - if (networkInfo.networkType === 'none') { - uni.$uv.toast('网络连接不可用,请检查网络设置') - return Promise.reject({ - errMsg: '网络连接不可用', - networkType: 'none' - }) - } + await checkNetworkStatus() } catch (error) { - console.error('获取网络状态失败:', error) - // 如果获取网络状态失败,也提示用户 - uni.$uv.toast('无法检测网络状态,请检查网络连接') - return Promise.reject({ - errMsg: '无法检测网络状态', - error - }) + // 网络不可用,阻止请求 + return Promise.reject(error) } // 初始化请求拦截器时,会执行此方法,此时data为undefined,赋予默认{} @@ -62,7 +107,7 @@ export const Request = () => { } } return config - }, config => { // 可使用async await 做异步操作 + }, config => { return Promise.reject(config) }) @@ -73,29 +118,10 @@ export const Request = () => { // 自定义参数 const custom = response.config?.custom - // 处理 token 过期等情况(根据实际业务调整) - if (data.code === 401) { - // token 过期或无效,清除登录状态 - const userStore = useUserStore() - userStore.logout() - - if (!isRedirectingToLogin) { - isRedirectingToLogin = true - uni.$uv.toast('登录已过期,请重新登录') - setTimeout(() => { - uni.reLaunch({ url: '/pages/login/index' }) - isRedirectingToLogin = false - }, 200) - } - } - - - if (data.code === 403) { - uni.$uv.toast('无权限') - // setTimeout(() => { - // uni.reLaunch({ url: '/pages/login/index' }) - // isRedirectingToLogin = false - // }, 200) + // 处理认证错误(401/403) + // 401需要跳转登录,403只提示权限不足 + if (data.code === 401 || data.code === 403) { + handleAuthError(null, data.code) } if (data.code !== 200) { @@ -131,39 +157,22 @@ export const Request = () => { if (!response.statusCode || response.statusCode === 0) { // 可能是网络连接问题,再次检测网络状态 try { - const networkInfo = await new Promise((resolve, reject) => { - uni.getNetworkType({ - success: resolve, - fail: reject - }) - }) - - if (networkInfo.networkType === 'none') { - uni.$uv.toast('网络连接不可用,请检查网络设置') - return Promise.reject({ - errMsg: '网络连接不可用', - networkType: 'none' - }) - } + await checkNetworkStatus() } catch (error) { - uni.$uv.toast('网络连接异常,请检查网络设置') + // 网络检测失败,直接返回错误 + return Promise.reject(error) } + // 网络正常但请求失败,提示并返回响应错误 uni.$uv.toast('网络连接异常,请稍后重试') return Promise.reject(response) } + // 处理认证错误(401/403) + // 401需要跳转登录,403只提示权限不足 if (response.statusCode === 401 || response.statusCode === 403) { - const userStore = useUserStore() - userStore.logout() - if (!isRedirectingToLogin) { - isRedirectingToLogin = true - uni.$uv.toast('登录已过期,请重新登录') - setTimeout(() => { - uni.reLaunch({ url: '/pages/login/index' }) - isRedirectingToLogin = false - }, 200) - } + handleAuthError(response.statusCode) } + return Promise.reject(response) }) } \ No newline at end of file