Files
steel_prices_service/data/CLAUDE.md
2026-01-06 09:19:12 +08:00

418 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# data/ - 数据模块
[根目录](../CLAUDE.md) > **data**
---
## 变更记录 (Changelog)
### 2026-01-05 16:13:47
- 更新模块文档,添加导航面包屑
- 完善数据质量说明和使用建议
### 2026-01-05 16:03:40
- 初始化数据模块文档
- 完成三类钢材价格数据文件的结构分析
---
## 模块职责
负责存储和管理钢材价格原始数据,包含三种不同来源的价格信息:
1. **钢材网架.json** - 第三方平台市场价格数据(我的钢铁网)
2. **钢厂指导价.json** - 钢厂官方指导价格(德钢)
3. **刚协指导价.json** - 钢材行业协会指导价格(云南钢协)
---
## 文件清单
| 文件名 | 大小 | 记录数 | 更新日期 | 数据来源 |
|-------|------|--------|----------|----------|
| **钢材网架.json** | ~190KB | 211+ 条 | 2026-01-05 | 我的钢铁网 |
| **钢厂指导价.json** | ~1600KB | 29,987 条 | 2025-09-04 | 德钢指导价 |
| **刚协指导价.json** | ~160KB | 900 条 | 2026-01-05 | 云南钢协 |
**总记录数**: 31,098 条
---
## 数据结构
### 统一格式
所有 JSON 文件均遵循以下嵌套结构:
```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 (我的钢铁网)
**特征**:
- 数据源: 第三方平台"我的钢铁"
- 涵盖地区: 重庆、成都、广州、南宁等
- 主要钢厂: 达州钢铁、成渝钒钛、韶钢松山、桂万钢
- 包含完整的价格涨跌信息
**示例记录**:
```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万条
- 仅包含挂牌价,无钢厂价
**示例记录**:
```json
{
"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
- 仅包含挂牌价,无钢厂价
**示例记录**:
```json
{
"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 文件
```javascript
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. 数据验证与清洗
```javascript
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. 批量插入数据库
```sql
-- 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 避免重复
```javascript
// 使用 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
`;
```
### 查询优化建议
#### 常用查询场景
```sql
-- 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;
```
#### 索引优化
```sql
-- 复合索引(地区+材质+日期)
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` 应该是全局唯一的。如发现重复:
1. 检查数据来源是否正确
2. 使用 `UPSERT` 语句更新现有记录
3. 记录冲突日志供后续分析
4. 考虑添加数据源标识符避免跨源冲突
### Q: 数据文件太大如何高效处理?
A: 建议采用以下策略:
1. 使用流式读取Node.js `stream`
2. 批量处理(每批 1000 条)
3. 使用事务批量插入
4. 考虑使用 worker 线程并行处理
---
## 相关文件路径
- **数据文件**: `d:\Code\steel_prices_service\data\*.json`
- **根文档**: `d:\Code\steel_prices_service\CLAUDE.md`
- **索引文件**: `d:\Code\steel_prices_service\.claude\index.json`
---
**导航**: [返回根目录](../CLAUDE.md) | [查看项目索引](../.claude/index.json)