12 KiB
12 KiB
data/ - 数据模块
根目录 > data
变更记录 (Changelog)
2026-01-05 16:13:47
- 更新模块文档,添加导航面包屑
- 完善数据质量说明和使用建议
2026-01-05 16:03:40
- 初始化数据模块文档
- 完成三类钢材价格数据文件的结构分析
模块职责
负责存储和管理钢材价格原始数据,包含三种不同来源的价格信息:
- 钢材网架.json - 第三方平台市场价格数据(我的钢铁网)
- 钢厂指导价.json - 钢厂官方指导价格(德钢)
- 刚协指导价.json - 钢材行业协会指导价格(云南钢协)
文件清单
| 文件名 | 大小 | 记录数 | 更新日期 | 数据来源 |
|---|---|---|---|---|
| 钢材网架.json | ~190KB | 211+ 条 | 2026-01-05 | 我的钢铁网 |
| 钢厂指导价.json | ~1600KB | 29,987 条 | 2025-09-04 | 德钢指导价 |
| 刚协指导价.json | ~160KB | 900 条 | 2026-01-05 | 云南钢协 |
总记录数: 31,098 条
数据结构
统一格式
所有 JSON 文件均遵循以下嵌套结构:
{
"code": 0, // 响应码(0=成功)
"isZip": 0, // 是否压缩
"isDes": 0, // 是否加密
"data": {
"page": {
"result": [...], // 实际数据数组
"pageSize": 100, // 每页大小
"pageNo": 1, // 当前页码
"pageNumber": 1, // 页码
"totalCount": 211, // 总记录数
"totalPage": 3 // 总页数
}
}
}
价格记录字段说明
| 字段名 | 类型 | 必填 | 说明 | 示例值 |
|---|---|---|---|---|
| GOODS_MATERIAL | string | 是 | 材质牌号 | HRB400E, HPB300, HRB500E |
| GOODS_SPEC | string | 是 | 规格型号 | Φ6, Φ8, Φ12, Φ14... |
| PIRCE_DATE | string | 是 | 价格日期 | 2026-01-05 08:00:00 |
| PARTSNAME_NAME | string | 是 | 品名 | 螺纹钢, 高线, 盘螺 |
| PRODUCTAREA_NAME | string | 是 | 产地/钢厂 | 达州钢铁, 玉昆, 韶钢松山 |
| PRICE_ID | string | 是 | 价格唯一ID | 2008067775216672776 |
| PR_PRICE_SOURCE | string | 是 | 价格来源 | 我的钢铁, 云南钢协, 德钢指导价 |
| PR_PRICE_REGION | string | 是 | 价格地区 | 重庆, 昆明, 成都, 广州 |
| PNTREE_NAME | string | 是 | 分类名称 | 钢筋 |
| PR_PRICESET_HANGPRICE | integer | 否 | 当前挂牌价 | 3770 (元/吨) |
| PR_LAST_PRICESET_HANGPRICE | integer | 否 | 上次挂牌价 | 3770 (元/吨) |
| PR_MAKEPRICE_UPDW | string | 否 | 钢厂价涨跌 | 0, -20, +30 |
| PR_HANGPRICE_UPDW | string | 否 | 挂牌价涨跌 | 0, -20, +30 |
| OPERATOR_CODE | string | 否 | 操作员代码 | 1048, 1128 |
| OPERATOR_NAME | string | 否 | 操作员名称 | 姜薇, RPA机器人 |
数据样本分析
1. 钢材网架.json (我的钢铁网)
特征:
- 数据源: 第三方平台"我的钢铁"
- 涵盖地区: 重庆、成都、广州、南宁等
- 主要钢厂: 达州钢铁、成渝钒钛、韶钢松山、桂万钢
- 包含完整的价格涨跌信息
示例记录:
{
"GOODS_MATERIAL": "HRB400E",
"GOODS_SPEC": "Φ12",
"PIRCE_DATE": "2026-01-05 08:00:00",
"PARTSNAME_NAME": "螺纹钢",
"PRODUCTAREA_NAME": "达州钢铁",
"PRICE_ID": "2008071950960877594",
"PR_PRICE_SOURCE": "我的钢铁",
"PR_PRICE_REGION": "重庆",
"PR_PRICESET_MAKEPRICE": 3350,
"PR_LAST_PRICESET_MAKEPRICE": 3370,
"PR_MAKEPRICE_UPDW": "-20",
"PNTREE_NAME": "钢筋"
}
覆盖地区:
- 重庆、成都、广州、南宁
- 数据较新(2026-01-05)
2. 钢厂指导价.json (德钢指导价)
特征:
- 数据源: 德钢官方指导价
- 涵盖地区: 云南省内(玉溪、昭通、文山、景洪、蒙自)
- 钢厂品牌: 德钢
- 数据量最大(约3万条)
- 仅包含挂牌价,无钢厂价
示例记录:
{
"GOODS_MATERIAL": "HRB500E",
"GOODS_SPEC": "Φ28",
"PIRCE_DATE": "2025-09-04 08:00:00",
"PARTSNAME_NAME": "螺纹钢",
"PRODUCTAREA_NAME": "德钢",
"PRICE_ID": "2001490258921979958",
"PR_PRICE_SOURCE": "德钢指导价",
"PR_PRICE_REGION": "玉溪",
"PR_LAST_PRICESET_HANGPRICE": 3350,
"PR_HANGPRICE_UPDW": "-30",
"PR_PRICESET_HANGPRICE": 3320,
"PNTREE_NAME": "钢筋",
"OPERATOR_CODE": "1048",
"OPERATOR_NAME": "姜薇"
}
数据质量警告:
- 数据日期较旧(2025-09-04),需要更新
3. 刚协指导价.json (云南钢协)
特征:
- 数据源: 云南钢协官方指导价
- 涵盖地区: 昆明、玉溪、楚雄、大理
- 钢厂品牌: 玉昆
- 数据较新(2026-01-05)
- 仅包含挂牌价,无钢厂价
示例记录:
{
"GOODS_MATERIAL": "HRB400E",
"GOODS_SPEC": "Φ12",
"PIRCE_DATE": "2026-01-05 08:00:00",
"PARTSNAME_NAME": "螺纹钢",
"PRODUCTAREA_NAME": "玉昆",
"PRICE_ID": "2008067775216672776",
"PR_PRICE_SOURCE": "云南钢协",
"PR_PRICE_REGION": "昆明",
"PR_LAST_PRICESET_HANGPRICE": 3770,
"PR_HANGPRICE_UPDW": "0",
"PR_PRICESET_HANGPRICE": 3770,
"PNTREE_NAME": "钢筋",
"OPERATOR_CODE": "1048",
"OPERATOR_NAME": "姜薇"
}
数据特征统计
材质分布
- HRB400E: 最常见的螺纹钢材质(抗震)
- HPB300: 高线材质(光圆钢筋)
- HRB500E: 高强度螺纹钢
- HRB400: 普通螺纹钢
规格范围
- 最小: Φ6(盘螺、高线)
- 最大: Φ40(螺纹钢)
- 常用规格: Φ8, Φ10, Φ12, Φ14, Φ16, Φ18, Φ20, Φ22, Φ25
地区覆盖
- 西南地区: 重庆、成都、南宁、云南(昆明、玉溪、楚雄、大理等)
- 华南地区: 广州
- 主要钢厂: 达州钢铁、成渝钒钛、韶钢松山、桂万钢、玉昆、德钢
数据质量说明
数据完整性
- ✅ 包含完整的
PRICE_ID唯一标识 - ✅ 包含价格日期(
PIRCE_DATE) - ⚠️ 部分字段可能缺失(如
PR_PRICESET_MAKEPRICE) - ⚠️ 钢厂指导价数据日期较旧(2025-09-04)
数据一致性
- ⚠️ 字段命名错误:
PIRCE_DATE应为PRICE_DATE - ⚠️ 价格字段在不同文件中有不同的子字段(钢厂价 vs 挂牌价)
- ⚠️ 部分数据源缺少涨跌幅信息
使用建议
数据导入流程
1. 读取 JSON 文件
const fs = require('fs');
const path = require('path');
// 读取数据文件
const filePath = path.join(__dirname, '钢材网架.json');
const rawData = fs.readFileSync(filePath, 'utf8');
const jsonData = JSON.parse(rawData);
// 提取价格记录
const records = jsonData.data.page.result;
2. 数据验证与清洗
function validateAndClean(record) {
// 必填字段检查
const requiredFields = [
'PRICE_ID', 'GOODS_MATERIAL', 'GOODS_SPEC',
'PIRCE_DATE', 'PARTSNAME_NAME', 'PRODUCTAREA_NAME',
'PR_PRICE_SOURCE', 'PR_PRICE_REGION', 'PNTREE_NAME'
];
for (const field of requiredFields) {
if (!record[field]) {
throw new Error(`Missing required field: ${field}`);
}
}
// 字段重命名(修正错误)
return {
...record,
PRICE_DATE: record.PIRCE_DATE, // 修正字段名
price_date: new Date(record.PIRCE_DATE),
make_price: record.PR_PRICESET_MAKEPRICE || null,
hang_price: record.PR_PRICESET_HANGPRICE || null,
make_price_updw: record.PR_MAKEPRICE_UPDW || null,
hang_price_updw: record.PR_HANGPRICE_UPDW || null
};
}
3. 批量插入数据库
-- MySQL 建表语句
CREATE TABLE steel_prices (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
price_id VARCHAR(64) UNIQUE NOT NULL COMMENT '价格唯一ID',
goods_material VARCHAR(32) NOT NULL COMMENT '材质牌号',
goods_spec VARCHAR(16) NOT NULL COMMENT '规格型号',
partsname_name VARCHAR(32) NOT NULL COMMENT '品名',
productarea_name VARCHAR(64) NOT NULL COMMENT '产地/钢厂',
price_source VARCHAR(32) NOT NULL COMMENT '价格来源',
price_region VARCHAR(32) NOT NULL COMMENT '价格地区',
pntree_name VARCHAR(32) NOT NULL COMMENT '分类名称',
price_date DATETIME NOT NULL COMMENT '价格日期',
make_price INT COMMENT '钢厂价(元/吨)',
hang_price INT COMMENT '挂牌价(元/吨)',
last_make_price INT COMMENT '上次钢厂价',
last_hang_price INT COMMENT '上次挂牌价',
make_price_updw VARCHAR(8) COMMENT '钢厂价涨跌',
hang_price_updw VARCHAR(8) COMMENT '挂牌价涨跌',
operator_code VARCHAR(16) COMMENT '操作员代码',
operator_name VARCHAR(32) COMMENT '操作员名称',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_price_date (price_date),
INDEX idx_region_material (price_region, goods_material),
INDEX idx_source_date (price_source, price_date),
INDEX idx_price_id (price_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='钢材价格表';
4. 使用 UPSERT 避免重复
// 使用 INSERT ... ON DUPLICATE KEY UPDATE
const sql = `
INSERT INTO steel_prices (
price_id, goods_material, goods_spec, partsname_name,
productarea_name, price_source, price_region, pntree_name,
price_date, make_price, hang_price, make_price_updw, hang_price_updw,
operator_code, operator_name
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
make_price = VALUES(make_price),
hang_price = VALUES(hang_price),
updated_at = CURRENT_TIMESTAMP
`;
查询优化建议
常用查询场景
-- 1. 按地区和材质查询最新价格
SELECT * FROM steel_prices
WHERE price_region = '重庆'
AND goods_material = 'HRB400E'
ORDER BY price_date DESC
LIMIT 10;
-- 2. 查询指定日期范围的价格
SELECT
goods_spec,
AVG(hang_price) as avg_price,
MIN(hang_price) as min_price,
MAX(hang_price) as max_price
FROM steel_prices
WHERE price_date BETWEEN '2026-01-01' AND '2026-01-05'
AND price_region = '昆明'
AND goods_material = 'HRB400E'
GROUP BY goods_spec
ORDER BY goods_spec;
-- 3. 价格趋势分析
SELECT
DATE(price_date) as date,
goods_spec,
AVG(hang_price) as avg_price
FROM steel_prices
WHERE price_region = '重庆'
AND goods_material = 'HRB400E'
AND price_date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
GROUP BY DATE(price_date), goods_spec
ORDER BY date DESC, goods_spec;
索引优化
-- 复合索引(地区+材质+日期)
CREATE INDEX idx_region_material_date
ON steel_prices(price_region, goods_material, price_date DESC);
-- 覆盖索引(查询优化)
CREATE INDEX idx_source_region_date_price
ON steel_prices(price_source, price_region, price_date, hang_price);
数据更新策略
建议更新频率
- 钢材网架.json: 每日更新(市场价格波动频繁)
- 钢厂指导价.json: 每周或按钢厂发布周期更新
- 刚协指导价.json: 每日或每周更新
自动化采集(未来实现)
- 定时任务自动抓取各平台数据
- 数据变更检测与增量更新
- 历史价格数据归档
- 异常数据告警
常见问题 (FAQ)
Q: 为什么 PIRCE_DATE 拼写是错误的?
A: 这是原始数据源的字段命名错误。建议在数据库模型中修正为 PRICE_DATE,并在数据导入时进行字段重命名。
Q: 价格字段 PR_PRICESET_MAKEPRICE 和 PR_PRICESET_HANGPRICE 有什么区别?
A:
MAKEPRICE: 钢厂出厂价(钢厂直接销售价格)HANGPRICE: 市场挂牌价(经销商挂牌价格)- 不同数据源可能只包含其中一种
Q: 如何处理重复的 PRICE_ID?
A: PRICE_ID 应该是全局唯一的。如发现重复:
- 检查数据来源是否正确
- 使用
UPSERT语句更新现有记录 - 记录冲突日志供后续分析
- 考虑添加数据源标识符避免跨源冲突
Q: 数据文件太大如何高效处理?
A: 建议采用以下策略:
- 使用流式读取(Node.js
stream) - 批量处理(每批 1000 条)
- 使用事务批量插入
- 考虑使用 worker 线程并行处理
相关文件路径
- 数据文件:
d:\Code\steel_prices_service\data\*.json - 根文档:
d:\Code\steel_prices_service\CLAUDE.md - 索引文件:
d:\Code\steel_prices_service\.claude\index.json