问题: - 导入成功条数显示为负数 - 原因:成功数量计算使用 validRecords.size() - failures.size() - 但没有使用实际的数据库操作返回值 修复: - saveBatchWithUpsert 和 saveBatch 方法现在返回 int - 累加实际的数据库影响行数 - 使用 actualSuccessCount 变量跟踪真实成功数量 影响范围: - CcdiIntermediaryPersonImportServiceImpl - CcdiIntermediaryEntityImportServiceImpl
227 lines
10 KiB
JavaScript
227 lines
10 KiB
JavaScript
const Excel = require('exceljs');
|
||
|
||
// 配置
|
||
const OUTPUT_FILE = 'purchase_test_data_2000_v2.xlsx';
|
||
const RECORD_COUNT = 2000;
|
||
|
||
// 数据池
|
||
const PURCHASE_CATEGORIES = ['货物类', '工程类', '服务类', '软件系统', '办公设备', '家具用具', '专用设备', '通讯设备'];
|
||
const PURCHASE_METHODS = ['公开招标', '邀请招标', '询价采购', '单一来源', '竞争性谈判'];
|
||
const DEPARTMENTS = ['人事部', '行政部', '财务部', '技术部', '市场部', '采购部', '研发部'];
|
||
const EMPLOYEES = [
|
||
{ id: 'EMP0001', name: '张伟' },
|
||
{ id: 'EMP0002', name: '王芳' },
|
||
{ id: 'EMP0003', name: '李娜' },
|
||
{ id: 'EMP0004', name: '刘洋' },
|
||
{ id: 'EMP0005', name: '陈静' },
|
||
{ id: 'EMP0006', name: '杨强' },
|
||
{ id: 'EMP0007', name: '赵敏' },
|
||
{ id: 'EMP0008', name: '孙杰' },
|
||
{ id: 'EMP0009', name: '周涛' },
|
||
{ id: 'EMP0010', name: '吴刚' },
|
||
{ id: 'EMP0011', name: '郑丽' },
|
||
{ id: 'EMP0012', name: '钱勇' },
|
||
{ id: 'EMP0013', name: '何静' },
|
||
{ id: 'EMP0014', name: '朱涛' },
|
||
{ id: 'EMP0015', name: '马超' }
|
||
];
|
||
|
||
// 生成随机整数
|
||
function randomInt(min, max) {
|
||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||
}
|
||
|
||
// 生成随机浮点数
|
||
function randomFloat(min, max, decimals = 2) {
|
||
const num = Math.random() * (max - min) + min;
|
||
return parseFloat(num.toFixed(decimals));
|
||
}
|
||
|
||
// 从数组中随机选择
|
||
function randomChoice(arr) {
|
||
return arr[Math.floor(Math.random() * arr.length)];
|
||
}
|
||
|
||
// 生成随机日期
|
||
function randomDate(start, end) {
|
||
return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
|
||
}
|
||
|
||
// 生成采购事项ID
|
||
function generatePurchaseId(index) {
|
||
const timestamp = Date.now();
|
||
const num = String(index + 1).padStart(4, '0');
|
||
return `PUR${timestamp}${num}`;
|
||
}
|
||
|
||
// 生成测试数据
|
||
function generateTestData(count) {
|
||
const data = [];
|
||
const startDate = new Date('2023-01-01');
|
||
const endDate = new Date('2025-12-31');
|
||
|
||
for (let i = 0; i < count; i++) {
|
||
const purchaseQty = randomFloat(1, 5000, 2);
|
||
const unitPrice = randomFloat(100, 50000, 2);
|
||
const budgetAmount = parseFloat((purchaseQty * unitPrice).toFixed(2));
|
||
const discount = randomFloat(0.85, 0.98, 2);
|
||
const actualAmount = parseFloat((budgetAmount * discount).toFixed(2));
|
||
|
||
const employee = randomChoice(EMPLOYEES);
|
||
|
||
// 生成Date对象
|
||
const applyDateObj = randomDate(startDate, endDate);
|
||
|
||
// 生成后续日期(都比申请日期晚)
|
||
const planApproveDate = new Date(applyDateObj);
|
||
planApproveDate.setDate(planApproveDate.getDate() + randomInt(1, 7));
|
||
|
||
const announceDate = new Date(planApproveDate);
|
||
announceDate.setDate(announceDate.getDate() + randomInt(3, 15));
|
||
|
||
const bidOpenDate = new Date(announceDate);
|
||
bidOpenDate.setDate(bidOpenDate.getDate() + randomInt(5, 20));
|
||
|
||
const contractSignDate = new Date(bidOpenDate);
|
||
contractSignDate.setDate(contractSignDate.getDate() + randomInt(3, 10));
|
||
|
||
const expectedDeliveryDate = new Date(contractSignDate);
|
||
expectedDeliveryDate.setDate(expectedDeliveryDate.getDate() + randomInt(15, 60));
|
||
|
||
const actualDeliveryDate = new Date(expectedDeliveryDate);
|
||
actualDeliveryDate.setDate(actualDeliveryDate.getDate() + randomInt(-2, 5));
|
||
|
||
const acceptanceDate = new Date(actualDeliveryDate);
|
||
acceptanceDate.setDate(acceptanceDate.getDate() + randomInt(1, 7));
|
||
|
||
const settlementDate = new Date(acceptanceDate);
|
||
settlementDate.setDate(settlementDate.getDate() + randomInt(7, 30));
|
||
|
||
data.push({
|
||
purchaseId: generatePurchaseId(i),
|
||
purchaseCategory: randomChoice(PURCHASE_CATEGORIES),
|
||
projectName: `${randomChoice(PURCHASE_CATEGORIES)}采购项目-${String(i + 1).padStart(4, '0')}`,
|
||
subjectName: `${randomChoice(PURCHASE_CATEGORIES).replace('类', '')}配件-${String(i + 1).padStart(4, '0')}`,
|
||
subjectDesc: `${randomChoice(PURCHASE_CATEGORIES)}采购项目标的物详细描述-${String(i + 1).padStart(4, '0')}`,
|
||
purchaseQty: purchaseQty,
|
||
budgetAmount: budgetAmount,
|
||
bidAmount: actualAmount,
|
||
actualAmount: actualAmount,
|
||
contractAmount: actualAmount,
|
||
settlementAmount: actualAmount,
|
||
purchaseMethod: randomChoice(PURCHASE_METHODS),
|
||
supplierName: `供应商公司-${String(i + 1).padStart(4, '0')}有限公司`,
|
||
contactPerson: `联系人-${String(i + 1).padStart(4, '0')}`,
|
||
contactPhone: `13${randomInt(0, 9)}${String(randomInt(10000000, 99999999))}`,
|
||
supplierUscc: `91${randomInt(10000000, 99999999)}MA${String(randomInt(1000, 9999))}`,
|
||
supplierBankAccount: `6222${String(randomInt(100000000000000, 999999999999999))}`,
|
||
applyDate: applyDateObj, // Date对象
|
||
planApproveDate: planApproveDate,
|
||
announceDate: announceDate,
|
||
bidOpenDate: bidOpenDate,
|
||
contractSignDate: contractSignDate,
|
||
expectedDeliveryDate: expectedDeliveryDate,
|
||
actualDeliveryDate: actualDeliveryDate,
|
||
acceptanceDate: acceptanceDate,
|
||
settlementDate: settlementDate,
|
||
applicantId: employee.id,
|
||
applicantName: employee.name,
|
||
applyDepartment: randomChoice(DEPARTMENTS),
|
||
purchaseLeaderId: randomChoice(EMPLOYEES).id,
|
||
purchaseLeaderName: randomChoice(EMPLOYEES).name,
|
||
purchaseDepartment: '采购部'
|
||
});
|
||
}
|
||
|
||
return data;
|
||
}
|
||
|
||
// 创建Excel文件
|
||
async function createExcelFile() {
|
||
console.log('开始生成测试数据...');
|
||
console.log(`记录数: ${RECORD_COUNT}`);
|
||
|
||
// 生成测试数据
|
||
const testData = generateTestData(RECORD_COUNT);
|
||
console.log('测试数据生成完成');
|
||
|
||
// 创建工作簿
|
||
const workbook = new Excel.Workbook();
|
||
const worksheet = workbook.addWorksheet('采购交易数据');
|
||
|
||
// 定义列(按照Excel实体类的index顺序)
|
||
worksheet.columns = [
|
||
{ header: '采购事项ID', key: 'purchaseId', width: 25 },
|
||
{ header: '采购类别', key: 'purchaseCategory', width: 15 },
|
||
{ header: '项目名称', key: 'projectName', width: 30 },
|
||
{ header: '标的物名称', key: 'subjectName', width: 30 },
|
||
{ header: '标的物描述', key: 'subjectDesc', width: 35 },
|
||
{ header: '采购数量', key: 'purchaseQty', width: 15 },
|
||
{ header: '预算金额', key: 'budgetAmount', width: 18 },
|
||
{ header: '中标金额', key: 'bidAmount', width: 18 },
|
||
{ header: '实际采购金额', key: 'actualAmount', width: 18 },
|
||
{ header: '合同金额', key: 'contractAmount', width: 18 },
|
||
{ header: '结算金额', key: 'settlementAmount', width: 18 },
|
||
{ header: '采购方式', key: 'purchaseMethod', width: 15 },
|
||
{ header: '中标供应商名称', key: 'supplierName', width: 30 },
|
||
{ header: '供应商联系人', key: 'contactPerson', width: 15 },
|
||
{ header: '供应商联系电话', key: 'contactPhone', width: 18 },
|
||
{ header: '供应商统一信用代码', key: 'supplierUscc', width: 25 },
|
||
{ header: '供应商银行账户', key: 'supplierBankAccount', width: 25 },
|
||
{ header: '采购申请日期', key: 'applyDate', width: 18 },
|
||
{ header: '采购计划批准日期', key: 'planApproveDate', width: 18 },
|
||
{ header: '采购公告发布日期', key: 'announceDate', width: 18 },
|
||
{ header: '开标日期', key: 'bidOpenDate', width: 18 },
|
||
{ header: '合同签订日期', key: 'contractSignDate', width: 18 },
|
||
{ header: '预计交货日期', key: 'expectedDeliveryDate', width: 18 },
|
||
{ header: '实际交货日期', key: 'actualDeliveryDate', width: 18 },
|
||
{ header: '验收日期', key: 'acceptanceDate', width: 18 },
|
||
{ header: '结算日期', key: 'settlementDate', width: 18 },
|
||
{ header: '申请人工号', key: 'applicantId', width: 15 },
|
||
{ header: '申请人姓名', key: 'applicantName', width: 15 },
|
||
{ header: '申请部门', key: 'applyDepartment', width: 18 },
|
||
{ header: '采购负责人工号', key: 'purchaseLeaderId', width: 15 },
|
||
{ header: '采购负责人姓名', key: 'purchaseLeaderName', width: 15 },
|
||
{ header: '采购部门', key: 'purchaseDepartment', width: 18 }
|
||
];
|
||
|
||
// 添加数据
|
||
worksheet.addRows(testData);
|
||
|
||
// 设置表头样式
|
||
const headerRow = worksheet.getRow(1);
|
||
headerRow.font = { bold: true };
|
||
headerRow.fill = {
|
||
type: 'pattern',
|
||
pattern: 'solid',
|
||
fgColor: { argb: 'FFE6E6FA' }
|
||
};
|
||
|
||
// 保存文件
|
||
console.log('正在写入Excel文件...');
|
||
await workbook.xlsx.writeFile(OUTPUT_FILE);
|
||
console.log(`✓ 文件已保存: ${OUTPUT_FILE}`);
|
||
|
||
// 显示统计信息
|
||
console.log('\n========================================');
|
||
console.log('数据统计');
|
||
console.log('========================================');
|
||
console.log(`总记录数: ${testData.length}`);
|
||
console.log(`采购数量范围: ${Math.min(...testData.map(d => d.purchaseQty))} - ${Math.max(...testData.map(d => d.purchaseQty))}`);
|
||
console.log(`预算金额范围: ${Math.min(...testData.map(d => d.budgetAmount))} - ${Math.max(...testData.map(d => d.budgetAmount))}`);
|
||
console.log('\n前3条记录预览:');
|
||
testData.slice(0, 3).forEach((record, index) => {
|
||
console.log(`\n记录 ${index + 1}:`);
|
||
console.log(` 采购事项ID: ${record.purchaseId}`);
|
||
console.log(` 项目名称: ${record.projectName}`);
|
||
console.log(` 采购数量: ${record.purchaseQty}`);
|
||
console.log(` 预算金额: ${record.budgetAmount}`);
|
||
console.log(` 申请人: ${record.applicantName} (${record.applicantId})`);
|
||
console.log(` 申请部门: ${record.applyDepartment}`);
|
||
console.log(` 申请日期: ${record.applyDate}`);
|
||
});
|
||
}
|
||
|
||
// 运行
|
||
createExcelFile().catch(console.error);
|