270 lines
8.4 KiB
JavaScript
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);
|