11 KiB
11 KiB
数据源标识系统说明
概述
为了清晰区分来自三个不同接口的数据,我们为每个数据源添加了明确的标识字段。这样可以:
- 清晰区分数据来源 - 知道数据来自哪个接口
- 便于数据筛选 - 按数据源查询和统计
- 数据溯源 - 追踪数据的采集方式(本地文件或 API)
- 避免数据混淆 - 即使数据相似也能区分来源
数据源配置
三个接口的标识
| 接口端点 | 数据来源 | 标识码 | 颜色标签 | 描述 |
|---|---|---|---|---|
DEFAULT |
云南钢协 | YUNNAN_STEEL_ASSOC |
🔴 #FF6B6B | 云南钢协指导价(API) |
BACKUP |
我的钢铁 | MY_STEEL |
🔵 #4ECDC4 | 我的钢铁网价格(API) |
EXTENDED |
德钢指导价 | DE_STEEL_FACTORY |
🟢 #95E1D3 | 德钢钢厂指导价(API) |
本地文件映射
| 文件名 | 数据来源 | 标识码 | 颜色标签 | 描述 |
|---|---|---|---|---|
刚协指导价.json |
云南钢协 | YUNNAN_STEEL_ASSOC |
🔴 #FF6B6B | 云南钢协指导价 |
钢材网架.json |
我的钢铁 | MY_STEEL |
🔵 #4ECDC4 | 我的钢铁网价格 |
钢厂指导价.json |
德钢指导价 | DE_STEEL_FACTORY |
🟢 #95E1D3 | 德钢钢厂指导价 |
数据库字段说明
新增字段
-- 数据源代码(唯一标识)
price_source_code VARCHAR(32) NOT NULL
-- 可能的值: 'YUNNAN_STEEL_ASSOC', 'MY_STEEL', 'DE_STEEL_FACTORY'
-- 数据源描述
price_source_desc VARCHAR(64) NOT NULL
-- 例如: '云南钢协指导价(API)', '我的钢铁网价格(API)'
-- 数据来源标识
data_origin VARCHAR(32) NOT NULL
-- 格式:
-- - 'LOCAL_FILE' - 从本地文件导入
-- - 'API:DEFAULT' - 从 DEFAULT 接口导入
-- - 'API:BACKUP' - 从 BACKUP 接口导入
-- - 'API:EXTENDED' - 从 EXTENDED 接口导入
完整表结构
CREATE TABLE prices (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
price_id VARCHAR(64) UNIQUE NOT NULL,
goods_material VARCHAR(32) NOT NULL,
goods_spec VARCHAR(16) NOT NULL,
partsname_name VARCHAR(32) NOT NULL,
productarea_name VARCHAR(64) NOT NULL,
-- 数据源标识字段
price_source VARCHAR(32) NOT NULL, -- 原有字段:价格来源名称
price_source_code VARCHAR(32) NOT NULL, -- 新增:数据源代码
price_source_desc VARCHAR(64) NOT NULL, -- 新增:数据源描述
data_origin VARCHAR(32) NOT NULL, -- 新增:数据来源标识
price_region VARCHAR(32) NOT NULL,
pntree_name VARCHAR(32) NOT NULL,
price_date DATETIME NOT NULL,
make_price INT DEFAULT NULL,
hang_price INT NOT NULL,
last_make_price INT DEFAULT NULL,
last_hang_price INT DEFAULT NULL,
make_price_updw VARCHAR(8) DEFAULT NULL,
hang_price_updw VARCHAR(8) DEFAULT NULL,
operator_code VARCHAR(16) DEFAULT NULL,
operator_name VARCHAR(32) DEFAULT NULL,
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_source_code (price_source_code), -- 新增:按数据源代码查询
INDEX idx_data_origin (data_origin), -- 新增:按数据来源查询
INDEX idx_goods_spec (goods_spec)
);
使用示例
1. 数据库迁移(为现有表添加新字段)
npm run db:migrate
输出示例:
🔄 开始数据库迁移:添加数据源标识字段
✅ 数据源字段迁移成功
============================================================
✅ 数据库迁移完成!
============================================================
📊 新增字段说明:
- price_source_code: 数据源代码(YUNNAN_STEEL_ASSOC / MY_STEEL / DE_STEEL_FACTORY)
- price_source_desc: 数据源描述
- data_origin: 数据来源标识(LOCAL_FILE 或 API:ENDPOINT)
🎨 数据源标识:
🔴 YUNNAN_STEEL_ASSOC - 云南钢协指导价(DEFAULT 接口)
🔵 MY_STEEL - 我的钢铁网价格(BACKUP 接口)
🟢 DE_STEEL_FACTORY - 德钢钢厂指导价(EXTENDED 接口)
2. 从 API 接口导入数据(带标识)
# 导入云南钢协数据(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
# 从所有 API 接口导入
npm run db:import:api
导入过程示例:
🌐 正在从 API 接口获取数据: DEFAULT
📊 数据源: 云南钢协指导价(API)
🏷️ 标识码: YUNNAN_STEEL_ASSOC
🎨 标签: #FF6B6B
📅 查询参数: {
"startDate": "2025-01-06",
"endDate": "2026-01-06",
"page": 1,
"pageSize": 100000
}
🔐 正在获取 Token...
✅ Token 获取成功
🔄 切换到接口: 默认钢材价格查询
Page ID: PG-D615-D8E2-2FD84B8D
Menu ID: MK-A8B8-109E-13D34116
✅ 解析到 1250 条有效数据
进度: 1000/1250 条
进度: 1250/1250 条
✅ 成功导入 1250 条数据
3. 从本地文件导入数据(带标识)
# 从本地文件导入
npm run db:import:local
导入过程示例:
📄 正在读取本地文件: 刚协指导价.json
📊 数据源: 云南钢协指导价
🏷️ 标识码: YUNNAN_STEEL_ASSOC
🎨 标签: #FF6B6B
✅ 解析到 900 条有效数据
进度: 900/900 条
✅ 成功导入 900 条数据
数据查询示例
SQL 查询
1. 查询所有数据源统计
SELECT
price_source_code AS '数据源代码',
price_source_desc AS '数据源描述',
data_origin AS '数据来源',
COUNT(*) AS '记录数',
AVG(hang_price) AS '平均价格',
MIN(hang_price) AS '最低价格',
MAX(hang_price) AS '最高价格'
FROM prices
GROUP BY price_source_code, price_source_desc, data_origin
ORDER BY price_source_code;
结果示例:
+---------------------+----------------------+----------------+----------+----------+----------+----------+
| 数据源代码 | 数据源描述 | 数据来源 | 记录数 | 平均价格 | 最低价格 | 最高价格 |
+---------------------+----------------------+----------------+----------+----------+----------+----------+
| YUNNAN_STEEL_ASSOC | 云南钢协指导价(API) | API:DEFAULT | 1250 | 4500.50 | 3800 | 5200 |
| YUNNAN_STEEL_ASSOC | 云南钢协指导价 | LOCAL_FILE | 900 | 4480.30 | 3850 | 5180 |
| MY_STEEL | 我的钢铁网价格(API) | API:BACKUP | 850 | 4420.80 | 3700 | 5150 |
| MY_STEEL | 我的钢铁网价格 | LOCAL_FILE | 211 | 4400.60 | 3750 | 5120 |
| DE_STEEL_FACTORY | 德钢钢厂指导价(API)| API:EXTENDED | 15000 | 4550.20 | 3900 | 5300 |
| DE_STEEL_FACTORY | 德钢钢厂指导价 | LOCAL_FILE | 29987 | 4530.90 | 3880 | 5280 |
+---------------------+----------------------+----------------+----------+----------+----------+----------+
2. 按数据源筛选
-- 查询云南钢协的数据
SELECT * FROM prices
WHERE price_source_code = 'YUNNAN_STEEL_ASSOC'
ORDER BY price_date DESC;
-- 查询从 API 导入的数据
SELECT * FROM prices
WHERE data_origin LIKE 'API:%'
ORDER BY price_date DESC;
-- 查询特定接口的数据
SELECT * FROM prices
WHERE data_origin = 'API:DEFAULT'
ORDER BY price_date DESC;
3. 对比不同数据源的价格
SELECT
DATE(price_date) AS '日期',
price_source_code AS '数据源',
AVG(hang_price) AS '平均价格'
FROM prices
WHERE DATE(price_date) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
GROUP BY DATE(price_date), price_source_code
ORDER BY DATE(price_date), price_source_code;
Node.js 查询
// 查询特定数据源的数据
const yunnanSteelPrices = await Price.search({
material: 'HRB400E',
startDate: '2025-01-01',
endDate: '2025-01-31'
});
// 过滤云南钢协数据
const filtered = yunnanSteelPrices.filter(item =>
item.price_source_code === 'YUNNAN_STEEL_ASSOC'
);
// 按数据源分组统计
const statsBySource = await Price.getStats({
/* 可以扩展 getStats 方法支持按数据源统计 */
});
API 接口返回数据格式
导入数据时,每条记录将包含以下标识字段:
{
"price_id": "abc123...",
"goods_material": "HRB400E",
"goods_spec": "Φ18",
"partsname_name": "螺纹钢",
"productarea_name": "云南德胜",
"price_source": "云南钢协",
"price_source_code": "YUNNAN_STEEL_ASSOC", // 数据源代码
"price_source_desc": "云南钢协指导价(API)", // 数据源描述
"data_origin": "API:DEFAULT", // 数据来源标识
"price_region": "昆明",
"pntree_name": "钢筋",
"price_date": "2025-01-06 00:00:00",
"make_price": 4450,
"hang_price": 4500,
"last_make_price": 4400,
"last_hang_price": 4450,
"make_price_updw": "+50",
"hang_price_updw": "+50"
}
颜色标签使用建议
这些颜色标签可以在前端界面中使用,帮助用户直观区分数据来源:
const SOURCE_COLORS = {
YUNNAN_STEEL_ASSOC: '#FF6B6B', // 红色 - 云南钢协
MY_STEEL: '#4ECDC4', // 蓝绿色 - 我的钢铁
DE_STEEL_FACTORY: '#95E1D3' // 绿色 - 德钢指导价
};
// 在 React/Vue 等前端框架中使用
<div style={{ color: SOURCE_COLORS[item.price_source_code] }}>
{item.price_source_desc}
</div>
注意事项
- 唯一性:
price_source_code是数据源的唯一标识,建议在业务逻辑中使用 - 兼容性: 原有的
price_source字段保留,用于显示中文名称 - 索引优化: 已为
price_source_code和data_origin添加索引,查询性能更好 - 数据迁移: 如果已有数据,运行迁移脚本会自动添加新字段并设置默认值
故障排查
问题 1: 迁移后新字段为空
原因: 旧数据没有标识字段信息
解决方案:
-- 更新旧数据的标识字段
UPDATE prices SET
price_source_code = CASE
WHEN price_source = '云南钢协' THEN 'YUNNAN_STEEL_ASSOC'
WHEN price_source = '我的钢铁' THEN 'MY_STEEL'
WHEN price_source = '德钢指导价' THEN 'DE_STEEL_FACTORY'
ELSE 'UNKNOWN'
END,
price_source_desc = price_source,
data_origin = 'LOCAL_FILE'
WHERE data_origin = '' OR data_origin IS NULL;
问题 2: 导入数据时字段未填充
原因: 导入脚本版本过旧
解决方案:
# 确保使用最新的 import-data.js
git pull origin main
npm run db:import:api