/** * Phase 3: 批处理API测试脚本 * * 测试所有批处理API端点 */ import axios from 'axios'; const BASE_URL = 'http://localhost:3001/api/v1'; // 等待服务器启动 async function waitForServer(maxAttempts = 10) { console.log('⏳ 等待服务器启动...'); for (let i = 0; i < maxAttempts; i++) { try { await axios.get(`${BASE_URL}`); console.log('✅ 服务器已就绪\n'); return true; } catch (error) { if (i < maxAttempts - 1) { await new Promise(resolve => setTimeout(resolve, 2000)); } } } console.error('❌ 服务器启动超时'); return false; } // 测试1: 获取所有预设模板 async function testGetTemplates() { console.log('📋 测试1: 获取所有预设模板'); console.log('GET /api/v1/batch/templates\n'); try { const response = await axios.get(`${BASE_URL}/batch/templates`); console.log('✅ 成功'); console.log('返回数据:', JSON.stringify(response.data, null, 2)); console.log('\n' + '='.repeat(60) + '\n'); return response.data.data; } catch (error) { console.error('❌ 失败:', error.response?.data || error.message); console.log('\n' + '='.repeat(60) + '\n'); return null; } } // 测试2: 执行批处理任务(需要真实的知识库和文档ID) async function testExecuteBatch(kbId, documentIds) { console.log('📦 测试2: 执行批处理任务'); console.log('POST /api/v1/batch/execute\n'); const requestData = { kb_id: kbId, document_ids: documentIds, template_type: 'preset', template_id: 'clinical_research', model_type: 'deepseek-v3', task_name: '批处理测试任务', }; console.log('请求数据:', JSON.stringify(requestData, null, 2)); try { const response = await axios.post(`${BASE_URL}/batch/execute`, requestData); console.log('\n✅ 成功'); console.log('返回数据:', JSON.stringify(response.data, null, 2)); console.log('\n' + '='.repeat(60) + '\n'); return response.data; } catch (error) { console.error('❌ 失败:', error.response?.data || error.message); console.log('\n' + '='.repeat(60) + '\n'); return null; } } // 测试3: 获取任务状态 async function testGetTask(taskId) { console.log('📊 测试3: 获取任务状态'); console.log(`GET /api/v1/batch/tasks/${taskId}\n`); try { const response = await axios.get(`${BASE_URL}/batch/tasks/${taskId}`); console.log('✅ 成功'); console.log('返回数据:', JSON.stringify(response.data, null, 2)); console.log('\n' + '='.repeat(60) + '\n'); return response.data.data; } catch (error) { console.error('❌ 失败:', error.response?.data || error.message); console.log('\n' + '='.repeat(60) + '\n'); return null; } } // 测试4: 获取任务结果 async function testGetTaskResults(taskId) { console.log('📄 测试4: 获取任务结果'); console.log(`GET /api/v1/batch/tasks/${taskId}/results\n`); try { const response = await axios.get(`${BASE_URL}/batch/tasks/${taskId}/results`); console.log('✅ 成功'); console.log('任务信息:', JSON.stringify(response.data.data.task, null, 2)); console.log(`\n结果数量: ${response.data.data.results.length}`); // 显示前3个结果的摘要 console.log('\n前3个结果摘要:'); response.data.data.results.slice(0, 3).forEach((r, i) => { console.log(`\n结果 ${i + 1}:`); console.log(` - 文档: ${r.document_name}`); console.log(` - 状态: ${r.status}`); console.log(` - 处理时间: ${r.processing_time_ms}ms`); if (r.status === 'success' && r.data) { console.log(` - 数据字段:`, Object.keys(r.data).join(', ')); } if (r.error_message) { console.log(` - 错误: ${r.error_message}`); } }); console.log('\n' + '='.repeat(60) + '\n'); return response.data.data; } catch (error) { console.error('❌ 失败:', error.response?.data || error.message); console.log('\n' + '='.repeat(60) + '\n'); return null; } } // 测试5: 重试失败的文档 async function testRetryFailed(taskId) { console.log('🔄 测试5: 重试失败的文档'); console.log(`POST /api/v1/batch/tasks/${taskId}/retry-failed\n`); try { const response = await axios.post(`${BASE_URL}/batch/tasks/${taskId}/retry-failed`); console.log('✅ 成功'); console.log('返回数据:', JSON.stringify(response.data, null, 2)); console.log('\n' + '='.repeat(60) + '\n'); return response.data; } catch (error) { console.error('❌ 失败:', error.response?.data || error.message); console.log('\n' + '='.repeat(60) + '\n'); return null; } } // 主测试流程 async function main() { console.log('🧪 Phase 3 批处理API测试\n'); console.log('='.repeat(60)); console.log('测试服务器: ' + BASE_URL); console.log('='.repeat(60) + '\n'); // 等待服务器启动 const serverReady = await waitForServer(); if (!serverReady) { process.exit(1); } // 测试1: 获取模板 const templates = await testGetTemplates(); // 检查是否有测试数据 console.log('⚠️ 测试2-5需要真实的知识库和文档数据\n'); console.log('请手动提供以下信息来继续测试:\n'); console.log('示例命令:'); console.log('node test-batch-api.js <知识库ID> <文档ID1> <文档ID2> <文档ID3>\n'); const args = process.argv.slice(2); if (args.length < 4) { console.log('📝 跳过测试2-5(需要提供知识库ID和至少3个文档ID)\n'); console.log('✅ 测试1完成!'); return; } const kbId = args[0]; const documentIds = args.slice(1); console.log(`\n📌 使用测试数据:`); console.log(` 知识库ID: ${kbId}`); console.log(` 文档数量: ${documentIds.length}`); console.log(` 文档IDs: ${documentIds.slice(0, 3).join(', ')}${documentIds.length > 3 ? '...' : ''}\n`); console.log('='.repeat(60) + '\n'); // 测试2: 执行批处理 const executeResult = await testExecuteBatch(kbId, documentIds); if (!executeResult || !executeResult.data || !executeResult.data.task_id) { console.log('❌ 批处理任务创建失败或未返回task_id,停止测试'); return; } const taskId = executeResult.data.task_id; console.log(`✅ 获取到任务ID: ${taskId}\n`); // 等待一段时间让任务开始执行 console.log('⏳ 等待5秒让任务开始执行...\n'); await new Promise(resolve => setTimeout(resolve, 5000)); // 测试3: 获取任务状态 const taskStatus = await testGetTask(taskId); // 等待任务完成(最多等待2分钟) if (taskStatus && taskStatus.status === 'processing') { console.log('⏳ 任务仍在处理中,等待完成(最多2分钟)...\n'); for (let i = 0; i < 24; i++) { // 24次 * 5秒 = 2分钟 await new Promise(resolve => setTimeout(resolve, 5000)); const currentStatus = await testGetTask(taskId); if (currentStatus && currentStatus.status !== 'processing') { console.log(`✅ 任务已完成,状态: ${currentStatus.status}\n`); break; } console.log(`⏳ 仍在处理中... (${currentStatus.completed_count}/${currentStatus.total_documents})\n`); } } // 测试4: 获取任务结果 const taskResults = await testGetTaskResults(taskId); // 测试5: 重试失败的文档(如果有失败的) if (taskResults && taskResults.task.failed_count > 0) { console.log(`\n⚠️ 发现 ${taskResults.task.failed_count} 个失败的文档,测试重试功能\n`); await testRetryFailed(taskId); } else { console.log('\n✅ 所有文档处理成功,跳过重试测试\n'); } console.log('🎉 所有API测试完成!'); } // 运行测试 main().catch(error => { console.error('💥 测试执行失败:', error); process.exit(1); });