134 lines
4.2 KiB
JavaScript
134 lines
4.2 KiB
JavaScript
/**
|
||
* 地址数据分片工具
|
||
* 将完整的地址JSON文件分片为:
|
||
* 1. 省份列表(轻量级,< 1MB)
|
||
* 2. 每个省份的详情文件(按需加载)
|
||
*
|
||
* 使用方法:
|
||
* 1. 将完整的 address.json 文件放到 data 目录
|
||
* 2. 运行: node scripts/splitAddressData.js
|
||
* 3. 将生成的 split 目录中的文件上传到服务器
|
||
*/
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
// 配置
|
||
const INPUT_FILE = path.join(__dirname, '../data/address.json');
|
||
const OUTPUT_DIR = path.join(__dirname, '../data/split');
|
||
|
||
// 检查输入文件是否存在
|
||
if (!fs.existsSync(INPUT_FILE)) {
|
||
console.error('❌ 错误:找不到输入文件');
|
||
console.error(` 请将完整的 address.json 文件放到: ${INPUT_FILE}`);
|
||
process.exit(1);
|
||
}
|
||
|
||
// 创建输出目录
|
||
if (!fs.existsSync(OUTPUT_DIR)) {
|
||
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
||
console.log(`✅ 创建输出目录: ${OUTPUT_DIR}`);
|
||
}
|
||
|
||
console.log('📥 开始读取完整地址数据...');
|
||
const startTime = Date.now();
|
||
|
||
// 读取完整数据
|
||
let fullData;
|
||
try {
|
||
const fileContent = fs.readFileSync(INPUT_FILE, 'utf8');
|
||
fullData = JSON.parse(fileContent);
|
||
const loadTime = ((Date.now() - startTime) / 1000).toFixed(2);
|
||
console.log(`✅ 数据读取完成,耗时 ${loadTime} 秒`);
|
||
} catch (error) {
|
||
console.error('❌ 读取或解析JSON失败:', error.message);
|
||
process.exit(1);
|
||
}
|
||
|
||
if (!Array.isArray(fullData)) {
|
||
console.error('❌ 错误:数据格式不正确,期望数组格式');
|
||
process.exit(1);
|
||
}
|
||
|
||
console.log(`📊 共 ${fullData.length} 个省份`);
|
||
|
||
// 1. 生成省份列表(轻量级)
|
||
console.log('\n📝 生成省份列表...');
|
||
const provinceList = fullData.map(province => ({
|
||
code: province.code,
|
||
name: province.name,
|
||
_hasChildren: !!province.children && province.children.length > 0
|
||
}));
|
||
|
||
const provinceListPath = path.join(OUTPUT_DIR, 'address_provinces.json');
|
||
fs.writeFileSync(
|
||
provinceListPath,
|
||
JSON.stringify(provinceList, null, 2),
|
||
'utf8'
|
||
);
|
||
|
||
const provinceListSize = (fs.statSync(provinceListPath).size / 1024).toFixed(2);
|
||
console.log(`✅ 省份列表已生成: ${provinceListPath}`);
|
||
console.log(` 大小: ${provinceListSize} KB`);
|
||
|
||
// 2. 为每个省份生成详情文件
|
||
console.log('\n📝 生成省份详情文件...');
|
||
let totalSize = 0;
|
||
let successCount = 0;
|
||
let failCount = 0;
|
||
|
||
fullData.forEach((province, index) => {
|
||
try {
|
||
const fileName = `address_province_${province.code}.json`;
|
||
const filePath = path.join(OUTPUT_DIR, fileName);
|
||
|
||
fs.writeFileSync(
|
||
filePath,
|
||
JSON.stringify(province, null, 2),
|
||
'utf8'
|
||
);
|
||
|
||
const fileSize = fs.statSync(filePath).size;
|
||
totalSize += fileSize;
|
||
successCount++;
|
||
|
||
const progress = ((index + 1) / fullData.length * 100).toFixed(1);
|
||
console.log(` [${progress}%] ${province.name} (${province.code}) - ${(fileSize / 1024 / 1024).toFixed(2)} MB`);
|
||
} catch (error) {
|
||
failCount++;
|
||
console.error(` ❌ ${province.name} 生成失败:`, error.message);
|
||
}
|
||
});
|
||
|
||
// 统计信息
|
||
console.log('\n📊 分片完成统计:');
|
||
console.log(` ✅ 成功: ${successCount} 个省份`);
|
||
if (failCount > 0) {
|
||
console.log(` ❌ 失败: ${failCount} 个省份`);
|
||
}
|
||
console.log(` 📦 总大小: ${(totalSize / 1024 / 1024).toFixed(2)} MB`);
|
||
console.log(` 📁 输出目录: ${OUTPUT_DIR}`);
|
||
|
||
// 生成文件列表(方便上传)
|
||
const fileList = [
|
||
'address_provinces.json',
|
||
...fullData.map(p => `address_province_${p.code}.json`)
|
||
];
|
||
|
||
const fileListPath = path.join(OUTPUT_DIR, 'file_list.txt');
|
||
fs.writeFileSync(
|
||
fileListPath,
|
||
fileList.join('\n'),
|
||
'utf8'
|
||
);
|
||
console.log(`\n📋 文件列表已生成: ${fileListPath}`);
|
||
|
||
console.log('\n✅ 数据分片完成!');
|
||
console.log('\n📤 下一步:');
|
||
console.log(' 1. 将 split 目录中的所有文件上传到服务器');
|
||
console.log(' 2. 确保文件可以通过以下URL访问:');
|
||
console.log(` - ${path.basename(OUTPUT_DIR)}/address_provinces.json`);
|
||
console.log(` - ${path.basename(OUTPUT_DIR)}/address_province_{code}.json`);
|
||
console.log(' 3. 在 addressDataLoaderLazy.js 中配置正确的 baseUrl');
|
||
|