/** * 独立API测试模块 - 纯TypeScript/JavaScript * 可以直接在浏览器控制台或Node.js中运行 * 不依赖Vite别名或前端代理配置 * 直接调用后端API服务 */ interface ProjectInfo { id: string name: string description: string path: string tenant_id: string creator: string created_at: string } interface HealthCheckResponse { healthy: boolean version: string [key: string]: any } interface TestResult { success: boolean duration: number data?: any error?: string } /** * 配置 */ const CONFIG = { // 后端API基础URL BACKEND_BASE_URL: 'http://localhost:8020', // API前缀 API_PREFIX: '/api', // 超时时间(毫秒) TIMEOUT: 10000, } /** * 获取完整的API URL */ function getApiUrl(endpoint: string): string { // 确保endpoint以/开头 const normalizedEndpoint = endpoint.startsWith('/') ? endpoint : `/${endpoint}` return `${CONFIG.BACKEND_BASE_URL}${CONFIG.API_PREFIX}${normalizedEndpoint}` } /** * 发起API请求 */ async function apiRequest( method: string, endpoint: string, data?: any ): Promise { const url = getApiUrl(endpoint) const controller = new AbortController() const timeoutId = setTimeout(() => controller.abort(), CONFIG.TIMEOUT) try { const response = await fetch(url, { method, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: data ? JSON.stringify(data) : undefined, signal: controller.signal, }) clearTimeout(timeoutId) if (!response.ok) { let errorMessage = `HTTP ${response.status}` try { const errorData = await response.json() errorMessage += `: ${JSON.stringify(errorData)}` } catch { // 忽略JSON解析错误 } throw new Error(errorMessage) } const responseData = await response.json() // 处理后端返回格式(假设是 {success: true, data: ...} 或直接是数据) if (responseData.success !== undefined) { if (!responseData.success) { throw new Error(responseData.message || responseData.error || '请求失败') } return responseData.data || responseData } return responseData } catch (error: any) { clearTimeout(timeoutId) if (error.name === 'AbortError') { throw new Error(`请求超时 (${CONFIG.TIMEOUT}ms)`) } throw error } } /** * API函数 - 测试专用(直接调用后端) */ export const testApi = { /** * 获取项目列表 */ async getProjects(): Promise { return apiRequest('GET', '/projects') }, /** * 健康检查 */ async checkHealth(): Promise { return apiRequest('GET', '/health') }, /** * 测试连接 */ async testConnection(timeoutMs: number = 5000): Promise { const startTime = Date.now() try { const controller = new AbortController() const timeoutId = setTimeout(() => controller.abort(), timeoutMs) const response = await fetch(getApiUrl('/health'), { signal: controller.signal, }) clearTimeout(timeoutId) if (!response.ok) { throw new Error(`HTTP ${response.status}`) } const data = await response.json() const duration = Date.now() - startTime return { success: true, duration, data } } catch (error: any) { const duration = Date.now() - startTime return { success: false, duration, error: error.message || '未知错误' } } }, } /** * 测试函数 */ export async function testGetProjects(): Promise { console.log('🧪 开始测试 getProjects API (直接调用后端)...') console.log(` 后端URL: ${CONFIG.BACKEND_BASE_URL}`) console.log(` API端点: ${getApiUrl('/projects')}`) try { const projects = await testApi.getProjects() console.log(`✅ 测试成功!获取到 ${projects.length} 个项目`) if (projects.length > 0) { console.log(' 项目列表:') projects.forEach((project: ProjectInfo, index: number) => { console.log(` ${index + 1}. ${project.name} (ID: ${project.id})`) console.log(` 描述: ${project.description}`) console.log(` 路径: ${project.path}`) }) } else { console.log('⚠️ 警告: 项目列表为空') } return true } catch (error: any) { console.error('❌ 测试失败:', error.message || error) console.error(' 请检查:') console.error(' 1. 后端服务是否运行在端口8020') console.error(' 2. 网络连接是否正常') console.error(' 3. 跨域设置是否正确') return false } } export async function testHealthCheck(): Promise { console.log('🧪 开始测试健康检查 API...') console.log(` 后端URL: ${CONFIG.BACKEND_BASE_URL}`) console.log(` API端点: ${getApiUrl('/health')}`) try { const health = await testApi.checkHealth() console.log(`✅ 健康检查成功!`) console.log(` 健康状态: ${health.healthy ? '健康' : '不健康'}`) console.log(` 版本: ${health.version}`) if (!health.healthy) { console.warn('⚠️ 警告: 后端报告不健康状态') } return true } catch (error: any) { console.error('❌ 健康检查失败:', error.message || error) return false } } export async function testBackendConnection(): Promise { console.log('🧪 开始测试后端连接...') console.log(` 后端URL: ${CONFIG.BACKEND_BASE_URL}`) try { const result = await testApi.testConnection(3000) if (result.success) { console.log(`✅ 连接测试成功!`) console.log(` 响应时间: ${result.duration}ms`) console.log(` 健康状态: ${result.data?.healthy ? '健康' : '不健康'}`) return true } else { console.error(`❌ 连接测试失败: ${result.error}`) return false } } catch (error: any) { console.error('❌ 连接测试异常:', error.message || error) return false } } /** * 运行所有测试 */ export async function runAllTests() { console.log('='.repeat(60)) console.log('🚀 开始运行独立API测试 (直接调用后端)') console.log('='.repeat(60)) console.log(`后端服务: ${CONFIG.BACKEND_BASE_URL}`) console.log(`API前缀: ${CONFIG.API_PREFIX}`) console.log('='.repeat(60)) const results = { healthCheck: false, connection: false, getProjects: false, } // 测试健康检查 results.healthCheck = await testHealthCheck() // 测试连接 results.connection = await testBackendConnection() // 测试获取项目列表 if (results.connection) { results.getProjects = await testGetProjects() } else { console.log('⏭️ 跳过项目列表测试(连接测试失败)') } console.log('='.repeat(60)) console.log('📊 测试结果汇总:') console.log('='.repeat(60)) console.log(`健康检查: ${results.healthCheck ? '✅ 通过' : '❌ 失败'}`) console.log(`连接测试: ${results.connection ? '✅ 通过' : '❌ 失败'}`) console.log(`获取项目: ${results.getProjects ? '✅ 通过' : results.connection ? '❌ 失败' : '⏭️ 跳过'}`) const allPassed = Object.values(results).every(result => result === true) console.log(`\n${allPassed ? '🎉 所有测试通过!' : '⚠️ 部分测试失败'}`) return allPassed } /** * 浏览器控制台快捷方式 */ if (typeof window !== 'undefined') { // 在浏览器控制台中可以使用 window.testAPI 来运行测试 ;(window as any).testAPI = { runAllTests, testGetProjects, testHealthCheck, testBackendConnection, testApi, } console.log(` 🛠️ API测试工具已加载! 在浏览器控制台中输入以下命令进行测试: 1. testAPI.runAllTests() - 运行所有测试 2. testAPI.testGetProjects() - 测试项目列表API 3. testAPI.testHealthCheck() - 测试健康检查API 4. testAPI.testBackendConnection() - 测试后端连接 5. testAPI.testApi.getProjects() - 直接调用API函数 后端配置: - URL: ${CONFIG.BACKEND_BASE_URL} - API前缀: ${CONFIG.API_PREFIX} `) } /** * Node.js环境支持 */ if (typeof module !== 'undefined' && module.exports) { module.exports = { runAllTests, testGetProjects, testHealthCheck, testBackendConnection, testApi, } } export default { runAllTests, testGetProjects, testHealthCheck, testBackendConnection, testApi, }