145 lines
4.1 KiB
TypeScript
145 lines
4.1 KiB
TypeScript
// api/request.ts
|
||
export class Request {
|
||
private baseURL: string
|
||
private interceptors: {
|
||
request: Array<(config: any) => any>
|
||
response: Array<(response: any) => any>
|
||
}
|
||
|
||
constructor(baseURL: string = '') {
|
||
this.baseURL = baseURL
|
||
this.interceptors = {
|
||
request: [],
|
||
response: []
|
||
}
|
||
}
|
||
|
||
// 添加请求拦截器
|
||
useRequestInterceptor(interceptor: (config: any) => any) {
|
||
this.interceptors.request.push(interceptor)
|
||
}
|
||
|
||
// 添加响应拦截器
|
||
useResponseInterceptor(interceptor: (response: any) => any) {
|
||
this.interceptors.response.push(interceptor)
|
||
}
|
||
|
||
async request(method: string, url: string, data?: any) {
|
||
let config = {
|
||
method,
|
||
url: this.baseURL + url,
|
||
data,
|
||
headers: {},
|
||
// 添加params字段用于区分GET参数
|
||
params: method === 'GET' || method === 'HEAD' ? data : undefined
|
||
}
|
||
|
||
// 执行请求拦截器
|
||
for (const interceptor of this.interceptors.request) {
|
||
config = await interceptor(config)
|
||
}
|
||
|
||
// 构建完整的URL(处理GET参数)
|
||
let fullUrl = config.url
|
||
if (config.params && Object.keys(config.params).length > 0) {
|
||
const queryString = new URLSearchParams(config.params).toString()
|
||
fullUrl += (fullUrl.includes('?') ? '&' : '?') + queryString
|
||
}
|
||
|
||
const fetchConfig: RequestInit = {
|
||
method: config.method,
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
...config.headers
|
||
}
|
||
}
|
||
|
||
// 只有非GET/HEAD请求才设置body
|
||
if (config.method !== 'GET' && config.method !== 'HEAD' && config.data) {
|
||
fetchConfig.body = JSON.stringify(config.data)
|
||
}
|
||
|
||
try {
|
||
const response = await fetch(fullUrl, fetchConfig)
|
||
|
||
if (!response.ok) {
|
||
throw new Error(`HTTP错误: ${response.status}`)
|
||
}
|
||
|
||
const result = await response.json()
|
||
|
||
let finalResult = { ...result, status: response.status }
|
||
for (const interceptor of this.interceptors.response) {
|
||
finalResult = await interceptor(finalResult)
|
||
}
|
||
|
||
return finalResult
|
||
} catch (error) {
|
||
// 错误处理
|
||
console.error('请求失败:', error)
|
||
throw error
|
||
}
|
||
}
|
||
|
||
get(url: string, params?: any) {
|
||
return this.request('GET', url, params)
|
||
}
|
||
|
||
post(url: string, data?: any) {
|
||
return this.request('POST', url, data)
|
||
}
|
||
|
||
put(url: string, data?: any) {
|
||
return this.request('PUT', url, data)
|
||
}
|
||
|
||
delete(url: string, data?: any) {
|
||
return this.request('DELETE', url, data)
|
||
}
|
||
}
|
||
|
||
// 创建实例
|
||
const request = new Request('http://192.168.123.111:8083/api/')
|
||
|
||
// 添加全局请求拦截器
|
||
request.useRequestInterceptor(async (config) => {
|
||
// 添加认证token
|
||
const token = localStorage.getItem('token')
|
||
if (token) {
|
||
config.headers.Authorization = `Bearer ${token}`
|
||
}
|
||
|
||
if (config.url.includes('/enrollment/') && config.params?.idCard) {
|
||
const idCardRegex = /(^\d{18}$)|(^\d{17}(\d|X|x)$)/
|
||
if (!idCardRegex.test(config.params.idCard)) {
|
||
throw new Error('身份证号格式不正确')
|
||
}
|
||
}
|
||
|
||
return config
|
||
})
|
||
|
||
// 添加全局响应拦截器
|
||
request.useResponseInterceptor(async (response) => {
|
||
// 根据你的后端返回结构调整
|
||
if (response.code && response.code !== 200 && response.code !== 0 && response.code !== 1) {
|
||
// 处理业务错误
|
||
switch (response.code) {
|
||
case 401:
|
||
window.location.href = '/login'
|
||
break
|
||
case 403:
|
||
throw new Error('权限不足,无法访问')
|
||
default:
|
||
throw new Error(response.message || '请求失败')
|
||
}
|
||
}
|
||
return response
|
||
})
|
||
|
||
// 添加错误处理拦截器
|
||
request.useResponseInterceptor(async (response) => {
|
||
return response
|
||
})
|
||
|
||
export default request |