Files
ccdi/doc/test-data/purchase_transaction/test-import-debug.js
2026-02-09 14:34:27 +08:00

270 lines
8.4 KiB
JavaScript

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);