Vue3.0+TS+ElementUI+登录判断拦截---请求层封装

import axios from 'axios'
import type { AxiosRequestConfig } from 'axios'
import { ElMessage, ElMessageBox } from 'element-plus'
import 'element-plus/es/components/message-box/style/index'
import 'element-plus/es/components/message/style/index'
import { user } from '@/stores/user'
import { Menu } from '@/stores/menu'
import { ElLoading } from 'element-plus'
import 'element-plus/theme-chalk/el-loading.css'
import type { LoadingInstance } from 'element-plus/lib/components/loading/src/loading'
const request = axios.create({
    baseURL: import.meta.env.VITE_API_BASEURL
})
console.log(import.meta.env)
// 请求拦截器
request.interceptors.request.use(
    function (config) {
        // 统一设置用户身份 token
        const token = sessionStorage.getItem('token')
        if (token) {
            config.headers.Authorization = `Bearer ${token}`
            // config.headers.token = token
        }
        return config
    },
    function (error) {
        // Do something with request error
        return Promise.reject(error)
    }
)

// 控制登录过期的锁
let isRefreshing = false

// 响应拦截器
request.interceptors.response.use(
    function (response) {
        const status = response.data.status
        const code = response.data.code
        if (code > 0) {
            // 权限相关的报错code会大于0
            ElMessage.error(response.data.message || '请求失败,请稍后重试')
            return Promise.reject(response)
        }
        // 正确的情况
        if (!status || status === 200) {
            return response
        }

        // 错误情况:比如 token 无效...
        // 其它错误情况
        ElMessage.error(response.data.msg || '请求失败,请稍后重试')
        // 手动返回一个 Promise 异常
        return Promise.reject(response)
    },
    function (error) {
        const errorCode =
            typeof error.request.status === 'number'
                ? error.request.status
                : error.request.status.status
        if (errorCode === 401) {
            // 跳转登录
            if (isRefreshing) return Promise.reject(error.request)
            isRefreshing = true
            ElMessageBox.confirm(
                '您的登录已过期,您可以取消停留在此页面,或确认重新登录',
                '登录过期',
                {
                    confirmButtonText: '确认',
                    cancelButtonText: '取消'
                }
            )
                .then(() => {
                    // 清除本地过期的登录状态
                    user.$reset() // 重置状态
                    Menu.$reset()
                    // 跳转到登录页面
                    window.open(`跳转登录首页地址`,'_self')
                })
                .finally(() => {
                    isRefreshing = false
                })

            // 在内部消化掉这个业务异常
            return Promise.reject(error)
        } else if (errorCode === 403) {
            ElMessage.error('无权限访问')
            return Promise.reject(error)
        }
        ElMessage.error(error.message || '请求失败,请稍后重试')
        return Promise.reject(error)
    }
)

export default <T = any>(
    config: AxiosRequestConfig,
    isLoading: boolean = true,
    customData = false,
    rejectError = false
) => {
    let loadingInstance: LoadingInstance | null
    if (isLoading) {
        // 默认是需要遮罩
        // 设置加载遮罩
        loadingInstance = ElLoading.service({
            fullscreen: true,
            body: true,
            text: '加载中...'
        })
    }
    return request(config)
        .then((res) => {
            return customData ? (res.data as T) : ((res.data.data || res.data) as T)
        })
        .catch((error) => {
            if (rejectError) return error
        })
        .finally(() => {
            // 最后都关闭遮罩
            if (isLoading) {
                loadingInstance && loadingInstance.close() // 关闭遮罩
            }
        })
}

猜你喜欢

转载自blog.csdn.net/weixin_50543490/article/details/131420696