# 数据导入脚本使用说明 ## 概述 `scripts/import-data.js` 已升级,现在支持两种数据导入模式: 1. **本地文件模式** (`local`): 从 `data/` 目录的 JSON 文件导入 2. **API 接口模式** (`api`): 从 `commonApi.js` 定义的接口实时获取数据 ## 接口映射关系 | 接口端点 | 数据来源 | 对应文件 | 数据来源标识 | |---------|---------|---------|------------| | `DEFAULT` | 云南钢协 | 刚协指导价.json | 云南钢协 | | `BACKUP` | 我的钢铁 | 钢材网架.json | 我的钢铁 | | `EXTENDED` | 德钢指导价 | 钢厂指导价.json | 德钢指导价 | ## 使用方法 ### 1. 本地文件导入(默认模式) ```bash # 方式 1: 显式指定模式 node scripts/import-data.js local # 方式 2: 使用默认模式(省略参数) npm run db:import # 或 node scripts/import-data.js ``` **功能说明:** - 从 `data/` 目录读取所有 JSON 文件 - 依次导入:刚协指导价.json、钢材网架.json、钢厂指导价.json - 跳过不存在的文件 ### 2. API 接口导入 #### 2.1 从所有 API 接口导入 ```bash # 使用默认参数(今天到一年后,每页 10 万条) node scripts/import-data.js api # 指定日期范围 node scripts/import-data.js api --startDate 2025-01-01 --endDate 2025-12-31 # 指定每页数量 node scripts/import-data.js api --pageSize 50000 # 组合参数 node scripts/import-data.js api --startDate 2025-01-01 --endDate 2025-12-31 --pageSize 100000 ``` **执行流程:** 1. 依次调用 DEFAULT、BACKUP、EXTENDED 三个接口 2. 自动获取 Token 3. 批量导入数据(每批 1000 条) 4. 显示导入进度和统计信息 #### 2.2 从单个 API 接口导入 ```bash # 仅导入云南钢协数据(DEFAULT 接口) node scripts/import-data.js single-api DEFAULT # 仅导入我的钢铁数据(BACKUP 接口) node scripts/import-data.js single-api BACKUP # 仅导入德钢指导价数据(EXTENDED 接口) node scripts/import-data.js single-api EXTENDED # 带参数的单接口导入 node scripts/import-data.js single-api DEFAULT --startDate 2025-01-01 --endDate 2025-12-31 ``` ## 命令行参数 | 参数 | 说明 | 示例 | 默认值 | |-----|------|-----|-------| | `--startDate` | 查询开始日期(YYYY-MM-DD) | `--startDate 2025-01-01` | 今天 | | `--endDate` | 查询结束日期(YYYY-MM-DD) | `--endDate 2026-01-01` | 一年后 | | `--pageSize` | 每页数据条数 | `--pageSize 100000` | 100000 | ## 输出示例 ### 本地文件导入 ``` 🚀 开始从本地文件导入钢材价格数据... 📄 正在读取本地文件: 刚协指导价.json ✅ 解析到 900 条有效数据 进度: 900/900 条 ✅ 成功导入 900 条数据 📄 正在读取本地文件: 钢材网架.json ✅ 解析到 211 条有效数据 进度: 211/211 条 ✅ 成功导入 211 条数据 📄 正在读取本地文件: 钢厂指导价.json ✅ 解析到 29987 条有效数据 进度: 1000/29987 条 进度: 2000/29987 条 ... 进度: 29987/29987 条 ✅ 成功导入 29987 条数据 ================================================== 🎉 本地文件导入完成!总计导入 31098 条数据 ================================================== 📊 数据库统计信息: 总记录数: 31098 平均价格: 4500.25 元/吨 最低价格: 3200 元/吨 最高价格: 5800 元/吨 ✅ 脚本执行完成 ``` ### API 接口导入 ``` 🚀 开始从 API 接口导入钢材价格数据... 🌐 正在从 API 接口获取数据: DEFAULT (云南钢协) 查询参数: { "startDate": "2025-01-06", "endDate": "2026-01-06", "page": 1, "pageSize": 100000 } 🔐 正在获取 Token... ✅ Token 获取成功: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... 🔄 切换到接口: 默认钢材价格查询 Page ID: PG-D615-D8E2-2FD84B8D Menu ID: MK-A8B8-109E-13D34116 ✅ 解析到 1250 条有效数据 进度: 1000/1250 条 进度: 1250/1250 条 ✅ 成功导入 1250 条数据 🌐 正在从 API 接口获取数据: BACKUP (我的钢铁) ... 🌐 正在从 API 接口获取数据: EXTENDED (德钢指导价) ... ================================================== 🎉 API 接口导入完成!总计导入 15234 条数据 ================================================== 📊 数据库统计信息: 总记录数: 46332 平均价格: 4450.80 元/吨 最低价格: 3100 元/吨 最高价格: 5900 元/吨 ✅ 脚本执行完成 ``` ## 编程式调用 除了命令行调用,也可以在代码中直接使用: ```javascript const { importFromAPI, importAllFromAPI, importAllLocalFiles } = require('./scripts/import-data'); // 方式 1: 从单个 API 接口导入 await importFromAPI('DEFAULT', { startDate: '2025-01-01', endDate: '2025-12-31', pageSize: 100000 }); // 方式 2: 从所有 API 接口导入 await importAllFromAPI({ startDate: '2025-01-01', endDate: '2025-12-31' }); // 方式 3: 从本地文件导入 await importAllLocalFiles(); ``` ## 错误处理 脚本包含完善的错误处理机制: 1. **文件不存在**: 自动跳过,继续处理其他文件 2. **API 请求失败**: 显示错误信息,继续处理下一个接口 3. **数据解析失败**: 显示详细错误,不会中断整个流程 4. **数据库插入失败**: 记录错误日志,支持批量插入失败重试 ## 注意事项 1. **环境变量**: 确保 `.env` 文件配置正确,包含数据库连接信息 2. **Token 管理**: API 模式会自动从 `loginApi.js` 获取 Token,确保登录凭证有效 3. **网络连接**: API 模式需要稳定的网络连接 4. **数据库性能**: 批量插入每批 1000 条,大数据量导入可能需要较长时间 5. **重复数据**: 使用 `ON DUPLICATE KEY UPDATE` 策略,避免重复导入 ## 故障排查 ### 问题 1: Token 获取失败 ``` ❌ Token 获取失败: Invalid credentials ``` **解决方案:** - 检查 `.env` 中的登录凭证 - 确认 `loginApi.js` 中的 Token 存储路径正确 - 手动运行 `node commonApi.js` 测试登录 ### 问题 2: 数据库连接失败 ``` ❌ 价格表创建失败: Access denied for user 'root'@'localhost' ``` **解决方案:** - 检查 `.env` 中的数据库配置 - 确认 MySQL 服务已启动 - 验证用户权限 ### 问题 3: API 返回空数据 ``` ⚠️ 没有有效数据可导入 ``` **解决方案:** - 检查日期范围是否合理 - 确认 API 接口地址正确 - 尝试增加 `pageSize` 参数 ## 最佳实践 1. **定期导入**: 使用 `node-cron` 或系统定时任务定期执行 API 导入 2. **增量更新**: 使用日期参数仅导入最新数据 3. **数据备份**: 导入前备份现有数据 4. **监控日志**: 保存导入日志用于审计和问题排查 ## 示例:定时任务 使用 `node-cron` 设置每天凌晨 2 点自动导入: ```javascript // scripts/schedule-import.js const cron = require('node-cron'); const { exec } = require('child_process'); cron.schedule('0 2 * * *', () => { console.log('🕰️ 开始定时导入任务...'); exec('node scripts/import-data.js api --startDate 2025-01-01 --pageSize 100000', (error, stdout, stderr) => { if (error) { console.error(`执行出错: ${error}`); return; } console.log(stdout); } ); }); console.log('✅ 定时任务已启动:每天 02:00 执行数据导入'); ``` 运行定时任务: ```bash node scripts/schedule-import.js ``` ## 技术细节 ### 数据转换 - 原始数据格式: `rawData.data.page.result[]` - 过滤条件: `price_date` 存在且 `hang_price > 0` - 字段映射: 自动映射 API 字段到数据库字段 ### 批量插入策略 - 批次大小: 1000 条/批 - 重复处理: 使用 `ON DUPLICATE KEY UPDATE` - 事务支持: 每批独立事务 ### 性能优化 - 批量插入优于单条插入 - 数据库索引优化 (`idx_price_date`, `idx_region_material`) - 自动过滤无效数据,减少不必要的数据库操作 --- ## 更新日志 ### 2026-01-06 - ✅ 新增 API 接口导入功能 - ✅ 支持命令行参数配置 - ✅ 改进错误处理和进度显示 - ✅ 保持向后兼容性