Newer
Older
xc-metering-front / src / api / index.ts
liyaguang on 19 Jul 2023 3 KB first commit
import axios from 'axios'
// import qs from 'qs'
import { ElLoading, ElMessage } from 'element-plus'
import router from '@/router/index'
import useUserStore from '@/store/modules/user'
// 错误码枚举
enum responseCode {
  success = 200, // 成功
  noPermission = 401, // 未授权
  error = 500, // 服务器异常
}
// 以下地址发生错误直接跳转至登录页
const toLoginPath = ['/sys/user/permission', '/sys/user/info']

// 跳转到登录页面
const toLogin = () => {
  useUserStore().logout()
  router.push({
    path: '/login',
    query: {
      redirect: router.currentRoute.value.path !== '/login' ? router.currentRoute.value.fullPath : undefined,
    },
  })
}

const request = axios.create({
  baseURL: import.meta.env.DEV && import.meta.env.VITE_OPEN_PROXY === 'true' ? '/proxy/' : import.meta.env.VITE_APP_API_BASEURL,
  timeout: 1000 * 60,
  responseType: 'json',
})

request.interceptors.request.use(
  (request) => {
    const userStore = useUserStore()
    /**
     * 全局拦截请求发送前提交的参数
     * 以下代码为示例,在请求头里带上 token 信息
     */
    if (userStore.isLogin && request.headers) {
      request.headers.token = userStore.token
    }
    // 是否将 POST 请求参数进行字符串化处理
    if (request.method === 'post') {
      // request.data = qs.stringify(request.data, {
      //   arrayFormat: 'brackets',
      // })
    }
    return request
  },
)

request.interceptors.response.use(
  (response) => {
    /**
     * 全局拦截请求发送后返回的数据,如果数据有报错则在这做全局的错误提示
     * 如果是文件直接返回整个response对象
     */
    if (response.data instanceof Blob) {
      return Promise.resolve(response)
    }
    else if (response.data.code !== responseCode.success) {
      if (response.data.code === responseCode.noPermission) { // token失效状态跳转到登录页
        toLogin()
        if (useUserStore().isLogout === 0) {
          ElMessage.error(response.data.message || '发生错误')
        }
        useUserStore().toLogout()
      }
      else {
        // 这里做错误提
        ElMessage.error(`${response.data.message}` || '发生错误')
        const loadingInstance = ElLoading.service({})
        nextTick(() => {
          // Loading should be closed asynchronously
          loadingInstance.close()
        })
      }

      return Promise.reject(response.data)
    }
    else { // 成功
      return Promise.resolve(response.data)
    }
  },
  (error) => {
    // 处理文件下载的错误提示
    if (error.response && error.response.data instanceof Blob) {
      const reader = new FileReader()
      reader.onload = (e) => {
        let errMsg = '发生错误!'
        if (e && e.target!.result) {
          errMsg = JSON.parse(e.target!.result as string)
        }
        ElMessage.error(errMsg)
      }
    }
    else if (error.response && error.response.data) {
      // 如果是发生错误必须回到登录页的api
      const needLogin = toLoginPath.findIndex(path => error.request.responseURL.includes(path))
      if (needLogin > -1) {
        toLogin()
      }
      else {
        const message: string = error.response.data.message
        ElMessage({
          message,
          type: 'error',
        })
      }
    }
    else if (error.message) {
      let message = error.message
      if (message === 'Network Error') {
        message = '后端网络故障'
      }
      else if (message.includes('timeout')) {
        message = '接口请求超时'
      }
      else if (message.includes('Request failed with status code')) {
        message = `接口${message.substr(message.length - 3)}异常`
      }
      ElMessage({
        message,
        type: 'error',
      })
    }

    return Promise.reject(error)
  },
)

export default request