Files
crawler-plugin/frontend-vue/src/shared/api/http.ts
2026-03-21 10:00:16 +08:00

126 lines
2.8 KiB
TypeScript

import axios, {
AxiosError,
type AxiosInstance,
type AxiosRequestConfig,
type AxiosResponse,
type InternalAxiosRequestConfig,
} from 'axios'
export interface LegacyApiSuccess<T> {
success: true
msg?: string
data?: T
}
export interface LegacyApiFailure {
success: false
error?: string
}
export type ApiResponse<T> = LegacyApiSuccess<T> | LegacyApiFailure
export interface JavaApiResponse<T> {
success: boolean
message: string
data: T | null
}
export type RequestOptions<D = unknown> = AxiosRequestConfig<D>
function extractErrorMessage(error: unknown) {
if (error instanceof AxiosError) {
const data = error.response?.data
if (data && typeof data === 'object') {
if ('error' in data && data.error) {
return String(data.error)
}
if ('message' in data && data.message) {
return String(data.message)
}
}
if (typeof data === 'string' && data.trim()) {
return data
}
return error.message || '请求失败'
}
return error instanceof Error ? error.message : '请求失败'
}
function createHttpClient(): AxiosInstance {
const instance = axios.create({
withCredentials: true,
timeout: 30000,
headers: {
'X-Requested-With': 'XMLHttpRequest',
},
})
instance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
return config
})
instance.interceptors.response.use(
(response: AxiosResponse) => response,
(error: unknown) => Promise.reject(new Error(extractErrorMessage(error))),
)
return instance
}
export const http = createHttpClient()
export async function request<T = unknown, D = unknown>(config: RequestOptions<D>): Promise<T> {
const response = await http.request<T, AxiosResponse<T>, D>(config)
return response.data
}
export function get<T = unknown>(url: string, config?: RequestOptions) {
return request<T>({
url,
method: 'GET',
...config,
})
}
export function post<T = unknown, D = unknown>(url: string, data?: D, config?: RequestOptions<D>) {
return request<T, D>({
url,
method: 'POST',
data,
...config,
})
}
export function put<T = unknown, D = unknown>(url: string, data?: D, config?: RequestOptions<D>) {
return request<T, D>({
url,
method: 'PUT',
data,
...config,
})
}
export function del<T = unknown>(url: string, config?: RequestOptions) {
return request<T>({
url,
method: 'DELETE',
...config,
})
}
export const requestJson = request
export const requestGetJson = get
export const requestPostJson = post
export const requestPutJson = put
export const requestDeleteJson = del
export async function unwrapJavaResponse<T>(promise: Promise<JavaApiResponse<T>>) {
const response = await promise
if (!response.success) {
throw new Error(response.message || '请求失败')
}
return response.data as T
}