| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- /**
- * 独立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<T = any>(
- method: string,
- endpoint: string,
- data?: any
- ): Promise<T> {
- 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<ProjectInfo[]> {
- return apiRequest<ProjectInfo[]>('GET', '/projects')
- },
-
- /**
- * 健康检查
- */
- async checkHealth(): Promise<HealthCheckResponse> {
- return apiRequest<HealthCheckResponse>('GET', '/health')
- },
-
- /**
- * 测试连接
- */
- async testConnection(timeoutMs: number = 5000): Promise<TestResult> {
- 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<boolean> {
- 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<boolean> {
- 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<boolean> {
- 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,
- }
|