504 lines
19 KiB
JavaScript
504 lines
19 KiB
JavaScript
const request = require('supertest');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// 测试基础URL
|
|
const BASE_URL = 'http://localhost:3005';
|
|
|
|
// 测试文件路径
|
|
const TEST_IMAGE_PATH = path.join(__dirname, 'uploads', 'test-image.png');
|
|
|
|
// 确保测试文件存在
|
|
if (!fs.existsSync(TEST_IMAGE_PATH)) {
|
|
console.log('测试文件不存在,创建模拟测试文件...');
|
|
if (!fs.existsSync(path.join(__dirname, 'uploads'))) {
|
|
fs.mkdirSync(path.join(__dirname, 'uploads'), { recursive: true });
|
|
}
|
|
// 创建一个简单的文本文件作为测试附件
|
|
fs.writeFileSync(TEST_IMAGE_PATH, 'Test image content');
|
|
console.log('测试文件创建成功');
|
|
}
|
|
|
|
// 测试数据
|
|
const testUser = {
|
|
username: 'admin',
|
|
password: 'X123c321@'
|
|
};
|
|
|
|
let authToken = '';
|
|
|
|
// 测试结果
|
|
const testResults = [];
|
|
|
|
// 登录函数
|
|
async function login() {
|
|
console.log('\n🔐 登录测试...');
|
|
const response = await request(BASE_URL)
|
|
.post('/api/auth/login')
|
|
.send(testUser);
|
|
|
|
if (response.status === 200 && response.body.success) {
|
|
authToken = response.body.token;
|
|
testResults.push({ test: '登录', status: '✅ 成功' });
|
|
console.log('✅ 登录成功,获取到token');
|
|
} else {
|
|
testResults.push({ test: '登录', status: '❌ 失败', message: response.body.message || '登录失败' });
|
|
console.log('❌ 登录失败:', response.body.message);
|
|
}
|
|
}
|
|
|
|
// 测试预支申请流程
|
|
async function testAdvanceFlow() {
|
|
console.log('\n💸 测试预支申请流程...');
|
|
let advanceId = '';
|
|
|
|
// 1. 创建预支申请
|
|
console.log('1. 创建预支申请...');
|
|
const createResponse = await request(BASE_URL)
|
|
.post('/api/advances')
|
|
.set('Authorization', `Bearer ${authToken}`)
|
|
.field('advance_date', '2026-03-24')
|
|
.field('amount', 5000)
|
|
.field('currency', 'CNY')
|
|
.field('reason', '项目差旅预支')
|
|
.field('expense_type', 'project')
|
|
.field('project_id', '1')
|
|
.field('applicant', '测试用户')
|
|
.attach('attachments', TEST_IMAGE_PATH);
|
|
|
|
if (createResponse.status === 200 && createResponse.body.success) {
|
|
advanceId = createResponse.body.data.id;
|
|
testResults.push({ test: '创建预支申请', status: '✅ 成功' });
|
|
console.log('✅ 预支申请创建成功,ID:', advanceId);
|
|
} else {
|
|
testResults.push({ test: '创建预支申请', status: '❌ 失败', message: createResponse.body.message || '创建失败' });
|
|
console.log('❌ 预支申请创建失败:', createResponse.body.message);
|
|
return;
|
|
}
|
|
|
|
// 2. 提交预支申请
|
|
console.log('2. 提交预支申请...');
|
|
const submitResponse = await request(BASE_URL)
|
|
.put(`/api/advances/${advanceId}/submit`)
|
|
.set('Authorization', `Bearer ${authToken}`);
|
|
|
|
if (submitResponse.status === 200 && submitResponse.body.success) {
|
|
testResults.push({ test: '提交预支申请', status: '✅ 成功' });
|
|
console.log('✅ 预支申请提交成功');
|
|
} else {
|
|
testResults.push({ test: '提交预支申请', status: '❌ 失败', message: submitResponse.body.message || '提交失败' });
|
|
console.log('❌ 预支申请提交失败:', submitResponse.body.message);
|
|
return;
|
|
}
|
|
|
|
// 3. 审批预支申请
|
|
console.log('3. 审批预支申请...');
|
|
const approveResponse = await request(BASE_URL)
|
|
.put(`/api/advances/${advanceId}/approve`)
|
|
.set('Authorization', `Bearer ${authToken}`)
|
|
.send({ approver: '系统管理员' });
|
|
|
|
if (approveResponse.status === 200 && approveResponse.body.success) {
|
|
testResults.push({ test: '审批预支申请', status: '✅ 成功' });
|
|
console.log('✅ 预支申请审批成功');
|
|
} else {
|
|
testResults.push({ test: '审批预支申请', status: '❌ 失败', message: approveResponse.body.message || '审批失败' });
|
|
console.log('❌ 预支申请审批失败:', approveResponse.body.message);
|
|
return;
|
|
}
|
|
|
|
// 4. 执行预支付款
|
|
console.log('4. 执行预支付款...');
|
|
const executeResponse = await request(BASE_URL)
|
|
.post('/api/executions')
|
|
.set('Authorization', `Bearer ${authToken}`)
|
|
.send({
|
|
apply_id: advanceId,
|
|
apply_type: 'advance',
|
|
action: 'execute',
|
|
execute_method: '银行转账',
|
|
voucher_no: 'VCH' + Date.now(),
|
|
remark: '测试执行'
|
|
});
|
|
|
|
if (executeResponse.status === 200 && executeResponse.body.success) {
|
|
testResults.push({ test: '执行预支付款', status: '✅ 成功' });
|
|
console.log('✅ 预支付款执行成功');
|
|
} else {
|
|
testResults.push({ test: '执行预支付款', status: '❌ 失败', message: executeResponse.body.message || '执行失败' });
|
|
console.log('❌ 预支付款执行失败:', executeResponse.body.message);
|
|
}
|
|
}
|
|
|
|
// 测试报销申请流程
|
|
async function testReimbursementFlow() {
|
|
console.log('\n🧾 测试报销申请流程...');
|
|
let reimbursementId = '';
|
|
|
|
// 1. 创建报销申请
|
|
console.log('1. 创建报销申请...');
|
|
const createResponse = await request(BASE_URL)
|
|
.post('/api/reimbursements')
|
|
.set('Authorization', `Bearer ${authToken}`)
|
|
.field('reimbursement_date', '2026-03-24')
|
|
.field('amount', 3500)
|
|
.field('currency', 'CNY')
|
|
.field('reason', '项目差旅报销')
|
|
.field('expense_type', 'project')
|
|
.field('project_id', '1')
|
|
.field('applicant', '测试用户')
|
|
.field('detail_items', JSON.stringify([
|
|
{
|
|
description: '住宿费',
|
|
amount: 2000,
|
|
category: 'accommodation',
|
|
attachments: []
|
|
},
|
|
{
|
|
description: '餐饮费',
|
|
amount: 1500,
|
|
category: 'food',
|
|
attachments: []
|
|
}
|
|
]))
|
|
.attach('attachments', TEST_IMAGE_PATH);
|
|
|
|
if (createResponse.status === 200 && createResponse.body.success) {
|
|
reimbursementId = createResponse.body.data.id;
|
|
testResults.push({ test: '创建报销申请', status: '✅ 成功' });
|
|
console.log('✅ 报销申请创建成功,ID:', reimbursementId);
|
|
} else {
|
|
testResults.push({ test: '创建报销申请', status: '❌ 失败', message: createResponse.body.message || '创建失败' });
|
|
console.log('❌ 报销申请创建失败:', createResponse.body.message);
|
|
return;
|
|
}
|
|
|
|
// 2. 提交报销申请
|
|
console.log('2. 提交报销申请...');
|
|
const submitResponse = await request(BASE_URL)
|
|
.put(`/api/reimbursements/${reimbursementId}/submit`)
|
|
.set('Authorization', `Bearer ${authToken}`);
|
|
|
|
if (submitResponse.status === 200 && submitResponse.body.success) {
|
|
testResults.push({ test: '提交报销申请', status: '✅ 成功' });
|
|
console.log('✅ 报销申请提交成功');
|
|
} else {
|
|
testResults.push({ test: '提交报销申请', status: '❌ 失败', message: submitResponse.body.message || '提交失败' });
|
|
console.log('❌ 报销申请提交失败:', submitResponse.body.message);
|
|
return;
|
|
}
|
|
|
|
// 3. 审批报销申请
|
|
console.log('3. 审批报销申请...');
|
|
const approveResponse = await request(BASE_URL)
|
|
.put(`/api/reimbursements/${reimbursementId}/approve`)
|
|
.set('Authorization', `Bearer ${authToken}`)
|
|
.send({ approver: '系统管理员' });
|
|
|
|
if (approveResponse.status === 200 && approveResponse.body.success) {
|
|
testResults.push({ test: '审批报销申请', status: '✅ 成功' });
|
|
console.log('✅ 报销申请审批成功');
|
|
} else {
|
|
testResults.push({ test: '审批报销申请', status: '❌ 失败', message: approveResponse.body.message || '审批失败' });
|
|
console.log('❌ 报销申请审批失败:', approveResponse.body.message);
|
|
return;
|
|
}
|
|
|
|
// 4. 执行报销付款
|
|
console.log('4. 执行报销付款...');
|
|
const executeResponse = await request(BASE_URL)
|
|
.post('/api/executions')
|
|
.set('Authorization', `Bearer ${authToken}`)
|
|
.send({
|
|
apply_id: reimbursementId,
|
|
apply_type: 'reimbursement',
|
|
action: 'execute',
|
|
execute_method: '银行转账',
|
|
voucher_no: 'VCH' + Date.now(),
|
|
remark: '测试执行'
|
|
});
|
|
|
|
if (executeResponse.status === 200 && executeResponse.body.success) {
|
|
testResults.push({ test: '执行报销付款', status: '✅ 成功' });
|
|
console.log('✅ 报销付款执行成功');
|
|
} else {
|
|
testResults.push({ test: '执行报销付款', status: '❌ 失败', message: executeResponse.body.message || '执行失败' });
|
|
console.log('❌ 报销付款执行失败:', executeResponse.body.message);
|
|
}
|
|
}
|
|
|
|
// 测试付款申请流程
|
|
async function testPaymentFlow() {
|
|
console.log('\n💰 测试付款申请流程...');
|
|
let paymentId = '';
|
|
|
|
// 1. 创建付款申请
|
|
console.log('1. 创建付款申请...');
|
|
const createResponse = await request(BASE_URL)
|
|
.post('/api/payments')
|
|
.set('Authorization', `Bearer ${authToken}`)
|
|
.field('payment_date', '2026-03-24')
|
|
.field('amount', 50000)
|
|
.field('currency', 'CNY')
|
|
.field('reason', '设备采购款')
|
|
.field('expense_type', 'company')
|
|
.field('payee', '测试供应商')
|
|
.field('applicant', '测试用户')
|
|
.attach('attachments', TEST_IMAGE_PATH);
|
|
|
|
if (createResponse.status === 200 && createResponse.body.success) {
|
|
paymentId = createResponse.body.data.id;
|
|
testResults.push({ test: '创建付款申请', status: '✅ 成功' });
|
|
console.log('✅ 付款申请创建成功,ID:', paymentId);
|
|
} else {
|
|
testResults.push({ test: '创建付款申请', status: '❌ 失败', message: createResponse.body.message || '创建失败' });
|
|
console.log('❌ 付款申请创建失败:', createResponse.body.message);
|
|
return;
|
|
}
|
|
|
|
// 2. 提交付款申请
|
|
console.log('2. 提交付款申请...');
|
|
const submitResponse = await request(BASE_URL)
|
|
.put(`/api/payments/${paymentId}/submit`)
|
|
.set('Authorization', `Bearer ${authToken}`);
|
|
|
|
if (submitResponse.status === 200 && submitResponse.body.success) {
|
|
testResults.push({ test: '提交付款申请', status: '✅ 成功' });
|
|
console.log('✅ 付款申请提交成功');
|
|
} else {
|
|
testResults.push({ test: '提交付款申请', status: '❌ 失败', message: submitResponse.body.message || '提交失败' });
|
|
console.log('❌ 付款申请提交失败:', submitResponse.body.message);
|
|
return;
|
|
}
|
|
|
|
// 3. 审批付款申请
|
|
console.log('3. 审批付款申请...');
|
|
const approveResponse = await request(BASE_URL)
|
|
.put(`/api/payments/${paymentId}/approve`)
|
|
.set('Authorization', `Bearer ${authToken}`)
|
|
.send({ approver: '系统管理员' });
|
|
|
|
if (approveResponse.status === 200 && approveResponse.body.success) {
|
|
testResults.push({ test: '审批付款申请', status: '✅ 成功' });
|
|
console.log('✅ 付款申请审批成功');
|
|
} else {
|
|
testResults.push({ test: '审批付款申请', status: '❌ 失败', message: approveResponse.body.message || '审批失败' });
|
|
console.log('❌ 付款申请审批失败:', approveResponse.body.message);
|
|
return;
|
|
}
|
|
|
|
// 4. 执行付款
|
|
console.log('4. 执行付款...');
|
|
const executeResponse = await request(BASE_URL)
|
|
.post('/api/executions')
|
|
.set('Authorization', `Bearer ${authToken}`)
|
|
.send({
|
|
apply_id: paymentId,
|
|
apply_type: 'payment',
|
|
action: 'execute',
|
|
execute_method: '银行转账',
|
|
voucher_no: 'VCH' + Date.now(),
|
|
remark: '测试执行'
|
|
});
|
|
|
|
if (executeResponse.status === 200 && executeResponse.body.success) {
|
|
testResults.push({ test: '执行付款', status: '✅ 成功' });
|
|
console.log('✅ 付款执行成功');
|
|
} else {
|
|
testResults.push({ test: '执行付款', status: '❌ 失败', message: executeResponse.body.message || '执行失败' });
|
|
console.log('❌ 付款执行失败:', executeResponse.body.message);
|
|
}
|
|
}
|
|
|
|
// 测试核销申请流程
|
|
async function testVerificationFlow() {
|
|
console.log('\n📋 测试核销申请流程...');
|
|
let verificationId = '';
|
|
|
|
// 1. 创建核销申请
|
|
console.log('1. 创建核销申请...');
|
|
const createResponse = await request(BASE_URL)
|
|
.post('/api/verifications')
|
|
.set('Authorization', `Bearer ${authToken}`)
|
|
.field('verification_date', '2026-03-24')
|
|
.field('advance_id', '1')
|
|
.field('actual_amount', 4500)
|
|
.field('balance', 500)
|
|
.field('reason', '项目差旅核销')
|
|
.field('applicant', '测试用户')
|
|
.field('detail_items', JSON.stringify([
|
|
{
|
|
description: '住宿费',
|
|
amount: 2500,
|
|
category: 'accommodation',
|
|
attachments: []
|
|
},
|
|
{
|
|
description: '餐饮费',
|
|
amount: 2000,
|
|
category: 'food',
|
|
attachments: []
|
|
}
|
|
]))
|
|
.attach('attachments', TEST_IMAGE_PATH);
|
|
|
|
if (createResponse.status === 200 && createResponse.body.success) {
|
|
verificationId = createResponse.body.data.id;
|
|
testResults.push({ test: '创建核销申请', status: '✅ 成功' });
|
|
console.log('✅ 核销申请创建成功,ID:', verificationId);
|
|
} else {
|
|
testResults.push({ test: '创建核销申请', status: '❌ 失败', message: createResponse.body.message || '创建失败' });
|
|
console.log('❌ 核销申请创建失败:', createResponse.body.message);
|
|
return;
|
|
}
|
|
|
|
// 2. 提交核销申请
|
|
console.log('2. 提交核销申请...');
|
|
const submitResponse = await request(BASE_URL)
|
|
.put(`/api/verifications/${verificationId}/submit`)
|
|
.set('Authorization', `Bearer ${authToken}`);
|
|
|
|
if (submitResponse.status === 200 && submitResponse.body.success) {
|
|
testResults.push({ test: '提交核销申请', status: '✅ 成功' });
|
|
console.log('✅ 核销申请提交成功');
|
|
} else {
|
|
testResults.push({ test: '提交核销申请', status: '❌ 失败', message: submitResponse.body.message || '提交失败' });
|
|
console.log('❌ 核销申请提交失败:', submitResponse.body.message);
|
|
return;
|
|
}
|
|
|
|
// 3. 审批核销申请
|
|
console.log('3. 审批核销申请...');
|
|
const approveResponse = await request(BASE_URL)
|
|
.put(`/api/verifications/${verificationId}/approve`)
|
|
.set('Authorization', `Bearer ${authToken}`)
|
|
.send({ approver: '系统管理员' });
|
|
|
|
if (approveResponse.status === 200 && approveResponse.body.success) {
|
|
testResults.push({ test: '审批核销申请', status: '✅ 成功' });
|
|
console.log('✅ 核销申请审批成功');
|
|
} else {
|
|
testResults.push({ test: '审批核销申请', status: '❌ 失败', message: approveResponse.body.message || '审批失败' });
|
|
console.log('❌ 核销申请审批失败:', approveResponse.body.message);
|
|
return;
|
|
}
|
|
|
|
// 4. 执行核销
|
|
console.log('4. 执行核销...');
|
|
const executeResponse = await request(BASE_URL)
|
|
.post('/api/executions')
|
|
.set('Authorization', `Bearer ${authToken}`)
|
|
.send({
|
|
apply_id: verificationId,
|
|
apply_type: 'verification',
|
|
action: 'execute',
|
|
execute_method: '银行转账',
|
|
voucher_no: 'VCH' + Date.now(),
|
|
remark: '测试执行'
|
|
});
|
|
|
|
if (executeResponse.status === 200 && executeResponse.body.success) {
|
|
testResults.push({ test: '执行核销', status: '✅ 成功' });
|
|
console.log('✅ 核销执行成功');
|
|
} else {
|
|
testResults.push({ test: '执行核销', status: '❌ 失败', message: executeResponse.body.message || '执行失败' });
|
|
console.log('❌ 核销执行失败:', executeResponse.body.message);
|
|
}
|
|
}
|
|
|
|
// 测试执行记录查询
|
|
async function testExecutionRecords() {
|
|
console.log('\n📊 测试执行记录查询...');
|
|
|
|
// 1. 查询执行记录列表
|
|
console.log('1. 查询执行记录列表...');
|
|
const recordsResponse = await request(BASE_URL)
|
|
.get('/api/executions')
|
|
.set('Authorization', `Bearer ${authToken}`);
|
|
|
|
if (recordsResponse.status === 200 && recordsResponse.body.success) {
|
|
testResults.push({ test: '查询执行记录列表', status: '✅ 成功', message: `找到 ${recordsResponse.body.data.length} 条记录` });
|
|
console.log('✅ 执行记录查询成功,找到', recordsResponse.body.data.length, '条记录');
|
|
} else {
|
|
testResults.push({ test: '查询执行记录列表', status: '❌ 失败', message: recordsResponse.body.message || '查询失败' });
|
|
console.log('❌ 执行记录查询失败:', recordsResponse.body.message);
|
|
}
|
|
|
|
// 2. 查询待执行列表
|
|
console.log('2. 查询待执行列表...');
|
|
const pendingResponse = await request(BASE_URL)
|
|
.get('/api/executions/pending')
|
|
.set('Authorization', `Bearer ${authToken}`);
|
|
|
|
if (pendingResponse.status === 200 && pendingResponse.body.success) {
|
|
testResults.push({ test: '查询待执行列表', status: '✅ 成功', message: `找到 ${pendingResponse.body.data.length} 条记录` });
|
|
console.log('✅ 待执行列表查询成功,找到', pendingResponse.body.data.length, '条记录');
|
|
} else {
|
|
testResults.push({ test: '查询待执行列表', status: '❌ 失败', message: pendingResponse.body.message || '查询失败' });
|
|
console.log('❌ 待执行列表查询失败:', pendingResponse.body.message);
|
|
}
|
|
|
|
// 3. 查询已执行列表
|
|
console.log('3. 查询已执行列表...');
|
|
const executedResponse = await request(BASE_URL)
|
|
.get('/api/executions/executed')
|
|
.set('Authorization', `Bearer ${authToken}`);
|
|
|
|
if (executedResponse.status === 200 && executedResponse.body.success) {
|
|
testResults.push({ test: '查询已执行列表', status: '✅ 成功', message: `找到 ${executedResponse.body.data.length} 条记录` });
|
|
console.log('✅ 已执行列表查询成功,找到', executedResponse.body.data.length, '条记录');
|
|
} else {
|
|
testResults.push({ test: '查询已执行列表', status: '❌ 失败', message: executedResponse.body.message || '查询失败' });
|
|
console.log('❌ 已执行列表查询失败:', executedResponse.body.message);
|
|
}
|
|
}
|
|
|
|
// 运行所有测试
|
|
async function runAllTests() {
|
|
console.log('🚀 开始执行完整财务流程测试\n');
|
|
|
|
await login();
|
|
|
|
if (authToken) {
|
|
await testAdvanceFlow();
|
|
await testReimbursementFlow();
|
|
await testPaymentFlow();
|
|
await testVerificationFlow();
|
|
await testExecutionRecords();
|
|
}
|
|
|
|
// 输出测试结果
|
|
console.log('\n📋 测试结果汇总:');
|
|
console.log('=============================================');
|
|
|
|
let successCount = 0;
|
|
let failureCount = 0;
|
|
|
|
testResults.forEach(result => {
|
|
console.log(`${result.test}: ${result.status}`);
|
|
if (result.status.includes('✅')) {
|
|
successCount++;
|
|
} else {
|
|
failureCount++;
|
|
}
|
|
});
|
|
|
|
console.log('=============================================');
|
|
console.log(`总测试数: ${testResults.length}`);
|
|
console.log(`成功: ${successCount}`);
|
|
console.log(`失败: ${failureCount}`);
|
|
|
|
if (failureCount === 0) {
|
|
console.log('\n🎉 所有测试通过!完整财务流程运行正常。');
|
|
} else {
|
|
console.log('\n⚠️ 部分测试失败,需要检查问题。');
|
|
}
|
|
|
|
console.log('\n测试完成。');
|
|
}
|
|
|
|
// 启动测试
|
|
runAllTests().catch(error => {
|
|
console.error('测试过程中出现错误:', error);
|
|
});
|