const axios = require('axios'); const fs = require('fs'); const path = require('path'); const FormData = require('form-data'); // 配置 const BASE_URL = 'http://localhost:8080'; const LOGIN_URL = `${BASE_URL}/login/test`; const IMPORT_URL = `${BASE_URL}/ccdi/purchaseTransaction/importData`; const STATUS_URL_TEMPLATE = `${BASE_URL}/ccdi/purchaseTransaction/importStatus`; const FAILURES_URL_TEMPLATE = `${BASE_URL}/ccdi/purchaseTransaction/importFailures`; // 测试账号 const USERNAME = 'admin'; const PASSWORD = 'admin123'; // 测试文件 const TEST_FILE = path.join(__dirname, 'purchase_test_data_2000_v2.xlsx'); /** * 登录获取token */ async function login() { try { console.log('正在登录...'); const response = await axios.post(LOGIN_URL, { username: USERNAME, password: PASSWORD }); if (response.data.code === 200) { console.log('✓ 登录成功'); return response.data.token; } else { throw new Error(`登录失败: ${response.data.msg}`); } } catch (error) { console.error('✗ 登录异常:', error.message); throw error; } } /** * 导入数据 */ async function importData(token, updateSupport = false) { try { console.log('\n========================================'); console.log('开始导入测试'); console.log('========================================'); console.log(`文件: ${TEST_FILE}`); console.log(`更新支持: ${updateSupport}`); // 检查文件是否存在 if (!fs.existsSync(TEST_FILE)) { throw new Error(`测试文件不存在: ${TEST_FILE}`); } // 创建form-data const formData = new FormData(); formData.append('file', fs.createReadStream(TEST_FILE)); console.log('\n正在上传文件...'); const response = await axios.post( `${IMPORT_URL}?updateSupport=${updateSupport}`, formData, { headers: { ...formData.getHeaders(), 'Authorization': `Bearer ${token}` } } ); console.log('\n响应状态:', response.status); console.log('响应数据:', JSON.stringify(response.data, null, 2)); if (response.data.code === 200) { console.log('\n✓ 导入任务已提交'); return response.data.data.taskId; } else { throw new Error(`导入失败: ${response.data.msg}`); } } catch (error) { console.error('\n✗ 导入异常:', error.message); if (error.response) { console.error('响应数据:', JSON.stringify(error.response.data, null, 2)); } throw error; } } /** * 查询导入状态 */ async function getImportStatus(token, taskId) { try { console.log(`\n查询导入状态 (taskId: ${taskId})...`); const response = await axios.get( `${STATUS_URL_TEMPLATE}/${taskId}`, { headers: { 'Authorization': `Bearer ${token}` } } ); console.log('导入状态:', JSON.stringify(response.data, null, 2)); if (response.data.code === 200) { return response.data.data; } else { throw new Error(`查询状态失败: ${response.data.msg}`); } } catch (error) { console.error('✗ 查询状态异常:', error.message); if (error.response) { console.error('响应数据:', JSON.stringify(error.response.data, null, 2)); } throw error; } } /** * 查询失败记录 */ async function getImportFailures(token, taskId) { try { console.log(`\n查询失败记录 (taskId: ${taskId})...`); const response = await axios.get( `${FAILURES_URL_TEMPLATE}/${taskId}`, { headers: { 'Authorization': `Bearer ${token}` } } ); console.log('失败记录数量:', response.data.total || response.data.data?.length); console.log('失败记录:', JSON.stringify(response.data, null, 2)); if (response.data.code === 200) { return response.data.data || response.data.rows; } else { throw new Error(`查询失败记录失败: ${response.data.msg}`); } } catch (error) { console.error('✗ 查询失败记录异常:', error.message); if (error.response) { console.error('响应数据:', JSON.stringify(error.response.data, null, 2)); } throw error; } } /** * 轮询导入状态 */ async function pollImportStatus(token, taskId, maxPolls = 30) { let pollCount = 0; const interval = 2000; // 2秒 console.log(`\n开始轮询导入状态 (最多${maxPolls}次, 间隔${interval}ms)...`); return new Promise((resolve, reject) => { const timer = setInterval(async () => { pollCount++; try { const status = await getImportStatus(token, taskId); console.log(`\n[轮询 ${pollCount}/${maxPolls}] 状态: ${status.status}`); if (status.status !== 'PROCESSING' && status.status !== 'PENDING' && status.status !== 'RUNNING') { clearInterval(timer); console.log('\n✓ 导入完成!'); resolve(status); } else if (pollCount >= maxPolls) { clearInterval(timer); reject(new Error('轮询超时')); } } catch (error) { clearInterval(timer); reject(error); } }, interval); }); } /** * 主函数 */ async function main() { let token; let taskId; try { // 登录 token = await login(); // 导入数据 taskId = await importData(token, false); // 轮询状态 const finalStatus = await pollImportStatus(token, taskId); console.log('\n========================================'); console.log('最终导入结果'); console.log('========================================'); console.log('状态:', finalStatus.status); console.log('总数:', finalStatus.totalCount); console.log('成功:', finalStatus.successCount); console.log('失败:', finalStatus.failureCount); console.log('消息:', finalStatus.message); // 如果有失败记录,查询失败记录 if (finalStatus.failureCount > 0) { console.log('\n有失败记录,正在查询...'); const failures = await getImportFailures(token, taskId); console.log('\n========================================'); console.log('失败记录详情'); console.log('========================================'); console.log(`失败记录数: ${failures.length}`); // 显示前10条失败记录 const displayCount = Math.min(10, failures.length); console.log(`\n前${displayCount}条失败记录:`); for (let i = 0; i < displayCount; i++) { const failure = failures[i]; console.log(`\n[${i + 1}] 采购事项ID: ${failure.purchaseId}`); console.log(` 项目名称: ${failure.projectName || '(空)'}`); console.log(` 标的物名称: ${failure.subjectName || '(空)'}`); console.log(` 失败原因: ${failure.errorMessage}`); } if (failures.length > displayCount) { console.log(`\n... 还有 ${failures.length - displayCount} 条失败记录`); } // 统计失败原因 const errorReasons = {}; failures.forEach(f => { const reason = f.errorMessage; errorReasons[reason] = (errorReasons[reason] || 0) + 1; }); console.log('\n失败原因统计:'); Object.entries(errorReasons) .sort((a, b) => b[1] - a[1]) .forEach(([reason, count]) => { console.log(` ${reason}: ${count}条`); }); } else { console.log('\n✓ 全部导入成功,无失败记录'); } } catch (error) { console.error('\n✗ 测试失败:', error.message); process.exit(1); } } // 运行测试 main().catch(console.error);