SYN/stu/src/api/request.ts

145 lines
4.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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