tps-ui-components
Version:
TPS UI组件库 - 基于Vue 2和Element UI的企业级组件库
326 lines (293 loc) • 7.5 kB
JavaScript
/**
* TPS HTTP请求工具
* 基于axios封装的HTTP请求库,提供统一的请求/响应处理
* @version 1.0.0
* @author TPS Team
*/
import axios from 'axios'
// 默认配置
const DEFAULT_CONFIG = {
baseURL: process.env.VUE_APP_BASE_API || '/api',
timeout: 10000,
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
}
/**
* 创建axios实例
* @param {Object} config - 自定义配置
* @returns {Object} axios实例
*/
function createRequest(config = {}) {
const instance = axios.create({
...DEFAULT_CONFIG,
...config
})
// 请求拦截器
instance.interceptors.request.use(
(config) => {
// 添加认证token
const token = getToken()
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
// 添加请求时间戳(防止缓存)
if (config.method === 'get') {
config.params = {
...config.params,
_t: Date.now()
}
}
// 请求日志
if (process.env.NODE_ENV === 'development') {
console.log('🚀 Request:', {
url: config.url,
method: config.method,
params: config.params,
data: config.data
})
}
return config
},
(error) => {
console.error('❌ Request Error:', error)
return Promise.reject(error)
}
)
// 响应拦截器
instance.interceptors.response.use(
(response) => {
const { data, config } = response
// 响应日志
if (process.env.NODE_ENV === 'development') {
console.log('✅ Response:', {
url: config.url,
data: data
})
}
// 检查业务状态码
if (data.code !== undefined && data.code !== 200) {
const errorMessage = data.message || data.msg || '请求失败'
// 显示错误信息
showErrorMessage(errorMessage)
// 特殊状态码处理
handleSpecialStatusCode(data.code, errorMessage)
return Promise.reject(new Error(errorMessage))
}
// 返回数据
return data.data !== undefined ? data.data : data
},
(error) => {
console.error('❌ Response Error:', error)
let errorMessage = '网络请求失败'
if (error.response) {
const { status, data } = error.response
// HTTP状态码错误处理
switch (status) {
case 400:
errorMessage = data.message || '请求参数错误'
break
case 401:
errorMessage = '未授权,请重新登录'
handleUnauthorized()
break
case 403:
errorMessage = '拒绝访问'
break
case 404:
errorMessage = '请求的资源不存在'
break
case 408:
errorMessage = '请求超时'
break
case 500:
errorMessage = '服务器内部错误'
break
case 502:
errorMessage = '网关错误'
break
case 503:
errorMessage = '服务不可用'
break
case 504:
errorMessage = '网关超时'
break
default:
errorMessage = data.message || `连接错误${status}`
}
} else if (error.request) {
errorMessage = '网络连接失败,请检查网络设置'
} else {
errorMessage = error.message || '请求配置错误'
}
// 显示错误信息
showErrorMessage(errorMessage)
return Promise.reject(error)
}
)
return instance
}
/**
* 获取认证token
* @returns {string|null} token
*/
function getToken() {
return localStorage.getItem('token') || sessionStorage.getItem('token')
}
/**
* 显示错误信息
* @param {string} message - 错误信息
*/
function showErrorMessage(message) {
// 尝试使用Element UI的Message组件
if (typeof window !== 'undefined' && window.Vue && window.Vue.prototype.$message) {
window.Vue.prototype.$message({
message,
type: 'error',
duration: 3000,
showClose: true
})
} else {
// 降级到console.error
console.error('API Error:', message)
}
}
/**
* 处理特殊状态码
* @param {number} code - 状态码
* @param {string} message - 错误信息
*/
function handleSpecialStatusCode(code, message) {
switch (code) {
case 401:
case 403:
handleUnauthorized()
break
case 1001:
// 自定义业务状态码处理
console.warn('业务警告:', message)
break
default:
break
}
}
/**
* 处理未授权情况
*/
function handleUnauthorized() {
// 清除token
localStorage.removeItem('token')
sessionStorage.removeItem('token')
// 跳转到登录页
if (typeof window !== 'undefined' && window.Vue && window.Vue.prototype.$router) {
window.Vue.prototype.$router.push('/login')
}
}
// 创建默认实例
const request = createRequest()
/**
* GET请求
* @param {string} url - 请求地址
* @param {Object} params - 请求参数
* @param {Object} config - 请求配置
* @returns {Promise} 请求Promise
*/
export const get = (url, params = {}, config = {}) => {
return request({
method: 'get',
url,
params,
...config
})
}
/**
* POST请求
* @param {string} url - 请求地址
* @param {Object} data - 请求数据
* @param {Object} config - 请求配置
* @returns {Promise} 请求Promise
*/
export const post = (url, data = {}, config = {}) => {
return request({
method: 'post',
url,
data,
...config
})
}
/**
* PUT请求
* @param {string} url - 请求地址
* @param {Object} data - 请求数据
* @param {Object} config - 请求配置
* @returns {Promise} 请求Promise
*/
export const put = (url, data = {}, config = {}) => {
return request({
method: 'put',
url,
data,
...config
})
}
/**
* DELETE请求
* @param {string} url - 请求地址
* @param {Object} params - 请求参数
* @param {Object} config - 请求配置
* @returns {Promise} 请求Promise
*/
export const del = (url, params = {}, config = {}) => {
return request({
method: 'delete',
url,
params,
...config
})
}
/**
* 文件上传
* @param {string} url - 上传地址
* @param {FormData} formData - 文件数据
* @param {Object} config - 请求配置
* @returns {Promise} 请求Promise
*/
export const upload = (url, formData, config = {}) => {
return request({
method: 'post',
url,
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
},
...config
})
}
/**
* 下载文件
* @param {string} url - 下载地址
* @param {Object} params - 请求参数
* @param {string} filename - 文件名
* @returns {Promise} 请求Promise
*/
export const download = (url, params = {}, filename = '') => {
return request({
method: 'get',
url,
params,
responseType: 'blob'
}).then(response => {
const blob = new Blob([response])
const downloadUrl = window.URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = downloadUrl
link.download = filename || 'download'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(downloadUrl)
})
}
// 导出默认实例和创建函数
export default request
export { createRequest }