import axios, { type AxiosInstance, type AxiosResponse } from 'axios' export interface ApiResponse { data: T error?: ApiError meta?: any trace_id?: string } export interface ApiError { code: string message: string type: 'system' | 'user' key?: string } export interface HttpClientConfig { baseURL?: string timeout?: number headers?: Record } export interface MiddlewareContext { config: any response?: AxiosResponse error?: ApiError store?: any } export type Middleware = ( context: MiddlewareContext, next: () => Promise ) => Promise export class ApiClient { private instance: AxiosInstance private middlewares: Middleware[] = [] private store: any = null private accessToken: string | null = null private tenantId: string | null = null constructor(config: HttpClientConfig = {}) { this.instance = axios.create({ baseURL: config.baseURL || '/api', timeout: config.timeout || 10000, headers: { 'Content-Type': 'application/json', ...config.headers } }) this.setupInterceptors() } // 设置 store(用于中间件访问用户状态) setStore(store: any): this { this.store = store return this } // 设置访问令牌 setToken(token: string | null): this { this.accessToken = token return this } // 设置租户ID setTenant(tenantId: string | null): this { this.tenantId = tenantId return this } // 添加中间件 addMiddleware(middleware: Middleware): this { this.middlewares.push(middleware) return this } private setupInterceptors(): void { // 请求拦截器:自动注入 token 和 tenant_id this.instance.interceptors.request.use((config) => { if (this.accessToken) { config.headers = config.headers || {} config.headers['Authorization'] = `Bearer ${this.accessToken}` } if (this.tenantId) { config.headers = config.headers || {} config.headers['X-Tenant-Id'] = this.tenantId } return config }) // 响应拦截器:基础错误处理 this.instance.interceptors.response.use( (response) => response, (error) => Promise.reject(error) ) } private handleError(error: any): ApiError { return { code: error.response?.status?.toString() || '500', message: error.response?.data?.message || error.message, type: 'system' } } // 执行带中间件的请求 private async executeWithMiddlewares(config: any): Promise { const context: MiddlewareContext = { config: { ...config }, store: this.store } // 构建中间件执行链 const executeMiddleware = async (index: number): Promise => { if (index >= this.middlewares.length) { // 所有中间件的 next() 前部分执行完毕,发起真正的 HTTP 请求 try { const response = await this.instance.request(context.config) context.response = response return response } catch (error) { context.error = this.handleError(error) throw context.error } } const currentMiddleware = this.middlewares[index] const next = async () => await executeMiddleware(index + 1) // 执行中间件,确保返回响应 const result = await currentMiddleware(context, next) // 如果中间件返回了结果,使用它;否则使用 context 中的响应 return result || context.response } const result = await executeMiddleware(0) // 确保返回有效的响应 return result || context.response } // 处理业务响应,如果有错误则抛出异常,否则返回 data private async processResponse(response: ApiResponse): Promise { if (response.error) { return Promise.reject(response.error) } if (typeof response.data === 'object' && response.data !== null) { (response.data as any).meta = () => response.meta } return response.data } async get(url: string, data?: any, config?: any): Promise { const requestConfig = { method: 'get', url, params: data, ...config } try { const response = await this.executeWithMiddlewares(requestConfig) return this.processResponse(response.data) } catch (err: any) { console.error(err) return Promise.reject({ type: 'user', key: "networkerror", message: err.message, }) } } async post(url: string, data?: any, config?: any): Promise { const requestConfig = { method: 'post', url, data, ...config } try { const response = await this.executeWithMiddlewares(requestConfig) return this.processResponse(response.data) } catch (err: any) { console.error(err) return Promise.reject({ type: 'user', key: "networkerror", message: err.message, }) } } async put(url: string, data?: any, config?: any): Promise { const requestConfig = { method: 'put', url, data, ...config } try { const response = await this.executeWithMiddlewares(requestConfig) return this.processResponse(response.data) } catch (err: any) { console.error(err) return Promise.reject({ type: 'user', key: "networkerror", message: err.message, }) } } async delete(url: string, data?: any, config?: any): Promise { const requestConfig = { method: 'delete', url, data, ...config } try { const response = await this.executeWithMiddlewares(requestConfig) return this.processResponse(response.data) } catch (err: any) { console.error(err) return Promise.reject({ type: 'user', key: "networkerror", message: err.message, }) } } // 如果需要获取完整响应(包括 meta、trace_id 等),可以使用这些方法 async getRaw(url: string, data?: any, config?: any): Promise> { const requestConfig = { method: 'get', url, params: data, ...config } const response = await this.executeWithMiddlewares(requestConfig) return response.data } async postRaw(url: string, data?: any, config?: any): Promise> { const requestConfig = { method: 'post', url, data, ...config } const response = await this.executeWithMiddlewares(requestConfig) return response.data } }