401重新登入和403权限警告

网络状态检测代码优化
This commit is contained in:
WindowBird 2025-11-27 10:32:15 +08:00
parent 84bdfcdba8
commit 8f202e50a1

View File

@ -6,6 +6,70 @@ import { useUserStore } from '@/store/user'
*/
let isRedirectingToLogin = false
/**
* 检测网络状态
* @returns {Promise<Object>} 返回网络信息如果无网络则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)
})
}