init:代码初始化

This commit is contained in:
bai
2026-01-06 09:19:12 +08:00
parent 2dff90de4a
commit ba478d70cc
34 changed files with 11917 additions and 1 deletions

417
data/CLAUDE.md Normal file
View File

@@ -0,0 +1,417 @@
# 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)