Files
wecom_it_smart_desk/frontend-admin/src/api/index.ts
T

119 lines
3.9 KiB
TypeScript

// =============================================================================
// 企微IT智能服务台 — 管理后台 Axios 实例与拦截器
// =============================================================================
// 说明:创建 Axios 实例,配置:
// 1. 请求基础 URL
// 2. 请求拦截器(添加管理员认证头)
// 3. 响应拦截器(统一错误处理)
// 与坐席端区别:使用 admin_token 而非 agent_token
import axios from 'axios'
import type { AxiosInstance, AxiosResponse, InternalAxiosRequestConfig } from 'axios'
// ElementPlus 消息提示
import { ElMessage } from 'element-plus'
// --------------------------------------------------------------------------
// 创建 Axios 实例
// --------------------------------------------------------------------------
const apiClient: AxiosInstance = axios.create({
// 基础 URL:所有请求会自动加上这个前缀
// 开发环境通过 Vite proxy 转发到后端
baseURL: '/api',
// 请求超时时间(10秒)
timeout: 10000,
// 默认请求头
headers: {
'Content-Type': 'application/json',
},
})
// --------------------------------------------------------------------------
// 请求拦截器
// --------------------------------------------------------------------------
// 在每个请求发送前执行,用于添加管理员认证信息
apiClient.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
// 从 localStorage 获取管理员 token,添加到请求头
const token = localStorage.getItem('admin_token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
(error) => {
// 请求配置错误时直接返回
return Promise.reject(error)
}
)
// --------------------------------------------------------------------------
// 响应拦截器
// --------------------------------------------------------------------------
// 在每个响应返回后执行,用于统一处理错误
apiClient.interceptors.response.use(
(response: AxiosResponse) => {
// 从响应中提取业务数据
const res = response.data
// 统一响应格式:{code: 0, data: {}, message: "success"}
// code === 0 表示业务成功
if (res.code !== 0) {
// 业务错误:显示错误消息
ElMessage.error(res.message || '请求失败')
// 特殊错误码处理
if (res.code === 1002) {
// 未授权:清除 token 并跳转到登录页
localStorage.removeItem('admin_token')
// 动态导入避免循环依赖
import('@/router').then((router) => {
router.default.push('/login')
})
}
// 返回 rejected Promise,让调用方的 catch 能捕获
return Promise.reject(new Error(res.message || '请求失败'))
}
// 业务成功:返回完整响应(调用方从 response.data.data 获取业务数据)
return response
},
(error) => {
// 网络错误或服务器错误(HTTP 状态码非 2xx)
let message = '网络异常,请稍后重试'
if (error.response) {
// 服务器返回了错误状态码
switch (error.response.status) {
case 401:
message = '未授权,请重新登录'
// 清除 token
localStorage.removeItem('admin_token')
break
case 403:
message = '拒绝访问'
break
case 404:
message = '请求的资源不存在'
break
case 500:
message = '服务器内部错误'
break
default:
message = `请求失败 (${error.response.status})`
}
} else if (error.code === 'ECONNABORTED') {
// 请求超时
message = '请求超时,请稍后重试'
}
// 显示错误提示
ElMessage.error(message)
return Promise.reject(error)
}
)
// 导出 Axios 实例,供 API 模块使用
export default apiClient