198 lines
5.5 KiB
JavaScript
198 lines
5.5 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
/**
|
|
* 导入公司信息 SQL 生成脚本
|
|
* 从 _doc/公司xinxi.md 文件读取数据并生成 SQL INSERT 语句
|
|
*/
|
|
|
|
// 转义 SQL 字符串中的特殊字符
|
|
function escapeSql(str) {
|
|
if (!str) return '';
|
|
return str.replace(/'/g, "''").replace(/\\/g, '\\\\');
|
|
}
|
|
|
|
// 从注册地址提取省份和城市
|
|
function extractProvinceAndCity(address) {
|
|
if (!address) return { province: '', city: '' };
|
|
|
|
// 大部分都是上海的公司
|
|
if (address.includes('上海')) {
|
|
return { province: '上海', city: '上海' };
|
|
}
|
|
|
|
// 处理其他省份(如果有)
|
|
const provincePatterns = [
|
|
{ pattern: /^(.+?省|.+?市|.+?自治区|.+?特别行政区)/, extract: (match) => match[1] }
|
|
];
|
|
|
|
for (const { pattern, extract } of provincePatterns) {
|
|
const match = address.match(pattern);
|
|
if (match) {
|
|
const province = extract(match);
|
|
return { province, city: province };
|
|
}
|
|
}
|
|
|
|
return { province: '', city: '' };
|
|
}
|
|
|
|
// 读取文件并解析数据
|
|
function parseCompanyData() {
|
|
const filePath = path.join(__dirname, '../_doc/公司xinxi.md');
|
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
const lines = content.split('\n');
|
|
|
|
const companies = [];
|
|
|
|
// 跳过表头(第一行)
|
|
for (let i = 1; i < lines.length; i++) {
|
|
const line = lines[i].trim();
|
|
if (!line) continue;
|
|
|
|
// 按制表符分割
|
|
const parts = line.split('\t');
|
|
if (parts.length < 7) continue;
|
|
|
|
const sequenceNumber = parts[0] || '';
|
|
const stockCode = parts[1] || '';
|
|
const companyName = parts[2] || '';
|
|
const registeredAddress = parts[3] || '';
|
|
const phone = parts[4] || '';
|
|
const email = parts[5] || '';
|
|
const website = parts[6] || '';
|
|
|
|
// 提取省份和城市
|
|
const { province, city } = extractProvinceAndCity(registeredAddress);
|
|
|
|
// 判断是否上市(有证券代码就是上市)
|
|
const isListed = stockCode ? 1 : 0;
|
|
|
|
companies.push({
|
|
sequence_number: sequenceNumber,
|
|
stock_code: stockCode,
|
|
company_name: companyName,
|
|
registered_address: registeredAddress,
|
|
province,
|
|
city,
|
|
phone,
|
|
email,
|
|
website,
|
|
is_listed: isListed,
|
|
recommendation_level: 'normal',
|
|
is_enabled: 1
|
|
});
|
|
}
|
|
|
|
return companies;
|
|
}
|
|
|
|
// 生成 SQL INSERT 语句
|
|
function generateSql(companies) {
|
|
const sqlStatements = [];
|
|
|
|
// 添加注释
|
|
sqlStatements.push('-- 导入公司信息数据');
|
|
sqlStatements.push(`-- 生成时间: ${new Date().toLocaleString('zh-CN')}`);
|
|
sqlStatements.push(`-- 数据条数: ${companies.length}`);
|
|
sqlStatements.push('');
|
|
sqlStatements.push('-- 开始事务(可选)');
|
|
sqlStatements.push('-- START TRANSACTION;');
|
|
sqlStatements.push('');
|
|
|
|
// 生成 INSERT 语句
|
|
companies.forEach((company, index) => {
|
|
const values = [
|
|
company.sequence_number || 'NULL',
|
|
company.stock_code ? `'${escapeSql(company.stock_code)}'` : 'NULL',
|
|
`'${escapeSql(company.company_name)}'`,
|
|
company.registered_address ? `'${escapeSql(company.registered_address)}'` : 'NULL',
|
|
company.province ? `'${escapeSql(company.province)}'` : 'NULL',
|
|
company.city ? `'${escapeSql(company.city)}'` : 'NULL',
|
|
company.phone ? `'${escapeSql(company.phone)}'` : 'NULL',
|
|
company.email ? `'${escapeSql(company.email)}'` : 'NULL',
|
|
company.website ? `'${escapeSql(company.website)}'` : 'NULL',
|
|
company.is_listed,
|
|
`'${escapeSql(company.recommendation_level)}'`,
|
|
company.is_enabled,
|
|
'NULL' // remark
|
|
];
|
|
|
|
const sql = `INSERT INTO company_info (
|
|
sequence_number,
|
|
stock_code,
|
|
company_name,
|
|
registered_address,
|
|
province,
|
|
city,
|
|
phone,
|
|
email,
|
|
website,
|
|
is_listed,
|
|
recommendation_level,
|
|
is_enabled,
|
|
remark
|
|
) VALUES (
|
|
${values.join(',\n ')}
|
|
);`;
|
|
|
|
sqlStatements.push(sql);
|
|
|
|
// 每 100 条添加一个注释
|
|
if ((index + 1) % 100 === 0) {
|
|
sqlStatements.push(`-- 已处理 ${index + 1} 条数据`);
|
|
sqlStatements.push('');
|
|
}
|
|
});
|
|
|
|
sqlStatements.push('');
|
|
sqlStatements.push('-- 提交事务(可选)');
|
|
sqlStatements.push('-- COMMIT;');
|
|
|
|
return sqlStatements.join('\n');
|
|
}
|
|
|
|
// 主函数
|
|
function main() {
|
|
try {
|
|
console.log('开始解析公司信息数据...');
|
|
const companies = parseCompanyData();
|
|
console.log(`成功解析 ${companies.length} 条公司信息`);
|
|
|
|
console.log('生成 SQL 语句...');
|
|
const sql = generateSql(companies);
|
|
|
|
// 保存到文件
|
|
const outputPath = path.join(__dirname, '../_script/import_company_info.sql');
|
|
fs.writeFileSync(outputPath, sql, 'utf-8');
|
|
|
|
console.log(`SQL 文件已生成: ${outputPath}`);
|
|
console.log(`文件大小: ${(fs.statSync(outputPath).size / 1024).toFixed(2)} KB`);
|
|
|
|
// 显示统计信息
|
|
const listedCount = companies.filter(c => c.is_listed === 1).length;
|
|
const provinceStats = {};
|
|
companies.forEach(c => {
|
|
const p = c.province || '未知';
|
|
provinceStats[p] = (provinceStats[p] || 0) + 1;
|
|
});
|
|
|
|
console.log('\n统计信息:');
|
|
console.log(`- 总数量: ${companies.length}`);
|
|
console.log(`- 上市公司: ${listedCount}`);
|
|
console.log(`- 未上市公司: ${companies.length - listedCount}`);
|
|
console.log('\n省份分布:');
|
|
Object.entries(provinceStats).forEach(([province, count]) => {
|
|
console.log(` - ${province}: ${count}`);
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('生成 SQL 失败:', error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// 执行
|
|
main();
|
|
|