/** * 集成测试 HTTP 客户端 * 使用 axios 替代 Playwright 的 APIRequestContext,确保可在 Vitest 中运行 */ import axios, { AxiosInstance, AxiosResponse } from 'axios'; const BASE_URL = process.env.BASE_URL || 'http://localhost:3000'; let httpClient: AxiosInstance; let authToken: string | null = null; /** 初始化 HTTP 客户端 */ export function initHttpClient(): void { httpClient = axios.create({ baseURL: BASE_URL, timeout: 30000, headers: { 'Content-Type': 'application/json' }, }); } /** 释放 HTTP 客户端 */ export function disposeHttpClient(): void { httpClient = null as any; } /** 设置认证 token */ export function setAuthToken(token: string): void { authToken = token; } /** 获取当前 token */ export function getAuthToken(): string | null { return authToken; } /** API 响应类型 */ export interface ApiResponse { code: number; message: string; data: any; } /** 解析 API 响应 */ function parseResponse(response: AxiosResponse): ApiResponse { const body = response.data; if (body && typeof body === 'object' && body.code !== undefined) { return { code: body.code, message: body.message ?? '', data: body.data }; } if (body && typeof body === 'object' && body.success === true) { return { code: 0, message: '', data: body.data }; } return { code: response.status, message: '', data: body }; } /** GET 请求 */ export async function apiGet(path: string, params?: Record): Promise { const config: any = {}; if (authToken) { config.headers = { Authorization: `Bearer ${authToken}` }; } if (params) { config.params = params; } try { const response = await httpClient.get(path, config); return parseResponse(response); } catch (error: any) { if (error.response) { return parseResponse(error.response); } return { code: -1, message: error.message, data: null }; } } /** POST 请求 */ export async function apiPost(path: string, data?: any): Promise { const config: any = {}; if (authToken) { config.headers = { Authorization: `Bearer ${authToken}` }; } try { const response = await httpClient.post(path, data, config); return parseResponse(response); } catch (error: any) { if (error.response) { return parseResponse(error.response); } return { code: -1, message: error.message, data: null }; } } /** PUT 请求 */ export async function apiPut(path: string, data?: any): Promise { const config: any = {}; if (authToken) { config.headers = { Authorization: `Bearer ${authToken}` }; } try { const response = await httpClient.put(path, data, config); return parseResponse(response); } catch (error: any) { if (error.response) { return parseResponse(error.response); } return { code: -1, message: error.message, data: null }; } } /** DELETE 请求 */ export async function apiDelete(path: string): Promise { const config: any = {}; if (authToken) { config.headers = { Authorization: `Bearer ${authToken}` }; } try { const response = await httpClient.delete(path, config); return parseResponse(response); } catch (error: any) { if (error.response) { return parseResponse(error.response); } return { code: -1, message: error.message, data: null }; } } /** 创建测试用户(集成测试专用) */ export async function createTestUser(): Promise<{ token: string; userId: string }> { initHttpClient(); const phone = `138${String(Date.now()).slice(-8)}`; await apiPost('/api/auth/send-code', { phone }); const loginRes = await apiPost('/api/auth/login', { phone, code: '123456' }); if (loginRes.code !== 0 || !loginRes.data?.token) { throw new Error('创建测试用户失败'); } setAuthToken(loginRes.data.token); return { token: loginRes.data.token, userId: loginRes.data.userId || '1' }; }