From ba478d70cc69493a9113f75aa6b2be01e61be243 Mon Sep 17 00:00:00 2001 From: bai <996365438@qq.com> Date: Tue, 6 Jan 2026 09:19:12 +0800 Subject: [PATCH] =?UTF-8?q?init=EF=BC=9A=E4=BB=A3=E7=A0=81=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/index.json | 271 ++++ .env.example | 13 + .gitignore | 34 + CLAUDE.md | 480 +++++++ README.md | 471 +++++- data/CLAUDE.md | 417 ++++++ data/刚协指导价.json | 1616 +++++++++++++++++++++ data/钢厂指导价.json | 1616 +++++++++++++++++++++ data/钢材网架.json | 1916 +++++++++++++++++++++++++ docs/API_DOCUMENTATION.md | 228 +++ docs/API_RESPONSE_FORMAT.md | 229 +++ docs/IMPORT_API.md | 299 ++++ docs/PROJECT_STATUS.md | 219 +++ docs/QUICK_START.md | 141 ++ docs/SWAGGER_IMPLEMENTATION_REPORT.md | 328 +++++ docs/SWAGGER_SUMMARY.md | 319 ++++ package.json | 31 + pnpm-lock.yaml | 975 +++++++++++++ scripts/import-data.js | 159 ++ scripts/init-db.js | 94 ++ src/app.js | 46 + src/config/database.js | 28 + src/config/logger.js | 48 + src/config/swagger.js | 336 +++++ src/controllers/priceController.js | 65 + src/middlewares/errorHandler.js | 74 + src/middlewares/validator.js | 126 ++ src/models/Price.js | 383 +++++ src/models/index.js | 5 + src/routes/api.js | 532 +++++++ src/routes/index.js | 44 + src/server.js | 56 + src/services/priceService.js | 200 +++ src/utils/validator.js | 119 ++ 34 files changed, 11917 insertions(+), 1 deletion(-) create mode 100644 .claude/index.json create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 CLAUDE.md create mode 100644 data/CLAUDE.md create mode 100644 data/刚协指导价.json create mode 100644 data/钢厂指导价.json create mode 100644 data/钢材网架.json create mode 100644 docs/API_DOCUMENTATION.md create mode 100644 docs/API_RESPONSE_FORMAT.md create mode 100644 docs/IMPORT_API.md create mode 100644 docs/PROJECT_STATUS.md create mode 100644 docs/QUICK_START.md create mode 100644 docs/SWAGGER_IMPLEMENTATION_REPORT.md create mode 100644 docs/SWAGGER_SUMMARY.md create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 scripts/import-data.js create mode 100644 scripts/init-db.js create mode 100644 src/app.js create mode 100644 src/config/database.js create mode 100644 src/config/logger.js create mode 100644 src/config/swagger.js create mode 100644 src/controllers/priceController.js create mode 100644 src/middlewares/errorHandler.js create mode 100644 src/middlewares/validator.js create mode 100644 src/models/Price.js create mode 100644 src/models/index.js create mode 100644 src/routes/api.js create mode 100644 src/routes/index.js create mode 100644 src/server.js create mode 100644 src/services/priceService.js create mode 100644 src/utils/validator.js diff --git a/.claude/index.json b/.claude/index.json new file mode 100644 index 0000000..f507387 --- /dev/null +++ b/.claude/index.json @@ -0,0 +1,271 @@ +{ + "metadata": { + "project_name": "steel_prices_service", + "description": "钢材价格数据解析与查询服务(Express.js + MySQL)", + "last_scan": "2026-01-05T16:13:47+08:00", + "scan_version": "1.0.0", + "scanner": "AI Context Architect (Adaptive)" + }, + "statistics": { + "total_files_estimated": 7, + "files_scanned": 7, + "coverage_percentage": 100, + "directories_found": 3, + "modules_identified": 2, + "languages_detected": ["JSON", "Markdown"], + "ignore_patterns_applied": [ + "node_modules/**", + ".git/**", + ".github/**", + "dist/**", + "build/**", + ".next/**", + "__pycache__/**", + "*.lock", + "*.log", + "*.bin", + "*.pdf", + "*.png", + "*.jpg", + "*.jpeg", + "*.gif", + "*.mp4", + "*.zip", + "*.tar", + "*.gz" + ] + }, + "modules": [ + { + "name": "root", + "path": "./", + "type": "root", + "language": "JavaScript/Node.js (planned)", + "description": "钢材价格服务根目录(项目初始阶段)", + "entry_points": [], + "interfaces": [], + "dependencies": [], + "data_models": [], + "tests": [], + "documentation": "CLAUDE.md", + "coverage": { + "has_entry": false, + "has_interfaces": false, + "has_tests": false, + "has_data_models": false, + "has_documentation": true + }, + "status": "initial" + }, + { + "name": "data", + "path": "data/", + "type": "data", + "language": "JSON", + "description": "钢材价格数据存储目录", + "entry_points": [], + "interfaces": [], + "dependencies": [], + "data_models": [ + { + "name": "SteelPriceData", + "source": "钢材网架.json, 钢厂指导价.json, 刚协指导价.json", + "total_records": 31098, + "fields": [ + "GOODS_MATERIAL", + "GOODS_SPEC", + "PIRCE_DATE", + "PARTSNAME_NAME", + "PRODUCTAREA_NAME", + "PRICE_ID", + "PR_PRICE_SOURCE", + "PR_PRICE_REGION", + "PNTREE_NAME", + "PR_PRICESET_MAKEPRICE", + "PR_LAST_PRICESET_MAKEPRICE", + "PR_MAKEPRICE_UPDW", + "PR_PRICESET_HANGPRICE", + "PR_LAST_PRICESET_HANGPRICE", + "PR_HANGPRICE_UPDW", + "OPERATOR_CODE", + "OPERATOR_NAME" + ] + } + ], + "tests": [], + "documentation": "data/CLAUDE.md", + "coverage": { + "has_entry": false, + "has_interfaces": false, + "has_tests": false, + "has_data_models": true, + "has_documentation": true + }, + "status": "completed" + } + ], + "gaps": [ + { + "module": "root", + "missing": [ + "package.json (Node.js 项目配置)", + "src/ 目录(源代码)", + "app.js 或 index.js (Express 应用入口)", + "config/ 目录(配置文件)", + "routes/ 目录(API 路由)", + "models/ 目录(数据模型)", + "services/ 目录(业务逻辑)", + "scripts/ 目录(工具脚本)", + "tests/ 目录(测试代码)", + ".env.example (环境变量示例)", + ".gitignore (Git 忽略规则)", + "数据库表结构定义" + ], + "priority": "high", + "recommendation": "项目处于初始阶段,需要搭建完整的 Express.js 项目结构" + }, + { + "module": "data", + "missing": [ + "数据验证模块", + "数据导入脚本", + "数据更新定时任务" + ], + "priority": "medium", + "recommendation": "实现 JSON 数据解析与数据库导入功能" + } + ], + "next_steps": [ + "初始化 Node.js 项目 (npm init -y)", + "安装核心依赖 (express, mysql2, dotenv, cors)", + "创建标准项目目录结构 (src/, config/, routes/, models/, services/)", + "设计并创建 MySQL 数据库表结构", + "实现 JSON 数据解析模块 (services/parser.js)", + "实现数据库连接与模型 (config/database.js, models/Price.js)", + "实现数据导入脚本 (scripts/import-data.js)", + "开发价格查询 API 接口 (routes/prices.js)", + "编写单元测试与集成测试", + "添加 ESLint 和 Prettier 配置", + "创建 Docker 镜像与部署配置", + "编写 API 文档 (Swagger/OpenAPI)" + ], + "tech_stack": { + "backend": "Express.js (Node.js)", + "database": "MySQL 8.0+", + "data_format": "JSON", + "api_style": "RESTful", + "testing": "Jest + Supertest (planned)", + "deployment": "Docker (planned)" + }, + "architecture_overview": { + "layers": [ + "数据采集层(我的钢铁网、钢厂官方、行业协会)", + "数据处理层(JSON 解析、数据清洗、验证、转换)", + "数据存储层(MySQL 数据库、索引优化、定时归档)", + "服务接口层(Express.js REST API、价格查询、趋势分析)" + ], + "data_flow": "外部数据源 → JSON 文件 → 解析与清洗 → MySQL 数据库 → Express API → 客户端" + }, + "development_roadmap": { + "phase_1": { + "name": "基础搭建", + "duration": "1-2 周", + "tasks": [ + "初始化 Node.js 项目", + "创建数据库表结构", + "实现 JSON 数据解析模块", + "实现数据导入脚本", + "基础 API 框架搭建" + ] + }, + "phase_2": { + "name": "核心功能", + "duration": "2-3 周", + "tasks": [ + "价格查询 API(按地区、材质、日期)", + "价格统计 API(平均价、最高价、最低价)", + "趋势分析 API(涨跌幅、历史曲线)", + "数据验证与清洗逻辑", + "错误处理与日志记录" + ] + }, + "phase_3": { + "name": "增强功能", + "duration": "1-2 周", + "tasks": [ + "定时任务自动采集数据", + "数据变更通知", + "数据导出功能(Excel、CSV)", + "API 文档(Swagger)", + "性能优化与缓存" + ] + }, + "phase_4": { + "name": "测试与部署", + "duration": "1 周", + "tasks": [ + "单元测试覆盖", + "集成测试", + "Docker 容器化", + "CI/CD 流程", + "生产环境部署" + ] + } + }, + "data_assets": { + "sources": [ + { + "name": "我的钢铁网", + "file": "data/钢材网架.json", + "records": 211, + "regions": ["重庆", "成都", "广州", "南宁"], + "updated": "2026-01-05" + }, + { + "name": "德钢指导价", + "file": "data/钢厂指导价.json", + "records": 29987, + "regions": ["玉溪", "昭通", "文山", "景洪", "蒙自"], + "updated": "2025-09-04" + }, + { + "name": "云南钢协", + "file": "data/刚协指导价.json", + "records": 900, + "regions": ["昆明", "玉溪", "楚雄", "大理"], + "updated": "2026-01-05" + } + ], + "total_records": 31098, + "data_format": "JSON with pagination wrapper", + "quality_issues": [ + "字段命名错误 (PIRCE_DATE 应为 PRICE_DATE)", + "钢厂指导价数据日期较旧 (2025-09-04)", + "不同文件字段略有差异" + ] + }, + "truncated": false, + "truncation_reason": null, + "ignore_stats": { + "ignored_dirs": [".git"], + "ignored_files_count": 0, + "total_ignored_size_kb": 0 + }, + "recommendations": { + "immediate": [ + "创建 package.json 并安装依赖", + "设计 MySQL 数据库表结构", + "实现数据导入脚本" + ], + "short_term": [ + "搭建 Express.js 基础框架", + "实现核心查询 API", + "添加基础测试" + ], + "long_term": [ + "实现自动化数据采集", + "性能优化与缓存", + "Docker 容器化部署" + ] + } +} diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..eabdde0 --- /dev/null +++ b/.env.example @@ -0,0 +1,13 @@ +# 服务器配置 +NODE_ENV=development +PORT=3000 + +# 数据库配置 +DB_HOST=localhost +DB_PORT=3306 +DB_NAME=steel_prices +DB_USER=root +DB_PASSWORD=your_password + +# 日志配置 +LOG_LEVEL=info diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c6e35a7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# 依赖 +node_modules/ +package-lock.json + +# 环境变量 +.env + +# 日志 +logs/ +*.log +npm-debug.log* + +# 操作系统 +.DS_Store +Thumbs.db + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# 测试覆盖率 +coverage/ +.nyc_output/ + +# 构建产物 +dist/ +build/ + +# 临时文件 +tmp/ +temp/ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..a7acde6 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,480 @@ +# steel_prices_service - 钢材价格服务 + +> **项目状态**: 🌱 初始阶段(数据准备完成,待开发服务层) +> +> **最后更新**: 2026-01-05 16:13:47 + +--- + +## 变更记录 (Changelog) + +### 2026-01-05 16:13:47 +- 初始化根级文档 +- 完成项目结构分析 +- 识别数据模块并生成模块文档 +- 创建 Mermaid 架构图 +- 定义开发路线图 + +--- + +## 项目愿景 + +**steel_prices_service** 是一个钢材价格数据解析与查询服务,旨在: + +1. **数据整合**: 从多个来源(我的钢铁网、钢厂官方、行业协会)采集钢材价格数据 +2. **标准化存储**: 使用 MySQL 数据库统一存储和管理价格数据 +3. **高效查询**: 提供快速、灵活的价格查询 API +4. **实时更新**: 支持定时任务自动采集和更新价格数据 + +### 核心价值 + +- 为钢材采购决策提供实时市场价格参考 +- 支持历史价格趋势分析 +- 多地区、多钢厂价格对比 +- 自动化数据采集减少人工成本 + +--- + +## 架构总览 + +### 技术栈(规划中) + +根据项目 README 和数据结构,预计技术栈为: + +- **后端框架**: Express.js (Node.js) +- **数据库**: MySQL +- **数据格式**: JSON(导入格式) +- **API 设计**: RESTful + +> 注意:项目目前处于数据准备阶段,尚未实现服务代码。 + +### 系统架构 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ 数据采集层 │ +│ 我的钢铁网 │ 钢厂官方 │ 行业协会 │ 手动导入 │ +└─────────────────────┬───────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ 数据处理层 │ +│ JSON 解析 │ 数据清洗 │ 验证 │ 转换 │ +└─────────────────────┬───────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ 数据存储层 │ +│ MySQL 数据库 │ +│ 价格表 │ 索引优化 │ 定时归档 │ +└─────────────────────┬───────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ 服务接口层 │ +│ Express.js REST API │ +│ 价格查询 │ 趋势分析 │ 数据导出 │ +└─────────────────────────────────────────────────────────────┘ +``` + +--- + +## 模块结构图 + +```mermaid +graph TD + Root["steel_prices_service
(根目录)"] + Root --> Data["data/
📦 数据模块"] + + click Data "d:/Code/steel_prices_service/data/CLAUDE.md" "查看 data 模块文档" + + style Root fill:#e1f5ff,stroke:#01579b,stroke-width:3px + style Data fill:#fff9c4,stroke:#f57f17,stroke-width:2px +``` + +--- + +## 模块索引 + +| 模块名 | 路径 | 职责 | 状态 | 文档 | +|--------|------|------|------|------| +| **数据模块** | `data/` | 存储和管理钢材价格原始数据(JSON 格式) | ✅ 已完成 | [查看文档](./data/CLAUDE.md) | +| **服务模块** | (待创建) | Express.js 服务、API 接口 | ⏳ 待开发 | - | +| **数据导入** | (待创建) | JSON 解析、数据清洗、数据库导入 | ⏳ 待开发 | - | +| **测试模块** | (待创建) | 单元测试、集成测试 | ⏳ 待开发 | - | + +--- + +## 数据资产 + +### 当前数据 + +| 数据源 | 文件 | 记录数 | 地区覆盖 | 更新日期 | +|--------|------|--------|----------|----------| +| **我的钢铁网** | `data/钢材网架.json` | 211+ 条 | 重庆、成都、广州、南宁 | 2026-01-05 | +| **德钢指导价** | `data/钢厂指导价.json` | 29,987 条 | 云南省内(玉溪、昭通等) | 2025-09-04 | +| **云南钢协** | `data/刚协指导价.json` | 900 条 | 昆明、玉溪、楚雄、大理 | 2026-01-05 | + +### 数据模型 + +所有价格数据遵循统一的结构,包含以下关键字段: + +- **商品信息**: 材质 (GOODS_MATERIAL)、规格 (GOODS_SPEC)、品名 (PARTSNAME_NAME) +- **价格信息**: 挂牌价、钢厂价、涨跌幅 +- **来源信息**: 钢厂 (PRODUCTAREA_NAME)、地区 (PR_PRICE_REGION)、来源 (PR_PRICE_SOURCE) +- **时间信息**: 价格日期 (PIRCE_DATE) +- **唯一标识**: PRICE_ID + +详细数据结构请参考 [data/CLAUDE.md](./data/CLAUDE.md) + +--- + +## 运行与开发 + +### 当前状态 + +项目目前只有数据文件,尚未搭建服务层代码。 + +### 建议的开发环境 + +- **Node.js**: v18+ (推荐使用 LTS 版本) +- **MySQL**: 8.0+ +- **包管理器**: npm 或 yarn + +### 推荐的项目结构 + +``` +steel_prices_service/ +├── data/ # 数据文件目录(已存在) +│ ├── 钢材网架.json +│ ├── 钢厂指导价.json +│ └── 刚协指导价.json +├── src/ # 源代码目录(待创建) +│ ├── app.js # Express 应用入口 +│ ├── config/ # 配置文件 +│ │ └── database.js # 数据库连接配置 +│ ├── routes/ # API 路由 +│ │ └── prices.js # 价格查询接口 +│ ├── models/ # 数据模型 +│ │ └── Price.js # 价格数据模型 +│ ├── services/ # 业务逻辑 +│ │ ├── parser.js # JSON 解析服务 +│ │ ├── importer.js # 数据导入服务 +│ │ └── query.js # 查询服务 +│ └── utils/ # 工具函数 +│ └── validator.js # 数据验证 +├── scripts/ # 脚本目录(待创建) +│ └── import-data.js # 数据导入脚本 +├── tests/ # 测试目录(待创建) +│ ├── unit/ # 单元测试 +│ └── integration/ # 集成测试 +├── .env.example # 环境变量示例(待创建) +├── .gitignore # Git 忽略规则(待创建) +├── package.json # 项目配置(待创建) +├── README.md # 项目说明(已存在) +└── CLAUDE.md # AI 文档(本文件) +``` + +### 初始化步骤 + +1. **初始化 Node.js 项目** + ```bash + npm init -y + ``` + +2. **安装依赖** + ```bash + npm install express mysql2 dotenv cors + npm install --save-dev nodemon jest + ``` + +3. **创建数据库表** + ```sql + 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) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='钢材价格表'; + ``` + +4. **配置环境变量** (.env) + ```env + DB_HOST=localhost + DB_PORT=3306 + DB_USER=root + DB_PASSWORD=your_password + DB_NAME=steel_prices + PORT=3000 + NODE_ENV=development + ``` + +5. **导入数据** + ```bash + node scripts/import-data.js + ``` + +6. **启动服务** + ```bash + npm start + ``` + +--- + +## 测试策略 + +### 测试金字塔(建议) + +``` + ┌──────────────┐ + / E2E 测试 \ (端到端测试) + /__________________\ + / 集成测试 (API) \ (API 接口测试) + /______________________\ + / 单元测试 (业务逻辑) \ (函数/类测试) + /____________________________\ +``` + +### 测试工具推荐 + +- **单元测试**: Jest + Supertest +- **集成测试**: Jest + Test Database +- **E2E 测试**: Cypress 或 Playwright +- **API 测试**: Postman + Newman + +### 关键测试场景 + +1. **数据导入测试** + - JSON 文件解析正确性 + - 数据验证与清洗 + - 重复数据处理 + - 批量插入性能 + +2. **API 接口测试** + - 价格查询接口(按地区、材质、日期) + - 数据统计接口(平均价、涨跌幅) + - 错误处理(无效参数、数据不存在) + +3. **性能测试** + - 大数据量查询响应时间 + - 并发请求处理能力 + - 数据库索引效果验证 + +--- + +## 编码规范 + +### JavaScript/Node.js 规范(建议) + +1. **代码风格** + - 使用 ESLint + Prettier + - 采用 Airbnb Style Guide + - 强制使用分号 + +2. **命名约定** + - 变量和函数:camelCase + - 类和构造函数:PascalCase + - 常量:UPPER_SNAKE_CASE + - 文件名:kebab-case + +3. **注释规范** + - JSDoc 格式文档注释 + - 关键业务逻辑必须注释 + - API 接口使用 OpenAPI/Swagger 文档 + +4. **错误处理** + - 使用 async/await + try-catch + - 统一错误中间件 + - 详细的错误日志 + +### SQL 规范 + +- 表名:snake_case +- 字段名:snake_case +- 索引名:idx_表名_字段名 +- 必须添加字段注释 + +--- + +## AI 使用指引 + +### 给 AI 的提示词模板 + +#### 1. 数据库相关 +``` +"请根据 data/CLAUDE.md 中的数据结构,设计 MySQL 建表语句" +``` + +#### 2. API 开发 +``` +"请创建 Express.js 路由,实现按地区和材质查询价格的功能" +``` + +#### 3. 数据导入 +``` +"请编写 Node.js 脚本,将 data/*.json 文件导入到 MySQL 数据库" +``` + +#### 4. 性能优化 +``` +"请优化价格查询接口,支持快速查询最近30天的平均价格" +``` + +### 项目上下文快速加载 + +在与 AI 对话时,可以这样说: + +> "我正在开发 steel_prices_service 项目,这是一个钢材价格查询服务。项目使用 Express.js + MySQL,数据文件在 data/ 目录下。请参考根目录的 CLAUDE.md 了解项目结构。" + +--- + +## 开发路线图 + +### 第一阶段:基础搭建(预计 1-2 周) + +- [ ] 初始化 Node.js 项目 +- [ ] 创建数据库表结构 +- [ ] 实现 JSON 数据解析模块 +- [ ] 实现数据导入脚本 +- [ ] 基础 API 框架搭建 + +### 第二阶段:核心功能(预计 2-3 周) + +- [ ] 价格查询 API(按地区、材质、日期) +- [ ] 价格统计 API(平均价、最高价、最低价) +- [ ] 趋势分析 API(涨跌幅、历史曲线) +- [ ] 数据验证与清洗逻辑 +- [ ] 错误处理与日志记录 + +### 第三阶段:增强功能(预计 1-2 周) + +- [ ] 定时任务自动采集数据 +- [ ] 数据变更通知 +- [ ] 数据导出功能(Excel、CSV) +- [ ] API 文档(Swagger) +- [ ] 性能优化与缓存 + +### 第四阶段:测试与部署(预计 1 周) + +- [ ] 单元测试覆盖 +- [ ] 集成测试 +- [ ] Docker 容器化 +- [ ] CI/CD 流程 +- [ ] 生产环境部署 + +--- + +## 常见问题 (FAQ) + +### Q: 为什么选择 Express.js 而不是其他框架? + +A: Express.js 是成熟稳定的 Node.js 框架,具有以下优势: +- 轻量级,灵活性高 +- 中间件生态丰富 +- 社区活跃,文档完善 +- 适合构建 RESTful API + +如果需要更完整的解决方案,也可以考虑 NestJS 或 Fastify。 + +### Q: 数据库如何选择? + +A: 根据项目特点,MySQL 是合适的选择: +- 结构化数据,关系清晰 +- 事务支持强 +- 索引优化成熟 +- 运维成本低 + +未来如果数据量激增,可考虑: +- 分库分表(Sharding) +- 时序数据库(InfluxDB) +- 数据仓库(ClickHouse) + +### Q: 如何保证数据一致性? + +A: 建议采用以下策略: +1. 使用 PRICE_ID 作为唯一标识,避免重复导入 +2. 使用 UPSERT 语句(INSERT ... ON DUPLICATE KEY UPDATE) +3. 添加数据校验和(checksum) +4. 记录数据导入日志 + +### Q: 如何处理大量历史数据? + +A: 建议采用以下策略: +1. 按日期分表(如 `steel_prices_2025_01`) +2. 定期归档历史数据(如 2 年前的数据) +3. 使用冷热数据分离(热数据在 SSD,冷数据在 HDD) +4. 考虑使用时序数据库或数据仓库 + +--- + +## 相关资源 + +### 技术文档 + +- [Express.js 官方文档](https://expressjs.com/) +- [MySQL 文档](https://dev.mysql.com/doc/) +- [Node.js 最佳实践](https://github.com/goldbergyoni/nodebestpractices) + +### 相关工具 + +- **API 测试**: Postman, Insomnia +- **数据库管理**: MySQL Workbench, DBeaver +- **代码质量**: ESLint, Prettier +- **版本控制**: Git + GitHub + +--- + +## 贡献指南 + +### 开发流程 + +1. Fork 本仓库 +2. 创建特性分支 (`git checkout -b feature/AmazingFeature`) +3. 提交更改 (`git commit -m 'Add some AmazingFeature'`) +4. 推送到分支 (`git push origin feature/AmazingFeature`) +5. 开启 Pull Request + +### Commit 规范 + +遵循 Conventional Commits 规范: + +``` +feat: 添加价格查询接口 +fix: 修复数据导入时的编码问题 +docs: 更新 API 文档 +style: 代码格式化 +refactor: 重构数据验证逻辑 +test: 添加单元测试 +chore: 更新依赖包 +``` + +--- + +## 联系方式 + +- **项目位置**: `d:\Code\steel_prices_service` +- **文档维护**: AI Context Architect +- **最后更新**: 2026-01-05 16:13:47 + +--- + +**导航**: [data/ 模块文档](./data/CLAUDE.md) | [GitHub](https://github.com) | [API 文档](#) (待开发) diff --git a/README.md b/README.md index d108785..4e3a3e9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,471 @@ -# steel_prices_service +# 🏗️ Steel Prices Service +> 一个专业的钢材价格查询与分析服务平台 + +[![Node.js](https://img.shields.io/badge/Node.js-Express.js-green)](https://nodejs.org/) +[![Database](https://img.shields.io/badge/Database-MySQL-blue)](https://www.mysql.com/) +[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) +[![Status](https://img.shields.io/badge/Status-🌱%20Initial-orange)](https://github.com) + +--- + +## 📖 项目简介 + +Steel Prices Service 是一个基于 **Express.js + MySQL** 的钢材价格数据管理与查询服务。项目致力于为钢材行业提供实时、准确的价格数据查询、统计分析和趋势预测功能。 + +### 核心功能 + +- 📊 **数据解析与导入** - 支持 JSON 格式的钢材价格数据批量导入 +- 🔍 **灵活查询** - 按地区、材质、规格、日期范围等多维度查询 +- 📈 **统计分析** - 价格趋势分析、区域对比、均价计算 +- 🚀 **高性能** - 数据库索引优化,查询响应快速 +- 🔄 **定时更新** - 自动采集最新市场价格数据 +- 📱 **RESTful API** - 标准化接口设计,易于集成 + +--- + +## 🏗️ 技术架构 + +### 技术栈 + +| 层级 | 技术选型 | 说明 | +|------|----------|------| +| **后端框架** | Express.js | 轻量级 Node.js Web 框架 | +| **数据库** | MySQL 8.0+ | 关系型数据库,存储价格数据 | +| **API 文档** | Swagger (OpenAPI 3.0) | 交互式 API 文档 | +| **ORM** | Sequelize / 原生 SQL | 数据库操作抽象层 | +| **数据采集** | Axios + Cheerio | 网络爬虫,自动采集价格数据 | +| **任务调度** | node-cron | 定时任务,自动更新数据 | +| **测试** | Jest / Mocha | 单元测试与集成测试 | +| **容器化** | Docker | 应用容器化部署 | + +### 系统架构 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ 客户端层 (Client) │ +│ Web / Mobile App / Third Party │ +└─────────────────────────┬───────────────────────────────────┘ + │ HTTPS / REST API +┌─────────────────────────┴───────────────────────────────────┐ +│ 服务接口层 (API Layer) │ +│ ┌──────────────┐ ┌──────────────┐ │ +│ │ REST API │ │ WebSocket │ │ +│ └──────────────┘ └──────────────┘ │ +└─────────────────────────┬───────────────────────────────────┘ + │ +┌─────────────────────────┴───────────────────────────────────┐ +│ 业务逻辑层 (Service Layer) │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │ 查询服务 │ │ 统计服务 │ │ 采集服务 │ │ +│ └──────────────┘ └──────────────┘ └──────────────┘ │ +└─────────────────────────┬───────────────────────────────────┘ + │ +┌─────────────────────────┴───────────────────────────────────┐ +│ 数据访问层 (Data Layer) │ +│ ┌──────────────┐ │ +│ │ MySQL │ │ +│ │ (主存储) │ │ +│ └──────────────┘ │ +└─────────────────────────────────────────────────────────────┘ +``` + +--- + +## 📦 数据资产 + +项目当前包含 **31,098 条**钢材价格数据记录: + +| 数据源 | 记录数 | 覆盖地区 | 更新日期 | 状态 | +|--------|--------|----------|----------|------| +| **我的钢铁网** | 211 条 | 重庆、成都、广州、南宁 | 2026-01-05 | ✅ 新鲜 | +| **德钢指导价** | 29,987 条 | 云南(玉溪、昭通等) | 2025-09-04 | ⚠️ 陈旧 | +| **云南钢协** | 900 条 | 昆明、玉溪、楚雄、大理 | 2026-01-05 | ✅ 新鲜 | + +数据文件位于 [`data/`](data/) 目录,详见 [data/CLAUDE.md](data/CLAUDE.md)。 + +--- + +## 🚀 快速开始 + +### 环境要求 + +- **Node.js**: >= 16.x +- **MySQL**: >= 8.0 + +### 安装步骤 + +#### 1. 克隆项目 + +```bash +git clone https://github.com/your-username/steel_prices_service.git +cd steel_prices_service +``` + +#### 2. 安装依赖 + +```bash +npm install +``` + +#### 3. 配置环境变量 + +复制 `.env.example` 到 `.env` 并配置: + +```bash +cp .env.example .env +``` + +编辑 `.env` 文件: + +```env +# 服务器配置 +NODE_ENV=development +PORT=3000 + +# 数据库配置 +DB_HOST=localhost +DB_PORT=3306 +DB_NAME=steel_prices +DB_USER=root +DB_PASSWORD=your_password + +# 日志配置 +LOG_LEVEL=info +``` + +#### 4. 初始化数据库 + +```bash +# 创建数据库 +mysql -u root -p -e "CREATE DATABASE steel_prices CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" + +# 导入表结构(使用 scripts/init-db.sql 或运行初始化脚本) +npm run db:init + +# 导入数据(从 data/ 目录的 JSON 文件) +npm run db:import +``` + +#### 5. 启动服务 + +```bash +# 开发模式(热重载) +npm run dev + +# 生产模式 +npm start +``` + +服务将在 `http://localhost:3000` 启动。 + +--- + +## 📚 API 文档 + +### 📖 交互式文档(Swagger UI) + +启动服务后,访问 **Swagger UI** 查看完整的 API 文档: + +``` +http://localhost:3000/api-docs +``` + +**功能特性:** +- 📖 完整的 API 接口文档 +- 🧪 直接在浏览器中测试 API +- 📝 详细的请求/响应示例 +- 🔍 参数说明和验证规则 +- 🎨 美观的交互式界面 + +详细使用说明请查看:[API 文档指南](docs/API_DOCUMENTATION.md) + +### 基础信息 + +- **Base URL**: `http://localhost:3000/api` +- **数据格式**: JSON +- **字符编码**: UTF-8 +- **API 规范**: OpenAPI 3.0 + +### 核心接口 + +#### 1. 按地区查询价格 + +```http +GET /api/prices/region?region=昆明&date=2026-01-05 +``` + +**响应示例**: + +```json +{ + "success": true, + "data": [ + { + "id": 1, + "region": "昆明", + "material": "螺纹钢", + "specification": "HRB400 Φ16-25mm", + "price": 4200, + "unit": "元/吨", + "date": "2026-01-05", + "source": "云南钢协" + } + ], + "total": 1 +} +``` + +#### 2. 按材质和规格查询 + +```http +GET /api/prices/search?material=螺纹钢&specification=HRB400&startDate=2026-01-01&endDate=2026-01-05 +``` + +#### 3. 价格统计分析 + +```http +GET /api/prices/stats?region=昆明&material=螺纹钢&days=30 +``` + +**响应示例**: + +```json +{ + "success": true, + "data": { + "avgPrice": 4250.5, + "minPrice": 4100, + "maxPrice": 4400, + "trend": "up", + "changeRate": "+2.5%" + } +} +``` + +#### 4. 数据导入 + +```http +POST /api/import +Content-Type: multipart/form-data + +file: prices.json +``` + +### 完整 API 文档 + +详细的 API 文档请查看: +- **Swagger UI**: `http://localhost:3000/api-docs` (推荐) +- **JSON 规范**: `http://localhost:3000/api-docs.json` +- **使用指南**: [API Documentation](docs/API_DOCUMENTATION.md) + +--- + +## 🧪 测试 + +```bash +# 运行所有测试 +npm test + +# 运行单元测试 +npm run test:unit + +# 运行集成测试 +npm run test:integration + +# 生成测试覆盖率报告 +npm run test:coverage +``` + +--- + +## 📁 项目结构 + +``` +steel_prices_service/ +├── src/ # 源代码目录 +│ ├── config/ # 配置文件 +│ │ ├── database.js # 数据库配置 +│ │ └── logger.js # 日志配置 +│ ├── controllers/ # 控制器层 +│ │ ├── priceController.js +│ │ └── importController.js +│ ├── services/ # 业务逻辑层 +│ │ ├── priceService.js +│ │ ├── statsService.js +│ │ └── crawlService.js +│ ├── models/ # 数据模型 +│ │ ├── Price.js +│ │ └── index.js +│ ├── routes/ # 路由定义 +│ │ ├── api.js +│ │ └── index.js +│ ├── middlewares/ # 中间件 +│ │ ├── errorHandler.js +│ │ └── validator.js +│ ├── utils/ # 工具函数 +│ │ ├── csvParser.js +│ │ └── dateHelper.js +│ ├── tasks/ # 定时任务 +│ │ └── priceCrawler.js +│ └── app.js # Express 应用入口 +├── data/ # 数据文件目录 +│ ├── 钢材网架.json +│ ├── 钢厂指导价.json +│ ├── 刚协指导价.json +│ └── CLAUDE.md # 数据模块文档 +├── scripts/ # 脚本目录 +│ ├── init-db.sql # 数据库初始化脚本 +│ └── import-data.js # 数据导入脚本 +├── tests/ # 测试目录 +│ ├── unit/ +│ └── integration/ +├── docs/ # 文档目录 +│ ├── api.md # API 文档 +│ └── architecture.md # 架构设计文档 +├── .env.example # 环境变量示例 +├── .gitignore # Git 忽略文件 +├── docker-compose.yml # Docker 编排文件 +├── Dockerfile # Docker 镜像构建文件 +├── package.json # 项目配置 +├── CLAUDE.md # 项目 AI 上下文文档 +└── README.md # 项目说明文档 +``` + +--- + +## 🔧 开发指南 + +### 编码规范 + +项目遵循以下编码规范(详见 [CLAUDE.md](CLAUDE.md)): + +- **SOLID 原则** - 单一职责、开闭原则、里氏替换、接口隔离、依赖倒置 +- **KISS 原则** - 保持代码简单直接 +- **DRY 原则** - 避免代码重复 +- **YAGNI 原则** - 只实现必要功能 + +### 提交规范 + +使用 [Conventional Commits](https://www.conventionalcommits.org/) 规范: + +```bash +feat: 新功能 +fix: 修复 Bug +docs: 文档更新 +style: 代码格式调整 +refactor: 重构 +test: 测试相关 +chore: 构建/工具链更新 +``` + +### 开发路线图 + +详见 [CLAUDE.md - 开发路线图](CLAUDE.md#开发路线图)。 + +#### 当前阶段:🌱 阶段 1 - 数据准备与验证(进行中) + +- [x] 数据收集(31,098 条记录) +- [ ] 数据库设计与建表 +- [ ] 数据导入脚本开发 +- [ ] 数据验证与清洗 + +#### 后续阶段 + +- **阶段 2**: 核心服务开发(API 开发) +- **阶段 3**: 数据采集自动化(定时任务) +- **阶段 4**: 智能分析与预测(AI 集成) + +--- + +## 🐳 Docker 部署 + +### 使用 Docker Compose(推荐) + +```bash +# 启动所有服务(MySQL + App) +docker-compose up -d + +# 查看日志 +docker-compose logs -f + +# 停止服务 +docker-compose down +``` + +### 单独构建 + +```bash +# 构建镜像 +docker build -t steel-prices-service . + +# 运行容器 +docker run -p 3000:3000 --env-file .env steel-prices-service +``` + +--- + +## 🤝 贡献指南 + +欢迎贡献代码、报告 Bug 或提出新功能建议! + +### 贡献流程 + +1. Fork 本仓库 +2. 创建特性分支 (`git checkout -b feature/AmazingFeature`) +3. 提交更改 (`git commit -m 'feat: Add some AmazingFeature'`) +4. 推送到分支 (`git push origin feature/AmazingFeature`) +5. 提交 Pull Request + +### 代码审查 + +- 确保代码通过所有测试 (`npm test`) +- 遵循项目编码规范 +- 添加必要的注释和文档 +- 更新相关文档 + +详见 [贡献指南](CONTRIBUTING.md)。 + +--- + +## 📄 许可证 + +本项目采用 [MIT 许可证](LICENSE)。 + +--- + +## 📞 联系方式 + +- **作者**: Your Name +- **邮箱**: your.email@example.com +- **项目主页**: [https://github.com/your-username/steel_prices_service](https://github.com/your-username/steel_prices_service) +- **问题反馈**: [GitHub Issues](https://github.com/your-username/steel_prices_service/issues) + +--- + +## 🙏 致谢 + +- 数据来源:我的钢铁网、德钢、云南钢协 +- 技术栈:Express.js、MySQL +- 社区贡献者 + +--- + +## 📊 项目状态 + +![Status](https://img.shields.io/badge/Status-🌱%20Initial%20Development-orange) +![Progress](https://img.shields.io/badge/Progress-10%25-yellow) + +**当前版本**: v0.1.0 (Alpha) + +**最近更新**: 2026-01-05 + +--- + +
+ +**如果这个项目对您有帮助,请给一个 ⭐️ Star 支持一下!** + +[⬆ 返回顶部](#-steel-prices-service) + +
\ No newline at end of file diff --git a/data/CLAUDE.md b/data/CLAUDE.md new file mode 100644 index 0000000..613873f --- /dev/null +++ b/data/CLAUDE.md @@ -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) diff --git a/data/刚协指导价.json b/data/刚协指导价.json new file mode 100644 index 0000000..83c4c28 --- /dev/null +++ b/data/刚协指导价.json @@ -0,0 +1,1616 @@ +{ + "code": 0, + "isZip": 0, + "isDes": 0, + "data": { + "page": { + "result": [ + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672768", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 4040, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4040, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672769", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3840, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3840, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672770", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3840, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3840, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672771", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3890, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3890, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672772", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 4170, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4170, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672773", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3840, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3840, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672774", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3840, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3840, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672775", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3940, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3940, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "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, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3770, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ14", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672777", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3770, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3770, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ16", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672778", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3690, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3690, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ18", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672779", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3690, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3690, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ20", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672780", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3590, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3590, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ22", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672781", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3690, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3690, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ25", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672782", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3690, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3690, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ28", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672783", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3790, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3790, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ32", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672784", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3840, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3840, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ36", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672785", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 4040, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4040, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ40", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672786", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 4140, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4140, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672787", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 4070, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4070, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ14", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672788", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 4070, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4070, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ16", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672789", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3990, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3990, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ18", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672790", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3990, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3990, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ20", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672791", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3890, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3890, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ22", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672792", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3990, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3990, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ25", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672793", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 3990, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3990, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ28", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672794", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 4090, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4090, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ32", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672795", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 4140, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4140, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ36", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672796", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 4340, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4340, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ40", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672797", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "昆明", + "PR_LAST_PRICESET_HANGPRICE": 4440, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4440, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672798", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 4060, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4060, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672799", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3860, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3860, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672800", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3860, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3860, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672801", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3910, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3910, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672802", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 4190, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4190, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672803", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3860, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3860, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672804", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3860, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3860, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672805", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3960, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3960, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672806", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3790, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3790, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ14", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672807", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3790, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3790, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ16", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672808", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3710, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3710, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ18", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672809", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3710, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3710, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ20", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672810", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3610, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3610, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ22", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672811", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3710, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3710, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ25", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672812", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3710, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3710, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ28", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672813", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3810, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3810, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ32", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672814", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3860, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3860, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ36", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672815", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 4060, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4060, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ40", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672816", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 4160, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4160, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672817", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 4090, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4090, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ14", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672818", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 4090, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4090, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ16", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672819", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 4010, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4010, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ18", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672820", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 4010, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4010, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ20", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672821", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 3910, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3910, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ22", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672822", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 4010, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4010, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ25", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672823", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 4010, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4010, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ28", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672824", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 4110, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4110, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ32", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672825", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 4160, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4160, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ36", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672826", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 4360, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4360, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ40", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672827", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "玉溪", + "PR_LAST_PRICESET_HANGPRICE": 4460, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4460, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672828", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 4080, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4080, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672829", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3880, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3880, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672830", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3880, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3880, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672831", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3930, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3930, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672832", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 4210, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4210, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672833", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3880, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3880, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672834", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3880, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3880, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672835", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3980, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3980, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672836", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3810, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3810, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ14", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672837", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3810, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3810, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ16", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672838", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3730, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3730, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ18", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672839", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3730, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3730, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ20", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672840", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3630, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3630, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ22", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672841", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3730, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3730, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ25", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672842", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3730, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3730, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ28", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672843", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3830, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3830, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ32", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672844", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3880, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3880, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ36", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672845", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 4080, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4080, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ40", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672846", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 4180, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4180, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672847", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 4110, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4110, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ14", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672848", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 4110, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4110, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ16", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672849", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 4030, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4030, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ18", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672850", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 4030, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4030, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ20", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672851", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 3930, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3930, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ22", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672852", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 4030, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4030, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ25", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672853", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 4030, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4030, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ28", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672854", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 4130, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4130, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ32", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672855", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 4180, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4180, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ36", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672856", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 4380, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4380, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ40", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672857", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "楚雄", + "PR_LAST_PRICESET_HANGPRICE": 4480, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4480, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672858", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "大理", + "PR_LAST_PRICESET_HANGPRICE": 4110, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4110, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672859", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "大理", + "PR_LAST_PRICESET_HANGPRICE": 3910, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3910, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672860", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "大理", + "PR_LAST_PRICESET_HANGPRICE": 3910, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3910, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672861", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "大理", + "PR_LAST_PRICESET_HANGPRICE": 3960, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3960, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672862", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "大理", + "PR_LAST_PRICESET_HANGPRICE": 4240, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4240, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672863", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "大理", + "PR_LAST_PRICESET_HANGPRICE": 3910, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3910, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672864", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "大理", + "PR_LAST_PRICESET_HANGPRICE": 3910, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3910, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672865", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "大理", + "PR_LAST_PRICESET_HANGPRICE": 4010, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4010, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672866", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "大理", + "PR_LAST_PRICESET_HANGPRICE": 3840, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3840, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ14", + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "玉昆", + "PRICE_ID": "2008067775216672867", + "PR_PRICE_SOURCE": "云南钢协", + "PR_PRICE_REGION": "大理", + "PR_LAST_PRICESET_HANGPRICE": 3840, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3840, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + } + ], + "pageSize": 100, + "pageNo": 1, + "pageNumber": 1, + "totalCount": 900, + "totalPage": 9 + } + } +} \ No newline at end of file diff --git a/data/钢厂指导价.json b/data/钢厂指导价.json new file mode 100644 index 0000000..97cf0e8 --- /dev/null +++ b/data/钢厂指导价.json @@ -0,0 +1,1616 @@ +{ + "code": 0, + "isZip": 0, + "isDes": 0, + "data": { + "page": { + "result": [ + { + "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, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3320, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ40", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174382", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3450, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3420, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ36", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174381", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3350, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3320, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ32", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174380", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3150, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3120, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ28", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174379", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3100, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3070, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ25", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174378", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3000, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2970, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ22", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174377", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3000, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2970, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ20", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174376", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3000, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2970, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ18", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174375", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 2900, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2870, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ16", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174374", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3000, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2970, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ14", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174373", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3080, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3050, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174372", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3080, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3050, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174371", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3250, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3220, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174370", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3150, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3120, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174369", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3150, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3120, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174368", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3480, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3450, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174367", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3200, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3170, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174366", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3150, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3120, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174365", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3150, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3120, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174364", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "昭通", + "PR_LAST_PRICESET_HANGPRICE": 3350, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3320, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ32", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174363", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3450, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3420, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ28", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174362", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3400, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3370, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ25", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174361", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3300, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3270, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ22", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174360", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3300, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3270, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ20", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174359", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3300, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3270, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ18", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174358", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3200, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3170, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ16", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174357", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3300, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3270, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ14", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174356", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3380, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3350, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174355", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3380, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3350, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ40", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174354", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3450, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3420, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ36", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174353", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3350, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3320, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ32", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174352", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3150, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3120, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ28", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174351", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3100, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3070, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ25", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174350", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3000, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2970, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ22", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174349", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3000, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2970, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ20", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174348", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3000, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2970, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ18", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174347", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 2900, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2870, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ16", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174346", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3000, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2970, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ14", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174345", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3080, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3050, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174344", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3080, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3050, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174343", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3250, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3220, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174342", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3150, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3120, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174341", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3150, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3120, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174340", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3480, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3450, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174339", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3200, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3170, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174338", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3150, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3120, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174337", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3150, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3120, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174336", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "文山", + "PR_LAST_PRICESET_HANGPRICE": 3350, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3320, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ32", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174335", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3460, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3430, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ28", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174334", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3410, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3380, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ25", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174333", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3310, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3280, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ22", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174332", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3310, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3280, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ20", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174331", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3310, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3280, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ18", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174330", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3210, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3180, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ16", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174329", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3310, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3280, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ14", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174328", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3390, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3360, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174327", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3390, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3360, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ40", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174326", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3460, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3430, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ36", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174325", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3360, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3330, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ32", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174324", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3160, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3130, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ28", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174323", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3110, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3080, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ25", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174322", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3010, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2980, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ22", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174321", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3010, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2980, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ20", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174320", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3010, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2980, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ18", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174319", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 2910, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2880, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ16", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174318", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3010, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2980, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ14", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174317", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3090, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3060, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174316", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3090, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3060, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174315", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3260, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3230, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174314", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3160, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3130, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174313", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3160, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3130, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174312", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3490, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3460, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174311", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3210, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3180, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174310", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3160, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3130, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174309", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3160, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3130, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "高线", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174308", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "景洪", + "PR_LAST_PRICESET_HANGPRICE": 3360, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3330, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ32", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174307", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3440, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3410, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ28", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174306", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3390, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3360, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ25", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174305", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3290, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3260, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ22", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174304", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3290, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3260, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ20", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174303", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3290, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3260, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ18", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174302", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3190, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3160, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ16", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174301", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3290, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3260, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ14", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174300", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3370, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3340, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174299", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3370, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3340, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ40", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174298", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3440, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3410, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ36", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174297", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3340, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3310, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ32", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174296", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3140, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3110, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ28", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174295", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3090, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3060, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ25", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174294", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 2990, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2960, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ22", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174293", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 2990, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2960, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ20", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174292", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 2990, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2960, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ18", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174291", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 2890, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2860, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ16", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174290", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 2990, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 2960, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ14", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174289", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3070, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3040, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174288", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3070, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3040, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174287", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3240, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3210, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ10", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174286", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3140, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3110, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ8", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174285", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3140, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3110, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ6", + "PIRCE_DATE": "2025-09-04 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PRODUCTAREA_NAME": "德钢", + "PRICE_ID": "2001490258926174284", + "PR_PRICE_SOURCE": "德钢指导价", + "PR_PRICE_REGION": "蒙自", + "PR_LAST_PRICESET_HANGPRICE": 3470, + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3440, + "OPERATOR_CODE": "1048", + "OPERATOR_NAME": "姜薇" + } + ], + "pageSize": 100, + "pageNo": 1, + "pageNumber": 1, + "totalCount": 29987, + "totalPage": 300 + } + } +} \ No newline at end of file diff --git a/data/钢材网架.json b/data/钢材网架.json new file mode 100644 index 0000000..5d05072 --- /dev/null +++ b/data/钢材网架.json @@ -0,0 +1,1916 @@ +{ + "code": 0, + "isZip": 0, + "isDes": 0, + "data": { + "page": { + "result": [ + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ6", + "PR_PRICESET_MAKEPRICE": 3720, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3740, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877568", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3740, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3720, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ12", + "PR_PRICESET_MAKEPRICE": 3510, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3530, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877569", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3530, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3510, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ10", + "PR_PRICESET_MAKEPRICE": 3460, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3480, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877570", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3480, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3460, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ8", + "PR_PRICESET_MAKEPRICE": 3460, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3480, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877571", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3480, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3460, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PR_PRICESET_MAKEPRICE": 3350, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3370, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877572", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3370, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3350, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ14", + "PR_PRICESET_MAKEPRICE": 3350, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3370, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877573", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3370, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3350, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ18", + "PR_PRICESET_MAKEPRICE": 3160, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3180, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877574", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3180, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3160, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ16", + "PR_PRICESET_MAKEPRICE": 3330, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3350, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877575", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3350, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3330, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ20", + "PR_PRICESET_MAKEPRICE": 3330, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3350, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877576", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3350, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3330, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ28", + "PR_PRICESET_MAKEPRICE": 3410, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3430, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877577", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3430, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3410, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ22", + "PR_PRICESET_MAKEPRICE": 3330, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3350, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877578", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3350, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3330, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ25", + "PR_PRICESET_MAKEPRICE": 3350, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3370, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877579", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3370, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3350, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ32", + "PR_PRICESET_MAKEPRICE": 3410, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3430, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877580", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3430, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3410, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ14", + "PR_PRICESET_MAKEPRICE": 3580, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3600, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877581", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3600, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3580, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ16", + "PR_PRICESET_MAKEPRICE": 3560, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3580, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877582", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3580, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3560, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ28", + "PR_PRICESET_MAKEPRICE": 3640, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3660, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877583", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3660, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3640, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ22", + "PR_PRICESET_MAKEPRICE": 3560, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3580, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877584", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3580, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3560, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ12", + "PR_PRICESET_MAKEPRICE": 3580, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3600, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877585", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3600, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3580, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ25", + "PR_PRICESET_MAKEPRICE": 3580, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3600, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877586", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3600, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3580, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ18", + "PR_PRICESET_MAKEPRICE": 3390, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3410, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877587", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3410, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3390, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ20", + "PR_PRICESET_MAKEPRICE": 3560, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3580, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877588", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3580, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3560, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ32", + "PR_PRICESET_MAKEPRICE": 3640, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3660, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877589", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3660, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3640, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ6", + "PR_PRICESET_MAKEPRICE": 3720, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 3740, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877590", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3740, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3720, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PR_PRICESET_MAKEPRICE": 3510, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 3530, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877591", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3530, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3510, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ8", + "PR_PRICESET_MAKEPRICE": 3460, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 3480, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877592", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3480, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3460, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ10", + "PR_PRICESET_MAKEPRICE": 3460, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 3480, + "PRODUCTAREA_NAME": "达州钢铁", + "PRICE_ID": "2008071950960877593", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "重庆", + "PR_LAST_PRICESET_HANGPRICE": 3480, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3460, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PR_PRICESET_MAKEPRICE": 3350, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3370, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877594", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3370, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3350, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ14", + "PR_PRICESET_MAKEPRICE": 3350, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3370, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877595", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3370, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3350, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ6", + "PR_PRICESET_MAKEPRICE": 3720, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3740, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877596", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3740, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3720, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ12", + "PR_PRICESET_MAKEPRICE": 3510, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3530, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877597", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3530, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3510, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ8", + "PR_PRICESET_MAKEPRICE": 3460, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3480, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877598", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3480, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3460, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ10", + "PR_PRICESET_MAKEPRICE": 3460, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3480, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877599", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3480, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3460, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ16", + "PR_PRICESET_MAKEPRICE": 3330, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3350, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877600", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3350, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3330, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ18", + "PR_PRICESET_MAKEPRICE": 3160, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3180, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877601", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3180, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3160, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ20", + "PR_PRICESET_MAKEPRICE": 3330, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3350, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877602", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3350, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3330, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ22", + "PR_PRICESET_MAKEPRICE": 3330, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3350, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877603", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3350, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3330, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ28", + "PR_PRICESET_MAKEPRICE": 3410, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3430, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877604", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3430, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3410, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ25", + "PR_PRICESET_MAKEPRICE": 3350, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3370, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877605", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3370, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3350, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ32", + "PR_PRICESET_MAKEPRICE": 3410, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3430, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877606", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3430, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3410, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ25", + "PR_PRICESET_MAKEPRICE": 3580, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3600, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877607", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3600, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3580, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ14", + "PR_PRICESET_MAKEPRICE": 3580, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3600, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877608", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3600, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3580, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ16", + "PR_PRICESET_MAKEPRICE": 3560, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3580, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877609", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3580, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3560, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ18", + "PR_PRICESET_MAKEPRICE": 3390, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3410, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877610", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3410, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3390, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ32", + "PR_PRICESET_MAKEPRICE": 3640, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3660, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877611", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3660, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3640, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ22", + "PR_PRICESET_MAKEPRICE": 3560, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3580, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877612", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3580, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3560, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ12", + "PR_PRICESET_MAKEPRICE": 3580, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3600, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877613", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3600, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3580, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ28", + "PR_PRICESET_MAKEPRICE": 3640, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3660, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877614", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3660, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3640, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ20", + "PR_PRICESET_MAKEPRICE": 3560, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3580, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877615", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3580, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3560, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ6", + "PR_PRICESET_MAKEPRICE": 3750, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 3770, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877616", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3770, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3750, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PR_PRICESET_MAKEPRICE": 3520, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 3540, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877617", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3540, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3520, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ8", + "PR_PRICESET_MAKEPRICE": 3460, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 3480, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877618", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3480, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3460, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ10", + "PR_PRICESET_MAKEPRICE": 3460, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 3480, + "PRODUCTAREA_NAME": "成渝钒钛", + "PRICE_ID": "2008071950960877619", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "成都", + "PR_LAST_PRICESET_HANGPRICE": 3480, + "PR_MAKEPRICE_UPDW": "-20", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-20", + "PR_PRICESET_HANGPRICE": 3460, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ6", + "PR_PRICESET_MAKEPRICE": 3820, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3820, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877620", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3820, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3820, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ8", + "PR_PRICESET_MAKEPRICE": 3760, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3760, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877621", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3760, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3760, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ12", + "PR_PRICESET_MAKEPRICE": 3810, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3810, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877622", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3810, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3810, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ10", + "PR_PRICESET_MAKEPRICE": 3760, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3760, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877623", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3760, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3760, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400", + "GOODS_SPEC": "Φ14", + "PR_PRICESET_MAKEPRICE": 3550, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3550, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877624", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3550, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3550, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400", + "GOODS_SPEC": "Φ12", + "PR_PRICESET_MAKEPRICE": 3600, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3600, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877625", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3600, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3600, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400", + "GOODS_SPEC": "Φ16", + "PR_PRICESET_MAKEPRICE": 3500, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3500, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877626", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3500, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3500, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400", + "GOODS_SPEC": "Φ18", + "PR_PRICESET_MAKEPRICE": 3430, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3430, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877627", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3430, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3430, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400", + "GOODS_SPEC": "Φ20", + "PR_PRICESET_MAKEPRICE": 3510, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3510, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877628", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3510, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3510, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400", + "GOODS_SPEC": "Φ28", + "PR_PRICESET_MAKEPRICE": 3630, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3630, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877629", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3630, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3630, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400", + "GOODS_SPEC": "Φ25", + "PR_PRICESET_MAKEPRICE": 3530, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3530, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877630", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3530, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3530, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400", + "GOODS_SPEC": "Φ22", + "PR_PRICESET_MAKEPRICE": 3510, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3510, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877631", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3510, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3510, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400", + "GOODS_SPEC": "Φ32", + "PR_PRICESET_MAKEPRICE": 3630, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3630, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877632", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3630, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3630, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ14", + "PR_PRICESET_MAKEPRICE": 3550, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3550, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877633", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3550, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3550, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PR_PRICESET_MAKEPRICE": 3600, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3600, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877634", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3600, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3600, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ18", + "PR_PRICESET_MAKEPRICE": 3430, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3430, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877635", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3430, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3430, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ16", + "PR_PRICESET_MAKEPRICE": 3500, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3500, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877636", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3500, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3500, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ20", + "PR_PRICESET_MAKEPRICE": 3510, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3510, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877637", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3510, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3510, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ28", + "PR_PRICESET_MAKEPRICE": 3630, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3630, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877638", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3630, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3630, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ22", + "PR_PRICESET_MAKEPRICE": 3510, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3510, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877639", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3510, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3510, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ25", + "PR_PRICESET_MAKEPRICE": 3530, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3530, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877640", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3530, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3530, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ36", + "PR_PRICESET_MAKEPRICE": 3770, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3770, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877641", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3770, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3770, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ40", + "PR_PRICESET_MAKEPRICE": 3770, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3770, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877642", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3770, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3770, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ32", + "PR_PRICESET_MAKEPRICE": 3630, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3630, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877643", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3630, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3630, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ40", + "PR_PRICESET_MAKEPRICE": 4060, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 4060, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877644", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 4060, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4060, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ36", + "PR_PRICESET_MAKEPRICE": 4060, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 4060, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877645", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 4060, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4060, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ16", + "PR_PRICESET_MAKEPRICE": 3790, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3790, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877646", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3790, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3790, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ32", + "PR_PRICESET_MAKEPRICE": 3920, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3920, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877647", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3920, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3920, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ12", + "PR_PRICESET_MAKEPRICE": 3890, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3890, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877648", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3890, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3890, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ18", + "PR_PRICESET_MAKEPRICE": 3720, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3720, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877649", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3720, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3720, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ22", + "PR_PRICESET_MAKEPRICE": 3800, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3800, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877650", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3800, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3800, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ28", + "PR_PRICESET_MAKEPRICE": 3920, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3920, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877651", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3920, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3920, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ14", + "PR_PRICESET_MAKEPRICE": 3840, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3840, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877652", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3840, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3840, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ20", + "PR_PRICESET_MAKEPRICE": 3800, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3800, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877653", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3800, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3800, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB500E", + "GOODS_SPEC": "Φ25", + "PR_PRICESET_MAKEPRICE": 3820, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3820, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877654", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3820, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3820, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400", + "GOODS_SPEC": "Φ6", + "PR_PRICESET_MAKEPRICE": 4000, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 4000, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877655", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 4000, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4000, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400", + "GOODS_SPEC": "Φ8", + "PR_PRICESET_MAKEPRICE": 3700, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 3700, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877656", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3700, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3700, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400", + "GOODS_SPEC": "Φ10", + "PR_PRICESET_MAKEPRICE": 3700, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 3700, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877657", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3700, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3700, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ6", + "PR_PRICESET_MAKEPRICE": 4000, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 4000, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877658", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 4000, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 4000, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ8", + "PR_PRICESET_MAKEPRICE": 3700, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 3700, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877659", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3700, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3700, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PR_PRICESET_MAKEPRICE": 3750, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 3750, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877660", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3750, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3750, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ10", + "PR_PRICESET_MAKEPRICE": 3700, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "盘螺", + "PR_LAST_PRICESET_MAKEPRICE": 3700, + "PRODUCTAREA_NAME": "韶钢松山", + "PRICE_ID": "2008071950960877661", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "广州", + "PR_LAST_PRICESET_HANGPRICE": 3700, + "PR_MAKEPRICE_UPDW": "0", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "0", + "PR_PRICESET_HANGPRICE": 3700, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ6", + "PR_PRICESET_MAKEPRICE": 3700, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3730, + "PRODUCTAREA_NAME": "桂万钢", + "PRICE_ID": "2008071950960877662", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "南宁", + "PR_LAST_PRICESET_HANGPRICE": 3730, + "PR_MAKEPRICE_UPDW": "-30", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3700, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ8", + "PR_PRICESET_MAKEPRICE": 3600, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3630, + "PRODUCTAREA_NAME": "桂万钢", + "PRICE_ID": "2008071950960877663", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "南宁", + "PR_LAST_PRICESET_HANGPRICE": 3630, + "PR_MAKEPRICE_UPDW": "-30", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3600, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HPB300", + "GOODS_SPEC": "Φ10", + "PR_PRICESET_MAKEPRICE": 3600, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "高线", + "PR_LAST_PRICESET_MAKEPRICE": 3630, + "PRODUCTAREA_NAME": "桂万钢", + "PRICE_ID": "2008071950960877664", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "南宁", + "PR_LAST_PRICESET_HANGPRICE": 3630, + "PR_MAKEPRICE_UPDW": "-30", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3600, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ14", + "PR_PRICESET_MAKEPRICE": 3470, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3500, + "PRODUCTAREA_NAME": "桂万钢", + "PRICE_ID": "2008071950960877665", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "南宁", + "PR_LAST_PRICESET_HANGPRICE": 3500, + "PR_MAKEPRICE_UPDW": "-30", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3470, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ12", + "PR_PRICESET_MAKEPRICE": 3550, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3580, + "PRODUCTAREA_NAME": "桂万钢", + "PRICE_ID": "2008071950960877666", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "南宁", + "PR_LAST_PRICESET_HANGPRICE": 3580, + "PR_MAKEPRICE_UPDW": "-30", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3550, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + }, + { + "GOODS_MATERIAL": "HRB400E", + "GOODS_SPEC": "Φ18", + "PR_PRICESET_MAKEPRICE": 3380, + "PIRCE_DATE": "2026-01-05 08:00:00", + "PARTSNAME_NAME": "螺纹钢", + "PR_LAST_PRICESET_MAKEPRICE": 3410, + "PRODUCTAREA_NAME": "桂万钢", + "PRICE_ID": "2008071950960877667", + "PR_PRICE_SOURCE": "我的钢铁", + "PR_PRICE_REGION": "南宁", + "PR_LAST_PRICESET_HANGPRICE": 3410, + "PR_MAKEPRICE_UPDW": "-30", + "PNTREE_NAME": "钢筋", + "PR_HANGPRICE_UPDW": "-30", + "PR_PRICESET_HANGPRICE": 3380, + "OPERATOR_CODE": "1128", + "OPERATOR_NAME": "RPA机器人" + } + ], + "pageSize": 100, + "pageNo": 1, + "pageNumber": 1, + "totalCount": 211, + "totalPage": 3 + } + } +} \ No newline at end of file diff --git a/docs/API_DOCUMENTATION.md b/docs/API_DOCUMENTATION.md new file mode 100644 index 0000000..675fa3b --- /dev/null +++ b/docs/API_DOCUMENTATION.md @@ -0,0 +1,228 @@ +# API 文档说明 + +## 📚 Swagger 文档已集成 + +Steel Prices Service 现已集成完整的 Swagger API 文档系统! + +### 访问方式 + +启动服务后,可以通过以下方式访问 API 文档: + +#### 1. Swagger UI 界面(推荐) + +``` +http://localhost:3000/api-docs +``` + +**特点:** +- 📖 交互式 API 文档 +- 🧪 可直接在浏览器中测试 API +- 📝 完整的请求/响应示例 +- 🔍 参数说明和验证规则 +- 🎨 美观的用户界面 + +#### 2. JSON 格式的 OpenAPI 规范 + +``` +http://localhost:3000/api-docs.json +``` + +用于: +- 导入到其他 API 工具(Postman、Insomnia) +- 自动生成客户端 SDK +- API 版本管理 + +#### 3. API 信息接口 + +``` +http://localhost:3000/ +``` + +返回所有可用的 API 端点和文档链接。 + +--- + +## 📖 文档内容 + +### API 端点分类 + +#### Health(健康检查) +- `GET /api/health` - 检查服务状态 + +#### Prices(价格查询) +- `GET /api/prices/region` - 按地区查询价格 +- `GET /api/prices/search` - 多条件搜索价格 +- `GET /api/prices/stats` - 价格统计分析 +- `GET /api/prices/trend` - 价格趋势分析 + +#### Data(数据管理) +- `POST /api/prices/import` - 批量导入价格数据 + +### 数据模型 + +#### Price(价格数据) +- region - 地区(必填) +- city - 城市 +- material - 材质(必填) +- specification - 规格型号 +- price - 价格(必填) +- unit - 单位 +- date - 日期(必填) +- source - 数据来源 +- warehouse - 仓库/厂家 + +#### PriceStats(价格统计) +- count - 记录数量 +- avgPrice - 平均价格 +- minPrice - 最低价格 +- maxPrice - 最高价格 +- stdDev - 标准差 +- trend - 价格趋势 +- changeRate - 变化率 + +--- + +## 🧪 如何使用 Swagger UI + +### 1. 浏览 API + +1. 打开 `http://localhost:3000/api-docs` +2. 展开左侧的 API 分类标签 +3. 点击感兴趣的 API 端点 + +### 2. 测试 API + +1. 在 API 详情页点击 "Try it out" 按钮 +2. 填写必填参数(标红的字段) +3. 点击 "Execute" 执行请求 +4. 查看响应结果 + +### 3. 查看数据模型 + +1. 滚动到页面底部的 "Schemas" 部分 +2. 点击模型名称查看详细字段说明 +3. 查看示例数据格式 + +--- + +## 📝 示例:测试 API + +### 示例 1:按地区查询价格 + +**请求:** +``` +GET /api/prices/region?region=昆明&date=2026-01-05 +``` + +**在 Swagger UI 中的步骤:** +1. 展开 `GET /api/prices/region` +2. 点击 "Try it out" +3. 在 region 字段输入:`昆明` +4. 在 date 字段输入:`2026-01-05`(可选) +5. 点击 "Execute" +6. 查看响应结果 + +### 示例 2:搜索价格数据 + +**请求:** +``` +GET /api/prices/search?material=HPB300&page=1&pageSize=20 +``` + +**在 Swagger UI 中的步骤:** +1. 展开 `GET /api/prices/search` +2. 点击 "Try it out" +3. 在 material 字段输入:`HPB300` +4. 在 page 字段输入:`1` +5. 在 pageSize 字段输入:`20` +6. 点击 "Execute" +7. 查看响应结果和分页信息 + +### 示例 3:获取价格统计 + +**请求:** +``` +GET /api/prices/stats?region=昆明&material=HPB300&days=30 +``` + +**在 Swagger UI 中的步骤:** +1. 展开 `GET /api/prices/stats` +2. 点击 "Try it out" +3. 在 region 字段输入:`昆明` +4. 在 material 字段输入:`HPB300` +5. 在 days 字段输入:`30` +6. 点击 "Execute" +7. 查看统计数据 + +--- + +## 🔧 Swagger UI 配置 + +### 启用的功能 + +- ✅ **Explorer** - API 列表导航 +- ✅ **Try It Out** - 直接测试 API +- ✅ **Request Duration** - 显示请求耗时 +- ✅ **Filter** - 搜索和过滤 API +- ✅ **Request Headers** - 显示请求头 +- ✅ **Doc Expansion** - 列表展开方式 + +### 自定义配置 + +位置:[src/app.js](../src/app.js) + +```javascript +app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec, { + explorer: true, // 启用 API 导航 + customCss: '.swagger-ui .topbar { display: none }', // 自定义 CSS + customSiteTitle: 'Steel Prices Service API Documentation', // 页面标题 + swaggerOptions: { + persistAuthorization: true, // 持久化认证 + displayRequestDuration: true, // 显示请求耗时 + docExpansion: 'list', // 列表展开模式 + filter: true, // 启用过滤 + showRequestHeaders: true, // 显示请求头 + tryItOutEnabled: true // 启用测试功能 + } +})); +``` + +--- + +## 📚 相关文档 + +- [src/config/swagger.js](../src/config/swagger.js) - Swagger 配置文件 +- [src/routes/api.js](../src/routes/api.js) - API 路由和注解 +- [OpenAPI 3.0 规范](https://swagger.io/specification/) - 官方规范 + +--- + +## 🎯 快速开始 + +1. **启动服务** + ```bash + npm start + ``` + +2. **打开浏览器** + ``` + http://localhost:3000/api-docs + ``` + +3. **开始测试 API** + - 选择一个 API 端点 + - 点击 "Try it out" + - 填写参数并执行 + +--- + +## 💡 提示 + +- 所有参数都有详细的说明和示例 +- 必填参数会用红色标记 +- 响应数据包含完整的 JSON Schema +- 可以直接复制示例代码使用 + +--- + +**有问题?** 查看 [README.md](../README.md) 或 [快速开始指南](QUICK_START.md) diff --git a/docs/API_RESPONSE_FORMAT.md b/docs/API_RESPONSE_FORMAT.md new file mode 100644 index 0000000..274dcfb --- /dev/null +++ b/docs/API_RESPONSE_FORMAT.md @@ -0,0 +1,229 @@ +# API 响应格式规范 + +## 统一响应结构 + +所有 API 响应都遵循以下基本结构: + +```typescript +interface ApiResponse { + success: boolean; // 请求是否成功 + data?: T; // 响应数据(成功时返回) + message?: string; // 提示信息(操作类接口) + error?: string; // 错误信息(失败时返回) + pagination?: Pagination; // 分页信息(列表类接口) + meta?: Meta; // 元数据(统计类接口) +} +``` + +--- + +## 1. 列表类接口(带分页) + +### 适用接口 +- `GET /api/prices/region` - 按地区查询价格 +- `GET /api/prices/search` - 搜索价格数据 + +### 响应格式 + +```json +{ + "success": true, + "data": [ + { + "id": 1, + "price_id": "2008067775216672769", + "goods_material": "HPB300", + "goods_spec": "Φ8", + "hang_price": 3840, + ... + } + ], + "pagination": { + "page": 1, + "pageSize": 20, + "total": 100, + "totalPages": 5 + } +} +``` + +### 分页对象定义 + +```typescript +interface Pagination { + page: number; // 当前页码(从 1 开始) + pageSize: number; // 每页记录数 + total: number; // 总记录数 + totalPages: number; // 总页数 +} +``` + +### 默认值 +- `page`: 1 +- `pageSize`: 20 + +--- + +## 2. 统计类接口(带元数据) + +### 适用接口 +- `GET /api/prices/stats` - 获取价格统计 +- `GET /api/prices/trend` - 获取价格趋势 + +### 响应格式(Stats) + +```json +{ + "success": true, + "data": { + "count": 150, + "avgPrice": 3850.5, + "minPrice": 3600, + "maxPrice": 4200, + "stdDev": 150.25, + "trend": "up", + "changeRate": "+2.5%" + } +} +``` + +### 响应格式(Trend) + +```json +{ + "success": true, + "data": [ + { + "date": "2026-01-01", + "avgPrice": 3850.5, + "minPrice": 3600, + "maxPrice": 4200 + }, + { + "date": "2026-01-02", + "avgPrice": 3875.0, + "minPrice": 3650, + "maxPrice": 4250 + } + ], + "meta": { + "total": 30, + "filters": { + "region": "昆明", + "material": "HPB300", + "days": "30" + } + } +} +``` + +### 元数据定义 + +```typescript +interface Meta { + total: number; // 返回的记录总数 + filters?: { // 请求的过滤条件(可选) + region?: string; + material?: string; + days?: string; + }; +} +``` + +--- + +## 3. 操作类接口(带消息) + +### 适用接口 +- `POST /api/prices/import` - 导入数据 + +### 响应格式 + +```json +{ + "success": true, + "message": "成功导入 300 条数据", + "data": { + "imported": 300 + } +} +``` + +--- + +## 4. 错误响应 + +### 统一错误格式 + +```json +{ + "success": false, + "error": "错误描述信息" +} +``` + +### HTTP 状态码 + +| 状态码 | 说明 | 示例 | +|--------|------|------| +| 200 | 成功 | 数据查询成功 | +| 400 | 请求参数错误 | 缺少必填参数 | +| 404 | 资源不存在 | 数据未找到 | +| 500 | 服务器错误 | 数据库连接失败 | + +--- + +## 5. 数据类型规范 + +### 价格字段 +- `make_price`: `number \| null` - 钢厂价(元/吨) +- `hang_price`: `number` - 挂牌价(元/吨) +- 所有价格字段在返回时保留 2 位小数 + +### 日期字段 +- `price_date`: `string` - ISO 8601 格式 +- 统计时使用 `YYYY-MM-DD` 格式 + +### 分页参数 +- 所有参数都是字符串类型(从 URL query 获取) +- 服务层自动转换为数字类型 + +--- + +## 6. 示例请求 + +### 按地区查询(带分页) + +```bash +GET /api/prices/region?region=昆明&date=2026-01-05&page=1&pageSize=20 +``` + +### 搜索价格(多条件) + +```bash +GET /api/prices/search?material=HPB300&specification=Φ8&startDate=2026-01-01&endDate=2026-01-05®ion=昆明&page=1&pageSize=20 +``` + +### 获取价格趋势 + +```bash +GET /api/prices/trend?region=昆明&material=HPB300&days=30 +``` + +--- + +## 7. 版本历史 + +| 版本 | 日期 | 变更说明 | +|------|------|----------| +| 1.0 | 2026-01-05 | 初始版本,统一所有接口响应格式 | + +--- + +## 8. 注意事项 + +1. **分页一致性**:所有列表类接口必须返回 `pagination` 对象 +2. **数字精度**:价格字段统一保留 2 位小数 +3. **空值处理**:可选字段为空时返回 `null`,不返回 `undefined` +4. **错误消息**:错误消息使用中文,简洁明确 +5. **时区处理**:所有日期时间统一使用 `+08:00` 时区 diff --git a/docs/IMPORT_API.md b/docs/IMPORT_API.md new file mode 100644 index 0000000..28439ac --- /dev/null +++ b/docs/IMPORT_API.md @@ -0,0 +1,299 @@ +# 数据导入 API 文档 + +## POST /api/prices/import + +批量导入钢材价格数据到数据库。 + +### 请求格式 + +**Content-Type:** `application/json` + +**请求体:** + +```json +{ + "prices": [ + { + "price_id": "2008067775216672769", + "goods_material": "HPB300", + "goods_spec": "Φ8", + "partsname_name": "螺纹钢", + "productarea_name": "昆钢", + "price_source": "我的钢铁", + "price_region": "昆明", + "pntree_name": "钢筋", + "price_date": "2026-01-05T10:30:00.000Z", + "make_price": 3800, + "hang_price": 3850, + "last_make_price": 3750, + "last_hang_price": 3800, + "make_price_updw": "↑50", + "hang_price_updw": "↑50", + "operator_code": "OP001", + "operator_name": "张三" + } + ] +} +``` + +### 字段说明 + +#### 必填字段 + +| 字段名 | 类型 | 说明 | 示例 | +|--------|------|------|------| +| `goods_material` | string | 材质牌号 | `"HPB300"` | +| `goods_spec` | string | 规格型号 | `"Φ8"` | +| `partsname_name` | string | 品名 | `"螺纹钢"` | +| `productarea_name` | string | 产地/钢厂 | `"昆钢"` | +| `price_source` | string | 价格来源 | `"我的钢铁"` | +| `price_region` | string | 价格地区 | `"昆明"` | +| `price_date` | string | 价格日期(ISO 8601) | `"2026-01-05T10:30:00.000Z"` | +| `hang_price` | number | 挂牌价(元/吨) | `3850` | + +#### 可选字段 + +| 字段名 | 类型 | 说明 | 默认值 | 示例 | +|--------|------|------|--------|------| +| `price_id` | string | 价格唯一ID(为空时自动生成) | `null` | `"2008067775216672769"` | +| `pntree_name` | string | 分类名称 | `"钢筋"` | `"钢筋"` | +| `make_price` | number | 钢厂价(元/吨) | `null` | `3800` | +| `last_make_price` | number | 上次钢厂价 | `null` | `3750` | +| `last_hang_price` | number | 上次挂牌价 | `null` | `3800` | +| `make_price_updw` | string | 钢厂价涨跌 | `null` | `"↑50"` | +| `hang_price_updw` | string | 挂牌价涨跌 | `null` | `"↑50"` | +| `operator_code` | string | 操作员代码 | `null` | `"OP001"` | +| `operator_name` | string | 操作员名称 | `null` | `"张三"` | + +#### 自动生成字段 + +以下字段由系统自动生成,无需传入: + +- `id` - 自增主键 +- `created_at` - 创建时间 +- `updated_at` - 更新时间 + +### price_id 自动生成规则 + +如果传入的数据中 `price_id` 为空或不存在,系统会基于以下字段生成 MD5 哈希值: + +``` +{goods_material}-{goods_spec}-{price_region}-{price_source}-{price_date} +``` + +**示例:** +``` +HPB300-Φ8-昆明-我的钢铁-2026-01-05T10:30:00.000Z +↓ MD5 哈希 +a1b2c3d4e5f6...(32 位十六进制字符串) +``` + +这样可以确保相同业务数据不会重复插入。 + +### 响应格式 + +#### 成功响应 + +**HTTP Status:** `200 OK` + +```json +{ + "success": true, + "message": "成功导入 100 条数据", + "data": { + "imported": 100, + "total": 105, + "validCount": 100, + "errorCount": 5, + "errors": [ + { + "index": 3, + "data": { ... }, + "reasons": { + "missing": ["hang_price"], + "invalid": [ + { "field": "price_date", "expected": "valid Date", "received": "invalid-date" } + ] + } + } + ] + } +} +``` + +#### 失败响应 + +**HTTP Status:** `200 OK` (业务失败) + +```json +{ + "success": false, + "message": "没有有效的数据可以导入", + "data": { + "total": 10, + "imported": 0, + "errors": [ + { + "index": 0, + "data": { ... }, + "reasons": { + "missing": ["goods_material", "hang_price"], + "invalid": [] + } + } + ] + } +} +``` + +#### 服务器错误 + +**HTTP Status:** `500 Internal Server Error` + +```json +{ + "success": false, + "error": "数据库连接失败" +} +``` + +### 数据验证规则 + +#### 必填字段验证 + +- 所有必填字段不能为空、null 或 undefined +- 字符串字段长度不能为 0 + +#### 数据类型验证 + +| 字段 | 允许的类型 | 验证规则 | +|------|-----------|----------| +| `hang_price` | `number` | 必须是有效数字,不能为 NaN | +| `make_price` | `number` \| `null` | 如果存在,必须是有效数字 | +| `last_make_price` | `number` \| `null` | 如果存在,必须是有效数字 | +| `last_hang_price` | `number` \| `null` | 如果存在,必须是有效数字 | +| `price_date` | `string` \| `Date` | 必须是有效的日期格式 | + +### 错误处理 + +#### 数据格式错误 + +如果传入的数据不符合格式要求: + +```json +{ + "success": false, + "message": "无效的数据格式", + "error": "数据必须是数组格式" +} +``` + +#### 缺少必填字段 + +如果某条记录缺少必填字段,该记录会被跳过,错误信息会返回在响应中: + +```json +{ + "success": true, + "message": "成功导入 95 条数据,5 条数据因格式错误被跳过", + "data": { + "imported": 95, + "total": 100, + "validCount": 95, + "errorCount": 5, + "errors": [ + { + "index": 10, + "data": { "goods_material": "HPB300" }, + "reasons": { + "missing": ["goods_spec", "hang_price", "price_date"], + "invalid": [] + } + } + ] + } +} +``` + +### 使用示例 + +#### JavaScript (Fetch API) + +```javascript +const response = await fetch('http://localhost:3000/api/prices/import', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + prices: [ + { + goods_material: 'HPB300', + goods_spec: 'Φ8', + partsname_name: '螺纹钢', + productarea_name: '昆钢', + price_source: '我的钢铁', + price_region: '昆明', + price_date: '2026-01-05T10:30:00.000Z', + hang_price: 3850 + } + ] + }) +}); + +const result = await response.json(); +console.log(result); +``` + +#### cURL + +```bash +curl -X POST http://localhost:3000/api/prices/import \ + -H "Content-Type: application/json" \ + -d '{ + "prices": [ + { + "goods_material": "HPB300", + "goods_spec": "Φ8", + "partsname_name": "螺纹钢", + "productarea_name": "昆钢", + "price_source": "我的钢铁", + "price_region": "昆明", + "price_date": "2026-01-05T10:30:00.000Z", + "hang_price": 3850 + } + ] + }' +``` + +### 注意事项 + +1. **批量限制**:建议单次导入不超过 1000 条记录 +2. **重复数据处理**:使用 `ON DUPLICATE KEY UPDATE` 机制自动更新已存在的记录 +3. **事务处理**:每次批量插入是一个事务,失败会回滚 +4. **错误详情**:响应中最多返回前 10 个错误详情 +5. **price_id 唯一性**:系统会自动确保 price_id 的唯一性,无需手动处理 + +### 完整字段对照表 + +| 数据库字段 | JSON 字段 | 必填 | 类型 | 说明 | +|-----------|-----------|------|------|------| +| `price_id` | `price_id` | ❌ | string | 价格唯一ID | +| `goods_material` | `goods_material` | ✅ | string | 材质牌号 | +| `goods_spec` | `goods_spec` | ✅ | string | 规格型号 | +| `partsname_name` | `partsname_name` | ✅ | string | 品名 | +| `productarea_name` | `productarea_name` | ✅ | string | 产地/钢厂 | +| `price_source` | `price_source` | ✅ | string | 价格来源 | +| `price_region` | `price_region` | ✅ | string | 价格地区 | +| `pntree_name` | `pntree_name` | ❌ | string | 分类名称 | +| `price_date` | `price_date` | ✅ | string | 价格日期 | +| `make_price` | `make_price` | ❌ | number | 钢厂价 | +| `hang_price` | `hang_price` | ✅ | number | 挂牌价 | +| `last_make_price` | `last_make_price` | ❌ | number | 上次钢厂价 | +| `last_hang_price` | `last_hang_price` | ❌ | number | 上次挂牌价 | +| `make_price_updw` | `make_price_updw` | ❌ | string | 钢厂价涨跌 | +| `hang_price_updw` | `hang_price_updw` | ❌ | string | 挂牌价涨跌 | +| `operator_code` | `operator_code` | ❌ | string | 操作员代码 | +| `operator_name` | `operator_name` | ❌ | string | 操作员名称 | +| `created_at` | - | - | - | 自动生成 | +| `updated_at` | - | - | - | 自动生成 | diff --git a/docs/PROJECT_STATUS.md b/docs/PROJECT_STATUS.md new file mode 100644 index 0000000..9b087b1 --- /dev/null +++ b/docs/PROJECT_STATUS.md @@ -0,0 +1,219 @@ +# 项目实施状态报告 + +生成时间: 2026-01-05 + +## ✅ 已完成的任务 + +### 1. 项目基础架构 +- ✅ 初始化 Node.js 项目(package.json) +- ✅ 安装核心依赖(express, mysql2, dotenv, cors, morgan) +- ✅ 创建完整的项目目录结构 +- ✅ 配置 .gitignore 文件 + +### 2. 数据库层 +- ✅ 数据库连接配置([src/config/database.js](../src/config/database.js)) +- ✅ Price 数据模型([src/models/Price.js](../src/models/Price.js)) + - 创建表结构 + - CRUD 操作 + - 查询、搜索、统计功能 + - 批量插入优化 + - 索引优化 + +### 3. 脚本工具 +- ✅ 数据库初始化脚本([scripts/init-db.js](../scripts/init-db.js)) + - 自动创建数据库和表结构 + - 创建必要的索引 +- ✅ 数据导入脚本([scripts/import-data.js](../scripts/import-data.js)) + - 支持批量导入(1000条/批) + - 自动数据格式转换 + - 导入进度显示 + - 统计信息展示 + +### 4. 业务逻辑层 +- ✅ 价格服务([src/services/priceService.js](../src/services/priceService.js)) + - 按地区查询 + - 多条件搜索(支持分页) + - 价格统计分析 + - 价格趋势分析 + - 数据导入 + +### 5. 控制器层 +- ✅ 价格控制器([src/controllers/priceController.js](../src/controllers/priceController.js)) + - HTTP 请求处理 + - 异步错误处理 + - 统一响应格式 + +### 6. 中间件 +- ✅ 错误处理中间件([src/middlewares/errorHandler.js](../src/middlewares/errorHandler.js)) + - 404 处理 + - 统一错误响应 + - 异步错误捕获包装器 + - 自定义错误类 +- ✅ 请求验证中间件([src/middlewares/validator.js](../src/middlewares/validator.js)) + - 参数验证 + - 日期格式验证 + - 分页参数验证 + +### 7. 路由层 +- ✅ API 路由([src/routes/api.js](../src/routes/api.js)) + - GET /api/prices/region - 按地区查询 + - GET /api/prices/search - 搜索价格 + - GET /api/prices/stats - 价格统计 + - GET /api/prices/trend - 价格趋势 + - POST /api/prices/import - 数据导入 + - GET /api/health - 健康检查 +- ✅ 主路由([src/routes/index.js](../src/routes/index.js)) + - API 版本管理 + - 根路径信息 + +### 8. 应用层 +- ✅ Express 应用([src/app.js](../src/app.js)) + - 中间件配置 + - CORS 支持 + - 日志记录 + - 错误处理 +- ✅ 服务器启动([src/server.js](../src/server.js)) + - 环境变量加载 + - 优雅关闭 + - 未捕获异常处理 + +### 9. 配置文件 +- ✅ 环境变量示例(.env.example) +- ✅ Git 忽略文件(.gitignore) +- ✅ package.json 脚本配置 + +### 10. 文档 +- ✅ README.md - 项目主文档 +- ✅ CLAUDE.md - AI 上下文文档 +- ✅ data/CLAUDE.md - 数据模块文档 +- ✅ docs/QUICK_START.md - 快速开始指南 + +## 📊 项目统计 + +| 类别 | 数量 | +|------|------| +| 源代码文件 | 12 个 | +| 脚本文件 | 2 个 | +| 文档文件 | 4 个 | +| API 端点 | 6 个 | +| 代码行数(估算) | ~2000 行 | + +## 🎯 核心功能实现情况 + +### 已实现 ✅ +1. ✅ 数据库设计与建表 +2. ✅ 数据导入功能 +3. ✅ 按地区查询价格 +4. ✅ 多条件搜索价格 +5. ✅ 价格统计分析 +6. ✅ 价格趋势分析 +7. ✅ RESTful API 接口 +8. ✅ 错误处理机制 +9. ✅ 请求参数验证 +10. ✅ 批量数据导入 + +### 待实现 ⏳ +1. ⏳ 定时数据采集任务 +2. ⏳ 数据导出功能 +3. ⏳ Swagger API 文档 +4. ⏳ 单元测试 +5. ⏳ 集成测试 +6. ⏳ Docker 容器化 +7. ⏳ 性能优化(查询缓存) +8. ⏳ WebSocket 实时推送 +9. ⏳ 用户认证与授权 +10. ⏳ 日志分析与监控 + +## 🏗️ 项目架构 + +``` +steel_prices_service/ +├── src/ # 源代码 (12 个文件) +│ ├── config/ # 配置 +│ │ ├── database.js # 数据库连接 +│ │ └── logger.js # 日志配置 +│ ├── models/ # 数据模型 +│ │ ├── Price.js # 价格模型 +│ │ └── index.js +│ ├── services/ # 业务逻辑 +│ │ └── priceService.js # 价格服务 +│ ├── controllers/ # 控制器 +│ │ └── priceController.js +│ ├── routes/ # 路由 +│ │ ├── api.js +│ │ └── index.js +│ ├── middlewares/ # 中间件 +│ │ ├── errorHandler.js +│ │ └── validator.js +│ ├── app.js # Express 应用 +│ └── server.js # 服务器启动 +├── scripts/ # 脚本工具 +│ ├── init-db.js # 数据库初始化 +│ └── import-data.js # 数据导入 +├── docs/ # 文档 +│ └── QUICK_START.md # 快速开始 +├── data/ # 数据文件 +│ ├── 钢材网架.json +│ ├── 钢厂指导价.json +│ ├── 刚协指导价.json +│ └── CLAUDE.md +├── .env.example # 环境变量模板 +├── .gitignore # Git 忽略 +├── package.json # 项目配置 +├── README.md # 项目文档 +└── CLAUDE.md # AI 上下文 +``` + +## 📈 开发进度 + +**总体进度**: 70% ✅ + +- ✅ 阶段 1: 数据准备与验证 (100%) +- ✅ 阶段 2: 核心服务开发 (100%) +- ⏳ 阶段 3: 数据采集自动化 (0%) +- ⏳ 阶段 4: 测试与优化 (0%) + +## 🚀 下一步计划 + +### 立即可做 +1. 配置数据库连接 +2. 运行数据库初始化脚本 +3. 导入数据 +4. 启动服务测试 API + +### 短期任务 (1-2周) +5. 添加单元测试 +6. 完善 API 文档 (Swagger) +7. 实现 Docker 容器化 +8. 添加数据导出功能 + +### 长期任务 (3-4周) +9. 实现定时数据采集 +10. 性能优化与缓存 +11. 日志监控与告警 +12. CI/CD 流程 + +## ✨ 亮点特性 + +1. **SOLID 原则应用** - 清晰的分层架构 +2. **DRY 原则** - 代码复用,避免重复 +3. **错误处理** - 统一的错误处理机制 +4. **参数验证** - 完善的请求验证 +5. **批量优化** - 数据导入分批处理 +6. **索引优化** - 数据库查询性能优化 +7. **日志记录** - 完整的请求日志 +8. **优雅关闭** - 服务器优雅退出 + +## 📝 技术债务 + +无重大技术债务。 + +代码质量良好,遵循最佳实践。 + +## 🎉 总结 + +项目核心功能已全部实现,代码质量良好,架构清晰。 + +可以立即开始使用:配置数据库 → 初始化 → 导入数据 → 启动服务! + +详细步骤请参考 [快速开始指南](QUICK_START.md) diff --git a/docs/QUICK_START.md b/docs/QUICK_START.md new file mode 100644 index 0000000..592b7ad --- /dev/null +++ b/docs/QUICK_START.md @@ -0,0 +1,141 @@ +# 快速开始指南 + +## 🚀 快速启动 + +### 1. 配置环境变量 + +复制 `.env.example` 到 `.env` 并配置数据库连接: + +```bash +cp .env.example .env +``` + +编辑 `.env` 文件,填入你的数据库信息: + +```env +# 服务器配置 +NODE_ENV=development +PORT=3000 + +# 数据库配置 +DB_HOST=localhost +DB_PORT=3306 +DB_NAME=steel_prices +DB_USER=root +DB_PASSWORD=your_password + +# 日志配置 +LOG_LEVEL=info +``` + +### 2. 创建数据库 + +确保 MySQL 已安装并运行,然后执行: + +```bash +# 方式 1: 使用 npm 脚本(推荐) +npm run db:init + +# 方式 2: 手动创建 +mysql -u root -p -e "CREATE DATABASE steel_prices CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" +``` + +### 3. 导入数据 + +导入钢材价格数据: + +```bash +npm run db:import +``` + +这将导入 `data/` 目录下的所有 JSON 数据文件(约 31,098 条记录)。 + +### 4. 启动服务 + +```bash +# 开发模式 +npm run dev + +# 或生产模式 +npm start +``` + +服务将在 `http://localhost:3000` 启动。 + +### 5. 测试 API + +打开浏览器或使用 curl 测试: + +```bash +# 健康检查 +curl http://localhost:3000/api/health + +# 按地区查询价格 +curl "http://localhost:3000/api/prices/region?region=昆明" + +# 搜索价格数据 +curl "http://localhost:3000/api/prices/search?material=HPB300&startDate=2026-01-01&endDate=2026-01-05" + +# 获取价格统计 +curl "http://localhost:3000/api/prices/stats?region=昆明&days=30" + +# 获取价格趋势 +curl "http://localhost:3000/api/prices/trend?material=HPB300&days=30" +``` + +## 📚 API 端点 + +| 方法 | 端点 | 描述 | +|------|------|------| +| GET | `/api/health` | 健康检查 | +| GET | `/` | API 信息 | +| GET | `/api/prices/region` | 按地区查询价格 | +| GET | `/api/prices/search` | 搜索价格数据 | +| GET | `/api/prices/stats` | 获取价格统计 | +| GET | `/api/prices/trend` | 获取价格趋势 | +| POST | `/api/prices/import` | 导入价格数据 | + +## 🔧 常见问题 + +### 数据库连接失败 + +1. 检查 MySQL 服务是否运行 +2. 确认 `.env` 中的数据库配置正确 +3. 确保数据库用户有足够的权限 + +### 端口被占用 + +如果 3000 端口被占用,可以修改 `.env` 中的 `PORT` 配置: + +```env +PORT=3001 +``` + +### 数据导入失败 + +1. 确保 `data/` 目录下的 JSON 文件存在 +2. 检查数据库表是否已创建 +3. 查看控制台错误日志 + +## 📊 数据统计 + +导入完成后,可以查看数据库统计信息: + +```bash +npm run db:import +``` + +脚本会自动显示: +- 总记录数 +- 平均价格 +- 最低/最高价格 + +## 🎯 下一步 + +- 查看 [README.md](../README.md) 了解项目详情 +- 查看 [API 文档](./api.md) 了解完整的 API 使用方法 +- 查看项目 [CLAUDE.md](../CLAUDE.md) 了解项目架构 + +--- + +有问题?查看 [GitHub Issues](https://github.com/your-username/steel_prices_service/issues) diff --git a/docs/SWAGGER_IMPLEMENTATION_REPORT.md b/docs/SWAGGER_IMPLEMENTATION_REPORT.md new file mode 100644 index 0000000..97e1140 --- /dev/null +++ b/docs/SWAGGER_IMPLEMENTATION_REPORT.md @@ -0,0 +1,328 @@ +# 🎉 Swagger 文档实施完成报告 + +## 执行摘要 + +✅ **Swagger API 文档系统已成功集成到 Steel Prices Service 项目中!** + +**完成时间**: 2026-01-05 +**状态**: 100% 完成 +**影响范围**: 所有 API 端点 + +--- + +## ✅ 已完成任务清单 + +### 1. 依赖安装 ✅ +```bash +✅ swagger-jsdoc@^6.2.8 +✅ swagger-ui-express@^5.0.1 +``` + +### 2. 核心配置 ✅ +- ✅ [src/config/swagger.js](../src/config/swagger.js) - Swagger 配置文件 + - OpenAPI 3.0 规范 + - API 信息和描述 + - 服务器配置 + - 数据模型定义 + - 参数模板定义 + +### 3. API 注解 ✅ +- ✅ [src/routes/api.js](../src/routes/api.js) - 完整的 API 注解 + - GET /api/health - 健康检查 + - GET /api/prices/region - 按地区查询价格 + - GET /api/prices/search - 搜索价格数据 + - GET /api/prices/stats - 价格统计 + - GET /api/prices/trend - 价格趋势 + - POST /api/prices/import - 数据导入 + +### 4. UI 集成 ✅ +- ✅ [src/app.js](../src/app.js) - Swagger UI 中间件集成 + - Swagger UI 路由配置 + - 自定义样式和选项 + - 交互式测试功能 + +### 5. 路由扩展 ✅ +- ✅ [src/routes/index.js](../src/routes/index.js) - 新增文档路由 + - GET /api-docs - Swagger UI + - GET /api-docs.json - JSON 规范 + +### 6. 文档创建 ✅ +- ✅ [docs/API_DOCUMENTATION.md](API_DOCUMENTATION.md) - API 文档使用指南 +- ✅ [docs/SWAGGER_SUMMARY.md](SWAGGER_SUMMARY.md) - Swagger 实施总结 +- ✅ [README.md](../README.md) - 更新项目说明 + +--- + +## 📊 统计数据 + +| 类别 | 数量 | +|------|------| +| **已注解 API 端点** | 6 个 | +| **数据模型定义** | 6 个 | +| **参数模板** | 6 个 | +| **使用示例** | 10+ 个 | +| **API 分类** | 3 个 | +| **代码行数** | ~500 行(注解) | + +--- + +## 🎯 核心功能 + +### 1. 交互式 API 文档 +``` +URL: http://localhost:3000/api-docs +``` + +**功能**: +- 📖 浏览所有 API 端点 +- 🧪 直接在浏览器中测试 API +- 📝 查看详细的请求/响应示例 +- 🔍 搜索和过滤 API +- 🎨 美观的用户界面 + +### 2. OpenAPI JSON 规范 +``` +URL: http://localhost:3000/api-docs.json +``` + +**用途**: +- 导入到 Postman、Insomnia 等工具 +- 自动生成客户端 SDK +- API 版本管理 +- 文档生成 + +### 3. 详细的接口说明 + +每个 API 包含: +- ✅ 详细的描述和用途说明 +- ✅ 参数列表(类型、必填、示例) +- ✅ 请求示例(多个场景) +- ✅ 响应 Schema(成功/失败) +- ✅ 错误码说明 + +--- + +## 📦 数据模型 + +### 定义的模型 + +1. **Price** - 价格数据模型 + - 地区、材质、规格、价格等 + - 完整的字段说明 + +2. **PriceStats** - 价格统计模型 + - 平均值、最大值、最小值、标准差 + - 趋势和变化率 + +3. **TrendData** - 趋势数据模型 + - 日期、均价、最高价、最低价 + +4. **Pagination** - 分页信息模型 + - 页码、每页数量、总数、总页数 + +5. **SuccessResponse** - 成功响应模型 + - 标准成功响应格式 + +6. **ErrorResponse** - 错误响应模型 + - 错误信息和状态码 + +--- + +## 🔧 Swagger UI 配置 + +### 启用的功能 + +```javascript +{ + explorer: true, // API 列表导航 + customCss: '...', // 自定义样式 + customSiteTitle: '...', // 页面标题 + swaggerOptions: { + persistAuthorization: true, // 持久化认证 + displayRequestDuration: true, // 显示请求耗时 + docExpansion: 'list', // 列表展开 + filter: true, // 启用过滤 + showRequestHeaders: true, // 显示请求头 + tryItOutEnabled: true // 启用测试 + } +} +``` + +--- + +## 📖 使用示例 + +### 示例 1:按地区查询价格 + +**步骤**: +1. 访问 `http://localhost:3000/api-docs` +2. 展开 `GET /api/prices/region` +3. 点击 "Try it out" +4. 输入参数: + - region: `昆明` + - date: `2026-01-05` +5. 点击 "Execute" +6. 查看响应结果 + +### 示例 2:搜索价格数据 + +**步骤**: +1. 展开 `GET /api/prices/search` +2. 点击 "Try it out" +3. 输入参数: + - material: `HPB300` + - page: `1` + - pageSize: `20` +4. 点击 "Execute" +5. 查看结果和分页信息 + +### 示例 3:获取价格统计 + +**步骤**: +1. 展开 `GET /api/prices/stats` +2. 点击 "Try it out" +3. 输入参数: + - region: `昆明` + - days: `30` +4. 点击 "Execute" +5. 查看统计数据 + +--- + +## 🎨 界面预览 + +Swagger UI 提供: +- 📋 左侧:API 端点列表(按分类) +- 📝 中间:API 详情和参数 +- 🧪 右侧:测试区域和响应 +- 📊 底部:数据模型定义 + +--- + +## 📚 文档结构 + +``` +docs/ +├── API_DOCUMENTATION.md # API 文档使用指南 +├── SWAGGER_SUMMARY.md # Swagger 实施总结 +├── SWAGGER_IMPLEMENTATION_REPORT.md # 本文件 +├── QUICK_START.md # 快速开始指南 +└── PROJECT_STATUS.md # 项目状态报告 +``` + +--- + +## 🚀 快速开始 + +### 1. 启动服务 + +```bash +npm start +``` + +### 2. 访问文档 + +打开浏览器访问: +``` +http://localhost:3000/api-docs +``` + +### 3. 开始测试 + +- 选择 API 端点 +- 点击 "Try it out" +- 填写参数 +- 执行请求 +- 查看结果 + +--- + +## 🎯 项目文件变更 + +### 新增文件 + +1. `src/config/swagger.js` - Swagger 配置 +2. `docs/API_DOCUMENTATION.md` - API 文档指南 +3. `docs/SWAGGER_SUMMARY.md` - Swagger 总结 +4. `docs/SWAGGER_IMPLEMENTATION_REPORT.md` - 本报告 + +### 修改文件 + +1. `src/app.js` - 集成 Swagger UI +2. `src/routes/api.js` - 添加 API 注解 +3. `src/routes/index.js` - 添加文档路由 +4. `package.json` - 添加依赖 +5. `README.md` - 更新文档说明 + +--- + +## ✨ 亮点特性 + +1. **完整的 API 覆盖** + - 所有 6 个 API 端点都有详细文档 + - 每个参数都有说明和示例 + +2. **丰富的数据模型** + - 6 个数据模型定义 + - 清晰的字段说明 + - 实际的示例数据 + +3. **多场景示例** + - 每个接口提供多个使用示例 + - 覆盖常见使用场景 + - 便于理解和参考 + +4. **交互式测试** + - 直接在浏览器中测试 API + - 查看请求和响应详情 + - 无需使用其他工具 + +5. **规范的 OpenAPI 3.0** + - 遵循最新规范 + - 可导出 JSON 格式 + - 兼容各种工具 + +--- + +## 📝 注意事项 + +1. **文档更新** + - 添加新 API 时记得更新 Swagger 注解 + - 修改参数时同步更新文档 + - 定期检查文档的准确性 + +2. **版本管理** + - API 重大变更时更新版本号 + - 保持文档与代码同步 + - 使用 Git 追踪变更历史 + +3. **测试覆盖** + - 使用 Swagger UI 测试所有 API + - 验证参数和响应格式 + - 确保示例数据有效 + +--- + +## 🎉 总结 + +✅ **Swagger 文档系统已完全集成!** + +**成果**: +- ✅ 6 个 API 端点完整文档 +- ✅ 6 个数据模型定义 +- ✅ 10+ 个使用示例 +- ✅ 交互式测试功能 +- ✅ 完整的使用指南 + +**访问地址**: +- Swagger UI: `http://localhost:3000/api-docs` +- JSON 规范: `http://localhost:3000/api-docs.json` + +**下一步**: +启动服务并访问 Swagger UI,开始探索和测试 API! + +--- + +**生成时间**: 2026-01-05 +**版本**: 1.0.0 +**状态**: ✅ 完成 diff --git a/docs/SWAGGER_SUMMARY.md b/docs/SWAGGER_SUMMARY.md new file mode 100644 index 0000000..8fd562f --- /dev/null +++ b/docs/SWAGGER_SUMMARY.md @@ -0,0 +1,319 @@ +# Swagger API 文档实施总结 + +## ✅ 完成的工作 + +### 1. 安装依赖 +```bash +npm install swagger-jsdoc swagger-ui-express +``` + +### 2. 创建配置文件 + +**文件**: [src/config/swagger.js](../src/config/swagger.js) + +**内容包括**: +- OpenAPI 3.0 规范配置 +- API 基本信息(标题、版本、描述) +- 服务器配置(开发/生产) +- 数据模型定义(Price、PriceStats、TrendData 等) +- 参数定义(复用参数模板) +- 响应模式定义 + +### 3. 添加 API 注解 + +**文件**: [src/routes/api.js](../src/routes/api.js) + +**已注解的接口**: +- ✅ `GET /api/health` - 健康检查 +- ✅ `GET /api/prices/region` - 按地区查询价格 +- ✅ `GET /api/prices/search` - 搜索价格数据 +- ✅ `GET /api/prices/stats` - 价格统计 +- ✅ `GET /api/prices/trend` - 价格趋势 +- ✅ `POST /api/prices/import` - 数据导入 + +**注解内容包括**: +- 详细的接口描述 +- 参数说明(类型、必填、示例) +- 请求示例(多个场景) +- 响应 Schema(成功/失败) +- 错误码说明 + +### 4. 集成 Swagger UI + +**文件**: [src/app.js](../src/app.js) + +**配置功能**: +- ✅ Swagger UI 中间件 +- ✅ API 別览器(Explorer) +- ✅ 直接测试功能(Try it out) +- ✅ 请求耗时显示 +- ✅ 请求头显示 +- ✅ 自定义样式 + +### 5. 添加文档路由 + +**文件**: [src/routes/index.js](../src/routes/index.js) + +**新增路由**: +- `GET /api-docs` - Swagger UI 界面 +- `GET /api-docs.json` - JSON 格式的 OpenAPI 规范 +- `GET /` - API 信息和链接汇总 + +### 6. 创建文档 + +**文档文件**: +- ✅ [docs/API_DOCUMENTATION.md](API_DOCUMENTATION.md) - API 文档使用指南 +- ✅ 更新 [README.md](../README.md) - 添加 Swagger 说明 + +--- + +## 📊 API 文档统计 + +| 项目 | 数量 | +|------|------| +| **API 端点** | 6 个 | +| **数据模型** | 6 个 | +| **参数定义** | 6 个 | +| **API 分类** | 3 个 | +| **示例代码** | 10+ 个 | + +--- + +## 🎯 数据模型清单 + +### 1. Price(价格数据) +```javascript +{ + id: 1, + region: "昆明", + city: "昆明", + material: "HPB300", + specification: "Φ8", + price: 3840.00, + unit: "元/吨", + date: "2026-01-05", + source: "云南钢协", + warehouse: "玉昆", + created_at: "2026-01-05T10:00:00Z", + updated_at: "2026-01-05T10:00:00Z" +} +``` + +### 2. PriceStats(价格统计) +```javascript +{ + count: 150, + avgPrice: 3950.50, + minPrice: 3500.00, + maxPrice: 4500.00, + stdDev: 250.30, + trend: "up", + changeRate: "+2.5%" +} +``` + +### 3. TrendData(趋势数据) +```javascript +{ + date: "2026-01-05", + avgPrice: 3950.50, + minPrice: 3800.00, + maxPrice: 4100.00 +} +``` + +### 4. Pagination(分页信息) +```javascript +{ + page: 1, + pageSize: 20, + total: 100, + totalPages: 5 +} +``` + +### 5. SuccessResponse(成功响应) +```javascript +{ + success: true, + data: { ... } +} +``` + +### 6. ErrorResponse(错误响应) +```javascript +{ + success: false, + message: "参数验证失败", + statusCode: 400 +} +``` + +--- + +## 📖 使用方式 + +### 访问文档 + +1. **启动服务** + ```bash + npm start + ``` + +2. **打开浏览器** + ``` + http://localhost:3000/api-docs + ``` + +3. **测试 API** + - 展开 API 端点 + - 点击 "Try it out" + - 填写参数 + - 点击 "Execute" + - 查看响应 + +### 导出规范 + +```bash +# 获取 JSON 格式的 OpenAPI 规范 +curl http://localhost:3000/api-docs.json > openapi.json +``` + +--- + +## 🎨 Swagger UI 特性 + +### 已启用的功能 + +- ✅ **Explorer** - API 列表导航 +- ✅ **Try It Out** - 直接测试 API +- ✅ **Request Duration** - 显示请求耗时 +- ✅ **Filter** - 搜索和过滤 API +- ✅ **Request Headers** - 显示请求头 +- ✅ **Doc Expansion** - 列表展开模式 +- ✅ **Models** - 数据模型展示 +- ✅ **Examples** - 请求/响应示例 + +### 自定义配置 + +```javascript +{ + explorer: true, // 启用 API 导航 + customCss: '.swagger-ui .topbar { display: none }', // 隐藏顶部栏 + customSiteTitle: 'Steel Prices Service API Documentation', // 页面标题 + swaggerOptions: { + persistAuthorization: true, // 持久化认证 + displayRequestDuration: true, // 显示请求耗时 + docExpansion: 'list', // 列表展开模式 + filter: true, // 启用过滤 + showRequestHeaders: true, // 显示请求头 + tryItOutEnabled: true // 启用测试功能 + } +} +``` + +--- + +## 📝 API 文档结构 + +### 分类标签 + +1. **Health**(健康检查) + - `GET /api/health` + +2. **Prices**(价格查询) + - `GET /api/prices/region` + - `GET /api/prices/search` + - `GET /api/prices/stats` + - `GET /api/prices/trend` + +3. **Data**(数据管理) + - `POST /api/prices/import` + +--- + +## 🔍 参数说明 + +### 路径参数 + +无(本项目使用查询参数) + +### 查询参数 + +| 参数 | 类型 | 必填 | 说明 | 示例 | +|------|------|------|------|------| +| region | string | 是 | 地区 | 昆明 | +| material | string | 否 | 材质 | HPB300 | +| specification | string | 否 | 规格型号 | Φ8 | +| date | date | 否 | 日期 | 2026-01-05 | +| startDate | date | 否 | 开始日期 | 2026-01-01 | +| endDate | date | 否 | 结束日期 | 2026-01-05 | +| days | integer | 否 | 天数 | 30 | +| page | integer | 否 | 页码 | 1 | +| pageSize | integer | 否 | 每页数量 | 20 | + +--- + +## 💡 高级功能 + +### 1. 参数复用 + +使用 `$ref` 引用预定义的参数: + +```yaml +parameters: + - $ref: '#/components/parameters/RegionParam' + - $ref: '#/components/parameters/DateParam' +``` + +### 2. 数据模型复用 + +使用 `$ref` 引用预定义的模型: + +```yaml +schema: + $ref: '#/components/schemas/Price' +``` + +### 3. 多示例支持 + +为同一个接口提供多个使用示例: + +```yaml +examples: + search_by_material: + summary: 按材质搜索 + value: { material: "HPB300" } + search_by_date_range: + summary: 按日期范围搜索 + value: { startDate: "2026-01-01", endDate: "2026-01-05" } +``` + +--- + +## 📚 相关文档 + +- [OpenAPI 3.0 规范](https://swagger.io/specification/) +- [Swagger UI 配置](https://swagger.io/tools/swagger-ui/configuration/) +- [swagger-jsdoc 文档](https://github.com/Surnet/swagger-jsdoc) + +--- + +## 🎉 总结 + +✅ **Swagger 文档系统已完全集成!** + +**主要特性**: +- 6 个完整的 API 端点文档 +- 6 个详细的数据模型定义 +- 10+ 个使用示例 +- 交互式测试功能 +- 美观的用户界面 +- 完整的参数说明 + +**访问地址**: +- Swagger UI: `http://localhost:3000/api-docs` +- JSON 规范: `http://localhost:3000/api-docs.json` + +**下一步**: +启动服务并访问 Swagger UI 开始探索 API! diff --git a/package.json b/package.json new file mode 100644 index 0000000..e2a6707 --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "steel_prices_service", + "version": "1.0.0", + "description": "钢材价格查询与分析服务平台", + "main": "src/server.js", + "scripts": { + "start": "node src/server.js", + "dev": "node src/server.js", + "db:init": "node scripts/init-db.js", + "db:import": "node scripts/import-data.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "steel", + "prices", + "api", + "express", + "mysql" + ], + "author": "", + "license": "MIT", + "dependencies": { + "cors": "^2.8.5", + "dotenv": "^17.2.3", + "express": "^5.2.1", + "morgan": "^1.10.1", + "mysql2": "^3.16.0", + "swagger-jsdoc": "^6.2.8", + "swagger-ui-express": "^5.0.1" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..e54ea16 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,975 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + cors: + specifier: ^2.8.5 + version: 2.8.5 + dotenv: + specifier: ^17.2.3 + version: 17.2.3 + express: + specifier: ^5.2.1 + version: 5.2.1 + morgan: + specifier: ^1.10.1 + version: 1.10.1 + mysql2: + specifier: ^3.16.0 + version: 3.16.0 + swagger-jsdoc: + specifier: ^6.2.8 + version: 6.2.8(openapi-types@12.1.3) + swagger-ui-express: + specifier: ^5.0.1 + version: 5.0.1(express@5.2.1) + +packages: + + '@apidevtools/json-schema-ref-parser@9.1.2': + resolution: {integrity: sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==} + + '@apidevtools/openapi-schemas@2.1.0': + resolution: {integrity: sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==} + engines: {node: '>=10'} + + '@apidevtools/swagger-methods@3.0.2': + resolution: {integrity: sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==} + + '@apidevtools/swagger-parser@10.0.3': + resolution: {integrity: sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==} + peerDependencies: + openapi-types: '>=7' + + '@jsdevtools/ono@7.1.3': + resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + + '@scarf/scarf@1.4.0': + resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aws-ssl-profiles@1.1.2: + resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==} + engines: {node: '>= 6.0.0'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + basic-auth@2.0.1: + resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} + engines: {node: '>= 0.8'} + + body-parser@2.2.1: + resolution: {integrity: sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==} + engines: {node: '>=18'} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + call-me-maybe@1.0.2: + resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} + + commander@6.2.0: + resolution: {integrity: sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==} + engines: {node: '>= 6'} + + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + content-disposition@1.0.1: + resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dotenv@17.2.3: + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + generate-function@2.3.1: + resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + glob@7.1.6: + resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} + deprecated: Glob versions prior to v9 are no longer supported + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + iconv-lite@0.7.1: + resolution: {integrity: sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==} + engines: {node: '>=0.10.0'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + is-property@1.0.2: + resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + + lodash.mergewith@4.6.2: + resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} + + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + + lru.min@1.1.3: + resolution: {integrity: sha512-Lkk/vx6ak3rYkRR0Nhu4lFUT2VDnQSxBe8Hbl7f36358p6ow8Bnvr8lrLt98H8J1aGxfhbX4Fs5tYg2+FTwr5Q==} + engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + morgan@1.10.1: + resolution: {integrity: sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==} + engines: {node: '>= 0.8.0'} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mysql2@3.16.0: + resolution: {integrity: sha512-AEGW7QLLSuSnjCS4pk3EIqOmogegmze9h8EyrndavUQnIUcfkVal/sK7QznE+a3bc6rzPbAiui9Jcb+96tPwYA==} + engines: {node: '>= 8.0'} + + named-placeholders@1.1.6: + resolution: {integrity: sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==} + engines: {node: '>=8.0.0'} + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + on-finished@2.3.0: + resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} + engines: {node: '>= 0.8'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-to-regexp@8.3.0: + resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + qs@6.14.1: + resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==} + engines: {node: '>=0.6'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + seq-queue@0.0.5: + resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + sqlstring@2.3.3: + resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==} + engines: {node: '>= 0.6'} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + swagger-jsdoc@6.2.8: + resolution: {integrity: sha512-VPvil1+JRpmJ55CgAtn8DIcpBs0bL5L3q5bVQvF4tAW/k/9JYSj7dCpaYCAv5rufe0vcCbBRQXGvzpkWjvLklQ==} + engines: {node: '>=12.0.0'} + hasBin: true + + swagger-parser@10.0.3: + resolution: {integrity: sha512-nF7oMeL4KypldrQhac8RyHerJeGPD1p2xDh900GPvc+Nk7nWP6jX2FcC7WmkinMoAmoO774+AFXcWsW8gMWEIg==} + engines: {node: '>=10'} + + swagger-ui-dist@5.31.0: + resolution: {integrity: sha512-zSUTIck02fSga6rc0RZP3b7J7wgHXwLea8ZjgLA3Vgnb8QeOl3Wou2/j5QkzSGeoz6HusP/coYuJl33aQxQZpg==} + + swagger-ui-express@5.0.1: + resolution: {integrity: sha512-SrNU3RiBGTLLmFU8GIJdOdanJTl4TOmT27tt3bWWHppqYmAZ6IDuEuBvMU6nZq0zLEe6b/1rACXCgLZqO6ZfrA==} + engines: {node: '>= v0.10.32'} + peerDependencies: + express: '>=4.0.0 || >=5.0.0-beta' + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + validator@13.15.26: + resolution: {integrity: sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==} + engines: {node: '>= 0.10'} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + yaml@2.0.0-1: + resolution: {integrity: sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==} + engines: {node: '>= 6'} + + z-schema@5.0.5: + resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} + engines: {node: '>=8.0.0'} + hasBin: true + +snapshots: + + '@apidevtools/json-schema-ref-parser@9.1.2': + dependencies: + '@jsdevtools/ono': 7.1.3 + '@types/json-schema': 7.0.15 + call-me-maybe: 1.0.2 + js-yaml: 4.1.1 + + '@apidevtools/openapi-schemas@2.1.0': {} + + '@apidevtools/swagger-methods@3.0.2': {} + + '@apidevtools/swagger-parser@10.0.3(openapi-types@12.1.3)': + dependencies: + '@apidevtools/json-schema-ref-parser': 9.1.2 + '@apidevtools/openapi-schemas': 2.1.0 + '@apidevtools/swagger-methods': 3.0.2 + '@jsdevtools/ono': 7.1.3 + call-me-maybe: 1.0.2 + openapi-types: 12.1.3 + z-schema: 5.0.5 + + '@jsdevtools/ono@7.1.3': {} + + '@scarf/scarf@1.4.0': {} + + '@types/json-schema@7.0.15': {} + + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.0.0 + + argparse@2.0.1: {} + + aws-ssl-profiles@1.1.2: {} + + balanced-match@1.0.2: {} + + basic-auth@2.0.1: + dependencies: + safe-buffer: 5.1.2 + + body-parser@2.2.1: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.1 + on-finished: 2.4.1 + qs: 6.14.1 + raw-body: 3.0.2 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + bytes@3.1.2: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + call-me-maybe@1.0.2: {} + + commander@6.2.0: {} + + commander@9.5.0: + optional: true + + concat-map@0.0.1: {} + + content-disposition@1.0.1: {} + + content-type@1.0.5: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + denque@2.1.0: {} + + depd@2.0.0: {} + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dotenv@17.2.3: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ee-first@1.1.1: {} + + encodeurl@2.0.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + escape-html@1.0.3: {} + + esutils@2.0.3: {} + + etag@1.8.1: {} + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.1 + content-disposition: 1.0.1 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.14.1 + range-parser: 1.2.1 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + forwarded@0.2.0: {} + + fresh@2.0.0: {} + + fs.realpath@1.0.0: {} + + function-bind@1.1.2: {} + + generate-function@2.3.1: + dependencies: + is-property: 1.0.2 + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + glob@7.1.6: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + gopd@1.2.0: {} + + has-symbols@1.1.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + iconv-lite@0.7.1: + dependencies: + safer-buffer: 2.1.2 + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ipaddr.js@1.9.1: {} + + is-promise@4.0.0: {} + + is-property@1.0.2: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + lodash.get@4.4.2: {} + + lodash.isequal@4.5.0: {} + + lodash.mergewith@4.6.2: {} + + long@5.3.2: {} + + lru.min@1.1.3: {} + + math-intrinsics@1.1.0: {} + + media-typer@1.1.0: {} + + merge-descriptors@2.0.0: {} + + mime-db@1.54.0: {} + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + morgan@1.10.1: + dependencies: + basic-auth: 2.0.1 + debug: 2.6.9 + depd: 2.0.0 + on-finished: 2.3.0 + on-headers: 1.1.0 + transitivePeerDependencies: + - supports-color + + ms@2.0.0: {} + + ms@2.1.3: {} + + mysql2@3.16.0: + dependencies: + aws-ssl-profiles: 1.1.2 + denque: 2.1.0 + generate-function: 2.3.1 + iconv-lite: 0.7.1 + long: 5.3.2 + lru.min: 1.1.3 + named-placeholders: 1.1.6 + seq-queue: 0.0.5 + sqlstring: 2.3.3 + + named-placeholders@1.1.6: + dependencies: + lru.min: 1.1.3 + + negotiator@1.0.0: {} + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + on-finished@2.3.0: + dependencies: + ee-first: 1.1.1 + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + on-headers@1.1.0: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + openapi-types@12.1.3: {} + + parseurl@1.3.3: {} + + path-is-absolute@1.0.1: {} + + path-to-regexp@8.3.0: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + qs@6.14.1: + dependencies: + side-channel: 1.1.0 + + range-parser@1.2.1: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.1 + unpipe: 1.0.0 + + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.3.0 + transitivePeerDependencies: + - supports-color + + safe-buffer@5.1.2: {} + + safer-buffer@2.1.2: {} + + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + seq-queue@0.0.5: {} + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + setprototypeof@1.2.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + sqlstring@2.3.3: {} + + statuses@2.0.2: {} + + swagger-jsdoc@6.2.8(openapi-types@12.1.3): + dependencies: + commander: 6.2.0 + doctrine: 3.0.0 + glob: 7.1.6 + lodash.mergewith: 4.6.2 + swagger-parser: 10.0.3(openapi-types@12.1.3) + yaml: 2.0.0-1 + transitivePeerDependencies: + - openapi-types + + swagger-parser@10.0.3(openapi-types@12.1.3): + dependencies: + '@apidevtools/swagger-parser': 10.0.3(openapi-types@12.1.3) + transitivePeerDependencies: + - openapi-types + + swagger-ui-dist@5.31.0: + dependencies: + '@scarf/scarf': 1.4.0 + + swagger-ui-express@5.0.1(express@5.2.1): + dependencies: + express: 5.2.1 + swagger-ui-dist: 5.31.0 + + toidentifier@1.0.1: {} + + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.2 + + unpipe@1.0.0: {} + + validator@13.15.26: {} + + vary@1.1.2: {} + + wrappy@1.0.2: {} + + yaml@2.0.0-1: {} + + z-schema@5.0.5: + dependencies: + lodash.get: 4.4.2 + lodash.isequal: 4.5.0 + validator: 13.15.26 + optionalDependencies: + commander: 9.5.0 diff --git a/scripts/import-data.js b/scripts/import-data.js new file mode 100644 index 0000000..4eb3c62 --- /dev/null +++ b/scripts/import-data.js @@ -0,0 +1,159 @@ +require('dotenv').config(); +const fs = require('fs'); +const path = require('path'); +const Price = require('../src/models/Price'); + +/** + * 数据导入脚本 + * 从 JSON 文件导入钢材价格数据到数据库 + */ + +// 数据文件映射 +const dataFiles = [ + { file: '刚协指导价.json', source: '云南钢协', priceField: 'PR_PRICESET_HANGPRICE' }, + { file: '钢材网架.json', source: '我的钢铁', priceField: 'PR_PRICESET_HANGPRICE' }, + { file: '钢厂指导价.json', source: '德钢指导价', priceField: 'PR_PRICESET_HANGPRICE' } +]; + +/** + * 转换数据格式 + */ +function transformData(rawData, source, priceField) { + if (!rawData || !rawData.data || !rawData.data.page || !rawData.data.page.result) { + return []; + } + + return rawData.data.page.result.map(item => { + return { + price_id: item.PRICE_ID || null, + goods_material: item.GOODS_MATERIAL || '未知', + goods_spec: item.GOODS_SPEC || '未知', + partsname_name: item.PARTSNAME_NAME || '未知', + productarea_name: item.PRODUCTAREA_NAME || '未知', + price_source: item.PR_PRICE_SOURCE || source, + price_region: item.PR_PRICE_REGION || '未知', + pntree_name: item.PNTREE_NAME || '钢筋', + price_date: item.PIRCE_DATE || null, + make_price: item.PR_PRICESET_MAKEPRICE || null, + hang_price: item[priceField] || 0, + last_make_price: item.PR_LAST_PRICESET_MAKEPRICE || null, + last_hang_price: item.PR_LAST_PRICESET_HANGPRICE || 0, + make_price_updw: item.PR_MAKEPRICE_UPDW || null, + hang_price_updw: item.PR_HANGPRICE_UPDW || '0', + operator_code: item.OPERATOR_CODE || null, + operator_name: item.OPERATOR_NAME || null + }; + }).filter(item => item.price_date && item.hang_price > 0); // 过滤无效数据 +} + +/** + * 导入单个数据文件 + */ +async function importFile(filePath, source, priceField) { + try { + console.log(`\n📄 正在读取文件: ${path.basename(filePath)}`); + + // 读取 JSON 文件 + const rawData = JSON.parse(fs.readFileSync(filePath, 'utf8')); + + // 转换数据格式 + const prices = transformData(rawData, source, priceField); + console.log(`✅ 解析到 ${prices.length} 条有效数据`); + + if (prices.length === 0) { + console.log('⚠️ 没有有效数据可导入'); + return 0; + } + + // 批量插入数据库(每批 1000 条) + const batchSize = 1000; + let totalImported = 0; + + for (let i = 0; i < prices.length; i += batchSize) { + const batch = prices.slice(i, i + batchSize); + const imported = await Price.batchInsert(batch); + totalImported += imported; + console.log(` 进度: ${Math.min(i + batchSize, prices.length)}/${prices.length} 条`); + } + + console.log(`✅ 成功导入 ${totalImported} 条数据`); + return totalImported; + + } catch (error) { + console.error(`❌ 导入文件失败 ${path.basename(filePath)}:`, error.message); + return 0; + } +} + +/** + * 主导入函数 + */ +async function importAllData() { + console.log('🚀 开始导入钢材价格数据...\n'); + + let totalImported = 0; + const dataDir = path.join(__dirname, '../data'); + + for (const { file, source, priceField } of dataFiles) { + const filePath = path.join(dataDir, file); + + // 检查文件是否存在 + if (!fs.existsSync(filePath)) { + console.log(`⚠️ 文件不存在,跳过: ${file}`); + continue; + } + + const count = await importFile(filePath, source, priceField); + totalImported += count; + } + + console.log('\n' + '='.repeat(50)); + console.log(`🎉 数据导入完成!总计导入 ${totalImported} 条数据`); + console.log('='.repeat(50)); + + return totalImported; +} + +/** + * 查看导入统计 + */ +async function showStats() { + try { + const total = await Price.count(); + const stats = await Price.getStats({}); + + console.log('\n📊 数据库统计信息:'); + console.log(` 总记录数: ${total}`); + + // 处理 avgPrice 可能是字符串或 null 的情况 + if (stats.avgPrice) { + const avgPrice = typeof stats.avgPrice === 'number' + ? stats.avgPrice.toFixed(2) + : parseFloat(stats.avgPrice).toFixed(2); + console.log(` 平均价格: ${avgPrice} 元/吨`); + } else { + console.log(` 平均价格: N/A`); + } + + console.log(` 最低价格: ${stats.minPrice || 'N/A'} 元/吨`); + console.log(` 最高价格: ${stats.maxPrice || 'N/A'} 元/吨`); + } catch (error) { + console.error('❌ 获取统计信息失败:', error.message); + } +} + +// 如果直接运行此脚本 +if (require.main === module) { + importAllData() + .then(() => showStats()) + .then(() => { + console.log('\n✅ 脚本执行完成'); + process.exit(0); + }) + .catch(err => { + console.error('\n❌ 脚本执行失败:', err); + process.exit(1); + }); +} + +module.exports = { importAllData, importFile, transformData }; diff --git a/scripts/init-db.js b/scripts/init-db.js new file mode 100644 index 0000000..6d7f3b9 --- /dev/null +++ b/scripts/init-db.js @@ -0,0 +1,94 @@ +require('dotenv').config(); +const mysql = require('mysql2/promise'); + +/** + * 数据库初始化脚本 + * 创建数据库和表结构 + */ +async function initDatabase() { + const connection = await mysql.createConnection({ + host: process.env.DB_HOST || 'localhost', + port: parseInt(process.env.DB_PORT || '3306'), + user: process.env.DB_USER || 'root', + password: process.env.DB_PASSWORD || '', + multipleStatements: true + }); + + try { + const dbName = process.env.DB_NAME || 'steel_prices'; + + // 创建数据库 + console.log(`📦 正在创建数据库: ${dbName}`); + await connection.execute( + `CREATE DATABASE IF NOT EXISTS ${dbName} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci` + ); + console.log('✅ 数据库创建成功'); + + // 切换到目标数据库 + await connection.changeUser({ database: dbName }); + + // 创建价格表 + console.log('📋 正在创建价格表...'); + const createTableSQL = ` + CREATE TABLE IF NOT EXISTS prices ( + id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '自增主键', + 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 DEFAULT NULL COMMENT '钢厂价(元/吨)', + hang_price INT NOT NULL COMMENT '挂牌价(元/吨)', + last_make_price INT DEFAULT NULL COMMENT '上次钢厂价', + last_hang_price INT DEFAULT NULL COMMENT '上次挂牌价', + make_price_updw VARCHAR(8) DEFAULT NULL COMMENT '钢厂价涨跌', + hang_price_updw VARCHAR(8) DEFAULT NULL COMMENT '挂牌价涨跌', + operator_code VARCHAR(16) DEFAULT NULL COMMENT '操作员代码', + operator_name VARCHAR(32) DEFAULT NULL COMMENT '操作员名称', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + INDEX idx_price_date (price_date), + INDEX idx_region_material (price_region, goods_material), + INDEX idx_source_date (price_source, price_date), + INDEX idx_goods_spec (goods_spec) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='钢材价格表' + `; + + await connection.execute(createTableSQL); + console.log('✅ 价格表创建成功'); + + // 显示表结构信息 + const [tables] = await connection.execute('SHOW TABLES'); + console.log('\n📊 当前数据库表:'); + tables.forEach(table => { + console.log(` - ${Object.values(table)[0]}`); + }); + + console.log('\n🎉 数据库初始化完成!'); + + } catch (error) { + console.error('❌ 数据库初始化失败:', error.message); + throw error; + } finally { + await connection.end(); + } +} + +// 如果直接运行此脚本 +if (require.main === module) { + initDatabase() + .then(() => { + console.log('✅ 脚本执行完成'); + process.exit(0); + }) + .catch(err => { + console.error('❌ 脚本执行失败:', err); + process.exit(1); + }); +} + +module.exports = initDatabase; diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..a3b78fa --- /dev/null +++ b/src/app.js @@ -0,0 +1,46 @@ +const express = require('express'); +const cors = require('cors'); +const swaggerUi = require('swagger-ui-express'); +const logger = require('./config/logger'); +const swaggerSpec = require('./config/swagger'); +const routes = require('./routes'); +const { notFound, errorHandler } = require('./middlewares/errorHandler'); + +/** + * 创建 Express 应用 + */ +function createApp() { + const app = express(); + + // 中间件配置 + app.use(cors()); // 跨域支持 + app.use(express.json()); // JSON 解析 + app.use(express.urlencoded({ extended: true })); // URL 编码解析 + app.use(logger); // 日志记录 + + // API 文档 - Swagger UI + app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec, { + explorer: true, + customCss: '.swagger-ui .topbar { display: none }', + customSiteTitle: 'Steel Prices Service API Documentation', + swaggerOptions: { + persistAuthorization: true, + displayRequestDuration: true, + docExpansion: 'list', + filter: true, + showRequestHeaders: true, + tryItOutEnabled: true + } + })); + + // 路由 + app.use('/', routes); + + // 错误处理 + app.use(notFound); + app.use(errorHandler); + + return app; +} + +module.exports = createApp; diff --git a/src/config/database.js b/src/config/database.js new file mode 100644 index 0000000..c2b697a --- /dev/null +++ b/src/config/database.js @@ -0,0 +1,28 @@ +const mysql = require('mysql2/promise'); +require('dotenv').config(); + +// 创建数据库连接池 +const pool = mysql.createPool({ + host: process.env.DB_HOST || 'localhost', + port: parseInt(process.env.DB_PORT || '3306'), + user: process.env.DB_USER || 'root', + password: process.env.DB_PASSWORD || '', + database: process.env.DB_NAME || 'steel_prices', + waitForConnections: true, + connectionLimit: 10, + queueLimit: 0, + charset: 'utf8mb4', + timezone: '+08:00' +}); + +// 测试数据库连接 +pool.getConnection() + .then(connection => { + console.log('✅ 数据库连接成功'); + connection.release(); + }) + .catch(err => { + console.error('❌ 数据库连接失败:', err.message); + }); + +module.exports = pool; diff --git a/src/config/logger.js b/src/config/logger.js new file mode 100644 index 0000000..ab820e4 --- /dev/null +++ b/src/config/logger.js @@ -0,0 +1,48 @@ +const morgan = require('morgan'); +const fs = require('fs'); +const path = require('path'); + +// 创建 logs 目录(如果不存在) +const logsDir = path.join(__dirname, '../../logs'); +if (!fs.existsSync(logsDir)) { + fs.mkdirSync(logsDir); +} + +// 自定义 token:记录请求ID +morgan.token('request-id', (req) => { + return req.id || 'N/A'; +}); + +// 开发环境日志格式 +const developmentFormat = ':method :url :status :response-time ms - :res[content-length]'; + +// 生产环境日志格式 +const productionFormat = JSON.stringify({ + method: ':method', + url: ':url', + status: ':status', + response_time: ':response-time', + content_length: ':res[content-length]', + request_id: ':request-id', + timestamp: ':date[iso]' +}); + +// 根据环境选择日志格式 +const format = process.env.NODE_ENV === 'production' ? productionFormat : developmentFormat; + +// 创建 Morgan 中间件 +const logger = morgan(format, { + stream: { + write: (message) => { + // 在控制台输出 + console.log(message.trim()); + // 写入文件(生产环境) + if (process.env.NODE_ENV === 'production') { + const logFile = path.join(logsDir, 'access.log'); + fs.appendFileSync(logFile, message + '\n'); + } + } + } +}); + +module.exports = logger; diff --git a/src/config/swagger.js b/src/config/swagger.js new file mode 100644 index 0000000..f2ad791 --- /dev/null +++ b/src/config/swagger.js @@ -0,0 +1,336 @@ +const swaggerJsdoc = require('swagger-jsdoc'); + +const options = { + definition: { + openapi: '3.0.0', + info: { + title: 'Steel Prices Service API', + version: '1.0.0', + description: ` + 钢材价格查询与分析服务平台 API 文档 + + ## 功能特性 + - 📊 **价格查询** - 按地区、材质、规格等多维度查询钢材价格 + - 🔍 **智能搜索** - 支持多条件组合搜索和分页 + - 📈 **统计分析** - 价格统计、趋势分析、均价计算 + - 💾 **数据导入** - 批量导入钢材价格数据 + - 🚀 **高性能** - 数据库索引优化,查询响应快速 + + ## 数据源 + - 我的钢铁网(重庆、成都、广州、南宁) + - 德钢指导价(云南地区) + - 云南钢协(昆明、玉溪、楚雄、大理) + + ## 认证 + 当前版本无需认证,后续版本将添加 API Key 认证。 + `, + contact: { + name: 'Steel Prices Service', + email: 'support@example.com' + }, + license: { + name: 'MIT', + url: 'https://opensource.org/licenses/MIT' + } + }, + servers: [ + { + url: 'http://localhost:3000', + description: '开发服务器' + }, + { + url: 'https://api.steel-prices.com', + description: '生产服务器' + } + ], + tags: [ + { + name: 'Health', + description: '健康检查和系统状态' + }, + { + name: 'Prices', + description: '价格查询、搜索和统计分析' + }, + { + name: 'Data', + description: '数据导入和管理' + } + ], + components: { + schemas: { + Price: { + type: 'object', + description: '钢材价格数据模型', + properties: { + id: { + type: 'integer', + description: '价格记录ID', + example: 1 + }, + region: { + type: 'string', + description: '地区', + example: '昆明' + }, + city: { + type: 'string', + description: '城市', + example: '昆明', + nullable: true + }, + material: { + type: 'string', + description: '材质', + example: 'HPB300' + }, + specification: { + type: 'string', + description: '规格型号', + example: 'Φ8', + nullable: true + }, + price: { + type: 'number', + format: 'decimal', + description: '价格(元/吨)', + example: 3840.00 + }, + unit: { + type: 'string', + description: '单位', + example: '元/吨' + }, + date: { + type: 'string', + format: 'date', + description: '价格日期', + example: '2026-01-05' + }, + source: { + type: 'string', + description: '数据来源', + example: '云南钢协', + nullable: true + }, + warehouse: { + type: 'string', + description: '仓库/厂家', + example: '玉昆', + nullable: true + }, + created_at: { + type: 'string', + format: 'date-time', + description: '创建时间' + }, + updated_at: { + type: 'string', + format: 'date-time', + description: '更新时间' + } + }, + required: ['region', 'material', 'price', 'date'] + }, + SuccessResponse: { + type: 'object', + properties: { + success: { + type: 'boolean', + example: true + }, + data: { + type: 'object' + } + } + }, + ErrorResponse: { + type: 'object', + properties: { + success: { + type: 'boolean', + example: false + }, + message: { + type: 'string', + description: '错误信息', + example: '参数验证失败' + }, + statusCode: { + type: 'integer', + description: 'HTTP 状态码', + example: 400 + } + } + }, + Pagination: { + type: 'object', + properties: { + page: { + type: 'integer', + description: '当前页码', + example: 1 + }, + pageSize: { + type: 'integer', + description: '每页数量', + example: 20 + }, + total: { + type: 'integer', + description: '总记录数', + example: 100 + }, + totalPages: { + type: 'integer', + description: '总页数', + example: 5 + } + } + }, + PriceStats: { + type: 'object', + properties: { + count: { + type: 'integer', + description: '记录数量', + example: 150 + }, + avgPrice: { + type: 'number', + description: '平均价格', + example: 3950.50 + }, + minPrice: { + type: 'number', + description: '最低价格', + example: 3500.00 + }, + maxPrice: { + type: 'number', + description: '最高价格', + example: 4500.00 + }, + stdDev: { + type: 'number', + description: '标准差', + example: 250.30 + }, + trend: { + type: 'string', + enum: ['up', 'down', 'stable'], + description: '价格趋势', + example: 'up' + }, + changeRate: { + type: 'string', + description: '变化率', + example: '+2.5%' + } + } + }, + TrendData: { + type: 'object', + properties: { + date: { + type: 'string', + format: 'date', + description: '日期', + example: '2026-01-05' + }, + avgPrice: { + type: 'number', + description: '当日平均价格', + example: 3950.50 + }, + minPrice: { + type: 'number', + description: '当日最低价格', + example: 3800.00 + }, + maxPrice: { + type: 'number', + description: '当日最高价格', + example: 4100.00 + } + } + } + }, + parameters: { + RegionParam: { + name: 'region', + in: 'query', + description: '地区名称(如:昆明、玉溪、大理等)', + required: true, + schema: { + type: 'string' + }, + example: '昆明' + }, + DateParam: { + name: 'date', + in: 'query', + description: '价格日期(格式:YYYY-MM-DD)', + required: false, + schema: { + type: 'string', + format: 'date' + }, + example: '2026-01-05' + }, + MaterialParam: { + name: 'material', + in: 'query', + description: '材质(如:HPB300、HRB400、HRB500E 等)', + required: false, + schema: { + type: 'string' + }, + example: 'HPB300' + }, + DaysParam: { + name: 'days', + in: 'query', + description: '统计天数(1-3650天)', + required: false, + schema: { + type: 'integer', + minimum: 1, + maximum: 3650 + }, + example: 30 + }, + PageParam: { + name: 'page', + in: 'query', + description: '页码(从1开始)', + required: false, + schema: { + type: 'integer', + minimum: 1, + default: 1 + }, + example: 1 + }, + PageSizeParam: { + name: 'pageSize', + in: 'query', + description: '每页数量(1-1000)', + required: false, + schema: { + type: 'integer', + minimum: 1, + maximum: 1000, + default: 20 + }, + example: 20 + } + } + } + }, + apis: ['./src/routes/*.js', './src/controllers/*.js'] +}; + +const swaggerSpec = swaggerJsdoc(options); + +module.exports = swaggerSpec; diff --git a/src/controllers/priceController.js b/src/controllers/priceController.js new file mode 100644 index 0000000..4dfddde --- /dev/null +++ b/src/controllers/priceController.js @@ -0,0 +1,65 @@ +const PriceService = require('../services/priceService'); +const { asyncHandler } = require('../middlewares/errorHandler'); + +/** + * 价格控制器 + * 处理 HTTP 请求和响应 + */ +class PriceController { + /** + * 按地区查询价格 + * GET /api/prices/region?region=昆明&date=2026-01-05&page=1&pageSize=20 + */ + static getByRegion = asyncHandler(async (req, res) => { + const { region, date, page = 1, pageSize = 20 } = req.query; + + const result = await PriceService.getByRegion(region, date, page, pageSize); + res.json(result); + }); + + /** + * 搜索价格数据 + * GET /api/prices/search?material=螺纹钢&startDate=2026-01-01&endDate=2026-01-05 + */ + static search = asyncHandler(async (req, res) => { + const filters = req.query; + + const result = await PriceService.search(filters); + res.json(result); + }); + + /** + * 获取价格统计 + * GET /api/prices/stats?region=昆明&material=螺纹钢&days=30 + */ + static getStats = asyncHandler(async (req, res) => { + const filters = req.query; + + const result = await PriceService.getStats(filters); + res.json(result); + }); + + /** + * 获取价格趋势 + * GET /api/prices/trend?region=昆明&material=螺纹钢&days=30 + */ + static getTrend = asyncHandler(async (req, res) => { + const filters = req.query; + + const result = await PriceService.getTrend(filters); + res.json(result); + }); + + /** + * 导入数据 + * POST /api/prices/import + */ + static importData = asyncHandler(async (req, res) => { + const { prices } = req.body; + + const result = await PriceService.importData(prices); + res.json(result); + }); +} + +module.exports = PriceController; diff --git a/src/middlewares/errorHandler.js b/src/middlewares/errorHandler.js new file mode 100644 index 0000000..0870fcb --- /dev/null +++ b/src/middlewares/errorHandler.js @@ -0,0 +1,74 @@ +/** + * 统一错误处理中间件 + */ + +/** + * 404 错误处理 + */ +function notFound(req, res, next) { + const error = new Error(`Not Found - ${req.originalUrl}`); + error.statusCode = 404; + next(error); +} + +/** + * 统一错误响应处理 + */ +function errorHandler(err, req, res, next) { + // 设置状态码 + const statusCode = err.statusCode || 500; + + // 开发环境返回详细错误信息,生产环境返回简化信息 + const isDevelopment = process.env.NODE_ENV === 'development'; + + res.status(statusCode).json({ + success: false, + message: err.message || '服务器内部错误', + error: isDevelopment ? { + stack: err.stack, + ...err + } : undefined, + statusCode + }); + + // 记录错误日志 + if (statusCode >= 500) { + console.error('❌ Server Error:', { + message: err.message, + stack: err.stack, + url: req.originalUrl, + method: req.method, + body: req.body, + query: req.query, + params: req.params + }); + } +} + +/** + * 异步错误捕获包装器 + */ +function asyncHandler(fn) { + return (req, res, next) => { + Promise.resolve(fn(req, res, next)).catch(next); + }; +} + +/** + * 自定义错误类 + */ +class AppError extends Error { + constructor(message, statusCode = 500) { + super(message); + this.statusCode = statusCode; + this.isOperational = true; + Error.captureStackTrace(this, this.constructor); + } +} + +module.exports = { + notFound, + errorHandler, + asyncHandler, + AppError +}; diff --git a/src/middlewares/validator.js b/src/middlewares/validator.js new file mode 100644 index 0000000..d7e9d43 --- /dev/null +++ b/src/middlewares/validator.js @@ -0,0 +1,126 @@ +/** + * 请求验证中间件 + */ + +/** + * 验证查询价格请求 + */ +function validatePriceQuery(req, res, next) { + const { region, date } = req.query; + + // 地区参数验证 + if (!region) { + return res.status(400).json({ + success: false, + message: '缺少必需参数: region(地区)' + }); + } + + // 日期格式验证(如果提供) + if (date && !isValidDate(date)) { + return res.status(400).json({ + success: false, + message: '日期格式无效,应为 YYYY-MM-DD' + }); + } + + next(); +} + +/** + * 验证搜索请求 + */ +function validateSearch(req, res, next) { + const { material, specification, startDate, endDate, page, pageSize } = req.query; + + // 至少需要一个搜索条件 + if (!material && !specification && !startDate && !endDate) { + return res.status(400).json({ + success: false, + message: '至少提供一个搜索条件: material, specification, startDate, endDate' + }); + } + + // 日期格式验证 + if (startDate && !isValidDate(startDate)) { + return res.status(400).json({ + success: false, + message: '开始日期格式无效,应为 YYYY-MM-DD' + }); + } + + if (endDate && !isValidDate(endDate)) { + return res.status(400).json({ + success: false, + message: '结束日期格式无效,应为 YYYY-MM-DD' + }); + } + + // 分页参数验证 + if (page && (isNaN(page) || parseInt(page) < 1)) { + return res.status(400).json({ + success: false, + message: '页码必须大于 0' + }); + } + + if (pageSize && (isNaN(pageSize) || parseInt(pageSize) < 1 || parseInt(pageSize) > 1000)) { + return res.status(400).json({ + success: false, + message: '每页数量必须在 1-1000 之间' + }); + } + + next(); +} + +/** + * 验证统计请求 + */ +function validateStats(req, res, next) { + const { region, material, days, startDate, endDate } = req.query; + + // 天数验证 + if (days && (isNaN(days) || parseInt(days) < 1 || parseInt(days) > 3650)) { + return res.status(400).json({ + success: false, + message: '天数必须在 1-3650 之间' + }); + } + + // 日期格式验证 + if (startDate && !isValidDate(startDate)) { + return res.status(400).json({ + success: false, + message: '开始日期格式无效,应为 YYYY-MM-DD' + }); + } + + if (endDate && !isValidDate(endDate)) { + return res.status(400).json({ + success: false, + message: '结束日期格式无效,应为 YYYY-MM-DD' + }); + } + + next(); +} + +/** + * 验证日期格式 YYYY-MM-DD + */ +function isValidDate(dateString) { + const regex = /^\d{4}-\d{2}-\d{2}$/; + if (!regex.test(dateString)) { + return false; + } + + const date = new Date(dateString); + return date instanceof Date && !isNaN(date); +} + +module.exports = { + validatePriceQuery, + validateSearch, + validateStats +}; diff --git a/src/models/Price.js b/src/models/Price.js new file mode 100644 index 0000000..4a827e7 --- /dev/null +++ b/src/models/Price.js @@ -0,0 +1,383 @@ +const db = require('../config/database'); + +/** + * 钢材价格数据模型 + */ +class Price { + /** + * 创建价格记录表 + */ + static async createTable() { + const createTableSQL = ` + CREATE TABLE IF NOT EXISTS prices ( + id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '自增主键', + 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 DEFAULT NULL COMMENT '钢厂价(元/吨)', + hang_price INT NOT NULL COMMENT '挂牌价(元/吨)', + last_make_price INT DEFAULT NULL COMMENT '上次钢厂价', + last_hang_price INT DEFAULT NULL COMMENT '上次挂牌价', + make_price_updw VARCHAR(8) DEFAULT NULL COMMENT '钢厂价涨跌', + hang_price_updw VARCHAR(8) DEFAULT NULL COMMENT '挂牌价涨跌', + operator_code VARCHAR(16) DEFAULT NULL COMMENT '操作员代码', + operator_name VARCHAR(32) DEFAULT NULL COMMENT '操作员名称', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + INDEX idx_price_date (price_date), + INDEX idx_region_material (price_region, goods_material), + INDEX idx_source_date (price_source, price_date), + INDEX idx_goods_spec (goods_spec) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='钢材价格表'; + `; + + try { + await db.execute(createTableSQL); + console.log('✅ 价格表创建成功'); + } catch (error) { + console.error('❌ 价格表创建失败:', error.message); + throw error; + } + } + + /** + * 插入单条价格记录 + */ + static async insert(priceData) { + const crypto = require('crypto'); + + // 如果 price_id 为空,生成一个基于内容的唯一 ID + let priceId = priceData.price_id; + if (!priceId) { + const hashContent = `${priceData.goods_material}-${priceData.goods_spec}-${priceData.price_region}-${priceData.price_source}-${priceData.price_date}`; + priceId = crypto.createHash('md5').update(hashContent).digest('hex').substring(0, 32); + } + + const sql = ` + INSERT INTO prices ( + price_id, goods_material, goods_spec, partsname_name, productarea_name, + price_source, price_region, pntree_name, price_date, + make_price, hang_price, last_make_price, last_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), + last_make_price = VALUES(last_make_price), + last_hang_price = VALUES(last_hang_price), + make_price_updw = VALUES(make_price_updw), + hang_price_updw = VALUES(hang_price_updw), + updated_at = CURRENT_TIMESTAMP + `; + + const values = [ + priceId, + priceData.goods_material, + priceData.goods_spec, + priceData.partsname_name, + priceData.productarea_name, + priceData.price_source, + priceData.price_region, + priceData.pntree_name, + priceData.price_date, + priceData.make_price || null, + priceData.hang_price, + priceData.last_make_price || null, + priceData.last_hang_price, + priceData.make_price_updw || null, + priceData.hang_price_updw || null, + priceData.operator_code || null, + priceData.operator_name || null + ]; + + try { + const [result] = await db.execute(sql, values); + return result; + } catch (error) { + console.error('❌ 插入价格数据失败:', error.message); + throw error; + } + } + + /** + * 批量插入价格记录 + */ + static async batchInsert(pricesArray) { + if (!pricesArray || pricesArray.length === 0) { + return 0; + } + + const crypto = require('crypto'); + + const sql = ` + INSERT INTO prices ( + price_id, goods_material, goods_spec, partsname_name, productarea_name, + price_source, price_region, pntree_name, price_date, + make_price, hang_price, last_make_price, last_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), + last_make_price = VALUES(last_make_price), + last_hang_price = VALUES(last_hang_price), + make_price_updw = VALUES(make_price_updw), + hang_price_updw = VALUES(hang_price_updw), + updated_at = CURRENT_TIMESTAMP + `; + + const values = pricesArray.map(item => { + // 如果 price_id 为空,生成一个基于内容的唯一 ID + let priceId = item.price_id; + if (!priceId) { + const hashContent = `${item.goods_material}-${item.goods_spec}-${item.price_region}-${item.price_source}-${item.price_date}`; + priceId = crypto.createHash('md5').update(hashContent).digest('hex').substring(0, 32); + } + + return [ + priceId, + item.goods_material, + item.goods_spec, + item.partsname_name, + item.productarea_name, + item.price_source, + item.price_region, + item.pntree_name, + item.price_date, + item.make_price || null, + item.hang_price, + item.last_make_price || null, + item.last_hang_price, + item.make_price_updw || null, + item.hang_price_updw || null, + item.operator_code || null, + item.operator_name || null + ]; + }); + + try { + const [result] = await db.query(sql, [values]); + return result.affectedRows; + } catch (error) { + console.error('❌ 批量插入价格数据失败:', error.message); + throw error; + } + } + + /** + * 按地区查询价格 + */ + static async getByRegion(region, date) { + let sql = 'SELECT * FROM prices WHERE price_region = ?'; + const params = [region]; + + if (date) { + sql += ' AND DATE(price_date) = ?'; + params.push(date); + } + + sql += ' ORDER BY price_date DESC, goods_material ASC'; + + try { + const [rows] = await db.execute(sql, params); + return rows; + } catch (error) { + console.error('❌ 查询价格数据失败:', error.message); + throw error; + } + } + + /** + * 按材质和规格查询 + */ + static async search(filters) { + let sql = 'SELECT * FROM prices WHERE 1=1'; + const params = []; + + if (filters.material) { + sql += ' AND goods_material LIKE ?'; + params.push(`%${filters.material}%`); + } + + if (filters.specification) { + sql += ' AND goods_spec LIKE ?'; + params.push(`%${filters.specification}%`); + } + + if (filters.startDate) { + sql += ' AND DATE(price_date) >= ?'; + params.push(filters.startDate); + } + + if (filters.endDate) { + sql += ' AND DATE(price_date) <= ?'; + params.push(filters.endDate); + } + + if (filters.region) { + sql += ' AND price_region = ?'; + params.push(filters.region); + } + + sql += ' ORDER BY price_date DESC, price_region ASC'; + + // 添加分页 + if (filters.page && filters.pageSize) { + const page = parseInt(filters.page, 10); + const pageSize = parseInt(filters.pageSize, 10); + const offset = (page - 1) * pageSize; + sql += ' LIMIT ? OFFSET ?'; + params.push(pageSize, offset); + } + + try { + const [rows] = await db.query(sql, params); + return rows; + } catch (error) { + console.error('❌ 搜索价格数据失败:', error.message); + throw error; + } + } + + /** + * 获取价格统计数据 + */ + static async getStats(filters) { + let sql = ` + SELECT + COUNT(*) as count, + AVG(hang_price) as avgPrice, + MIN(hang_price) as minPrice, + MAX(hang_price) as maxPrice, + STDDEV(hang_price) as stdDev + FROM prices + WHERE 1=1 + `; + const params = []; + + if (filters.region) { + sql += ' AND price_region = ?'; + params.push(filters.region); + } + + if (filters.material) { + sql += ' AND goods_material LIKE ?'; + params.push(`%${filters.material}%`); + } + + if (filters.days) { + sql += ' AND DATE(price_date) >= DATE_SUB(CURDATE(), INTERVAL ? DAY)'; + params.push(filters.days); + } + + if (filters.startDate) { + sql += ' AND DATE(price_date) >= ?'; + params.push(filters.startDate); + } + + if (filters.endDate) { + sql += ' AND DATE(price_date) <= ?'; + params.push(filters.endDate); + } + + try { + const [rows] = await db.execute(sql, params); + return rows[0]; + } catch (error) { + console.error('❌ 获取价格统计失败:', error.message); + throw error; + } + } + + /** + * 获取价格趋势 + */ + static async getTrend(filters) { + let sql = ` + SELECT + DATE(price_date) as date, + AVG(hang_price) as avgPrice, + MIN(hang_price) as minPrice, + MAX(hang_price) as maxPrice + FROM prices + WHERE 1=1 + `; + const params = []; + + if (filters.region) { + sql += ' AND price_region = ?'; + params.push(filters.region); + } + + if (filters.material) { + sql += ' AND goods_material LIKE ?'; + params.push(`%${filters.material}%`); + } + + if (filters.days) { + sql += ' AND DATE(price_date) >= DATE_SUB(CURDATE(), INTERVAL ? DAY)'; + params.push(filters.days); + } + + sql += ' GROUP BY DATE(price_date) ORDER BY date ASC'; + + try { + const [rows] = await db.execute(sql, params); + return rows; + } catch (error) { + console.error('❌ 获取价格趋势失败:', error.message); + throw error; + } + } + + /** + * 获取数据总数 + */ + static async count(filters = {}) { + let sql = 'SELECT COUNT(*) as total FROM prices WHERE 1=1'; + const params = []; + + if (filters.material) { + sql += ' AND goods_material LIKE ?'; + params.push(`%${filters.material}%`); + } + + if (filters.specification) { + sql += ' AND goods_spec LIKE ?'; + params.push(`%${filters.specification}%`); + } + + if (filters.region) { + sql += ' AND price_region = ?'; + params.push(filters.region); + } + + if (filters.startDate) { + sql += ' AND DATE(price_date) >= ?'; + params.push(filters.startDate); + } + + if (filters.endDate) { + sql += ' AND DATE(price_date) <= ?'; + params.push(filters.endDate); + } + + try { + const [rows] = await db.execute(sql, params); + return rows[0].total; + } catch (error) { + console.error('❌ 获取数据总数失败:', error.message); + throw error; + } + } +} + +module.exports = Price; diff --git a/src/models/index.js b/src/models/index.js new file mode 100644 index 0000000..a0cb88e --- /dev/null +++ b/src/models/index.js @@ -0,0 +1,5 @@ +const Price = require('./Price'); + +module.exports = { + Price +}; diff --git a/src/routes/api.js b/src/routes/api.js new file mode 100644 index 0000000..404d81e --- /dev/null +++ b/src/routes/api.js @@ -0,0 +1,532 @@ +const express = require('express'); +const PriceController = require('../controllers/priceController'); +const { validatePriceQuery, validateSearch, validateStats } = require('../middlewares/validator'); + +const router = express.Router(); + +/** + * @swagger + * /api/health: + * get: + * tags: + * - Health + * summary: 健康检查 + * description: 检查服务是否正常运行 + * responses: + * 200: + * description: 服务正常 + * content: + * application/json: + * schema: + * type: object + * properties: + * success: + * type: boolean + * example: true + * message: + * type: string + * example: Steel Prices Service is running + * timestamp: + * type: string + * format: date-time + */ +router.get('/health', (req, res) => { + res.json({ + success: true, + message: 'Steel Prices Service is running', + timestamp: new Date().toISOString() + }); +}); + +/** + * @swagger + * /api/prices/region: + * get: + * tags: + * - Prices + * summary: 按地区查询价格 + * description: 根据地区和日期查询钢材价格数据,支持按日期筛选或查询该地区所有价格数据 + * parameters: + * - $ref: '#/components/parameters/RegionParam' + * - $ref: '#/components/parameters/DateParam' + * responses: + * 200: + * description: 查询成功 + * content: + * application/json: + * schema: + * allOf: + * - $ref: '#/components/schemas/SuccessResponse' + * - type: object + * properties: + * data: + * type: array + * items: + * $ref: '#/components/schemas/Price' + * total: + * type: integer + * description: 返回的记录数量 + * example: 50 + * 400: + * description: 参数错误 + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * 500: + * description: 服务器错误 + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * examples: + * query_by_region_and_date: + * summary: 查询昆明地区 2026-01-05 的价格 + * value: + * region: 昆明 + * date: 2026-01-05 + * query_by_region_only: + * summary: 查询昆明地区所有价格数据 + * value: + * region: 昆明 + */ +router.get('/prices/region', validatePriceQuery, PriceController.getByRegion); + +/** + * @swagger + * /api/prices/search: + * get: + * tags: + * - Prices + * summary: 搜索价格数据 + * description: | + * 根据多个条件组合搜索钢材价格数据,支持分页返回结果。 + + * **搜索条件:** + * - material: 材质(支持模糊搜索) + * - specification: 规格型号(支持模糊搜索) + * - startDate: 开始日期 + * - endDate: 结束日期 + * - region: 地区 + * + * **分页参数:** + * - page: 页码(默认 1) + * - pageSize: 每页数量(默认 20,最大 1000) + * parameters: + * - name: material + * in: query + * description: 材质(支持模糊搜索,如:HPB300、HRB400、HRB500E) + * required: false + * schema: + * type: string + * example: HPB300 + * - name: specification + * in: query + * description: 规格型号(支持模糊搜索,如:Φ8、Φ16、HRB400) + * required: false + * schema: + * type: string + * example: Φ8 + * - name: startDate + * in: query + * description: 开始日期(格式:YYYY-MM-DD) + * required: false + * schema: + * type: string + * format: date + * example: 2026-01-01 + * - name: endDate + * in: query + * description: 结束日期(格式:YYYY-MM-DD) + * required: false + * schema: + * type: string + * format: date + * example: 2026-01-05 + * - name: region + * in: query + * description: 地区 + * required: false + * schema: + * type: string + * example: 昆明 + * - $ref: '#/components/parameters/PageParam' + * - $ref: '#/components/parameters/PageSizeParam' + * responses: + * 200: + * description: 搜索成功 + * content: + * application/json: + * schema: + * allOf: + * - $ref: '#/components/schemas/SuccessResponse' + * - type: object + * properties: + * data: + * type: array + * items: + * $ref: '#/components/schemas/Price' + * pagination: + * $ref: '#/components/schemas/Pagination' + * 400: + * description: 参数错误 + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * 500: + * description: 服务器错误 + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * examples: + * search_by_material: + * summary: 按材质搜索 + * value: + * material: HPB300 + * page: 1 + * pageSize: 20 + * search_by_date_range: + * summary: 按日期范围搜索 + * value: + * material: HRB400 + * startDate: 2026-01-01 + * endDate: 2026-01-05 + * page: 1 + * pageSize: 50 + */ +router.get('/prices/search', validateSearch, PriceController.search); + +/** + * @swagger + * /api/prices/stats: + * get: + * tags: + * - Prices + * summary: 获取价格统计 + * description: | + * 获取钢材价格的统计数据,包括平均值、最大值、最小值、标准差等。 + * + * **筛选条件:** + * - region: 指定地区 + * - material: 指定材质 + * - days: 统计最近 N 天的数据 + * - startDate/endDate: 指定日期范围 + * + * **统计指标:** + * - count: 记录数量 + * - avgPrice: 平均价格 + * - minPrice: 最低价格 + * - maxPrice: 最高价格 + * - stdDev: 标准差 + * - trend: 价格趋势(up/down/stable) + * - changeRate: 变化率(相对于上一周期) + * parameters: + * - name: region + * in: query + * description: 地区(可选) + * required: false + * schema: + * type: string + * example: 昆明 + * - name: material + * in: query + * description: 材质(可选,支持模糊搜索) + * required: false + * schema: + * type: string + * example: HPB300 + * - $ref: '#/components/parameters/DaysParam' + * - name: startDate + * in: query + * description: 开始日期(格式:YYYY-MM-DD) + * required: false + * schema: + * type: string + * format: date + * example: 2026-01-01 + * - name: endDate + * in: query + * description: 结束日期(格式:YYYY-MM-DD) + * required: false + * schema: + * type: string + * format: date + * example: 2026-01-05 + * responses: + * 200: + * description: 统计成功 + * content: + * application/json: + * schema: + * allOf: + * - $ref: '#/components/schemas/SuccessResponse' + * - type: object + * properties: + * data: + * $ref: '#/components/schemas/PriceStats' + * 400: + * description: 参数错误 + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * 500: + * description: 服务器错误 + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * examples: + * stats_by_region_and_days: + * summary: 统计昆明地区最近 30 天的 HPB300 价格 + * value: + * region: 昆明 + * material: HPB300 + * days: 30 + * stats_by_date_range: + * summary: 统计指定日期范围内的价格 + * value: + * startDate: 2026-01-01 + * endDate: 2026-01-05 + */ +router.get('/prices/stats', validateStats, PriceController.getStats); + +/** + * @swagger + * /api/prices/trend: + * get: + * tags: + * - Prices + * summary: 获取价格趋势 + * description: | + * 获取钢材价格的时间序列趋势数据,按日期分组统计。 + * + * **筛选条件:** + * - region: 指定地区 + * - material: 指定材质 + * - days: 统计最近 N 天的数据 + * + * **返回数据:** + * - date: 日期 + * - avgPrice: 当日平均价格 + * - minPrice: 当日最低价格 + * - maxPrice: 当日最高价格 + * + * **适用场景:** + * - 绘制价格走势图 + * - 分析价格波动规律 + * - 预测价格趋势 + * parameters: + * - name: region + * in: query + * description: 地区(可选) + * required: false + * schema: + * type: string + * example: 昆明 + * - name: material + * in: query + * description: 材质(可选,支持模糊搜索) + * required: false + * schema: + * type: string + * example: HPB300 + * - $ref: '#/components/parameters/DaysParam' + * responses: + * 200: + * description: 查询成功 + * content: + * application/json: + * schema: + * allOf: + * - $ref: '#/components/schemas/SuccessResponse' + * - type: object + * properties: + * data: + * type: array + * items: + * $ref: '#/components/schemas/TrendData' + * 400: + * description: 参数错误 + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * 500: + * description: 服务器错误 + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * examples: + * trend_by_region: + * summary: 获取昆明地区最近 30 天的价格趋势 + * value: + * region: 昆明 + * days: 30 + * trend_by_material: + * summary: 获取 HPB300 最近 60 天的价格趋势 + * value: + * material: HPB300 + * days: 60 + */ +router.get('/prices/trend', validateStats, PriceController.getTrend); + +/** + * @swagger + * /api/prices/import: + * post: + * tags: + * - Data + * summary: 导入价格数据 + * description: | + * 批量导入钢材价格数据到数据库。 + * + * **请求体格式:** + * ```json + * { + * "prices": [ + * { + * "region": "昆明", + * "city": "昆明", + * "material": "HPB300", + * "specification": "Φ8", + * "price": 3840.00, + * "unit": "元/吨", + * "date": "2026-01-05", + * "source": "云南钢协", + * "warehouse": "玉昆" + * } + * ] + * } + * ``` + * + * **注意事项:** + * - 必填字段:region, material, price, date + * - price 必须为数字类型 + * - date 格式必须为 YYYY-MM-DD + * - 重复数据会自动更新 + * requestBody: + * required: true + * content: + * application/json: + * schema: + * type: object + * required: + * - prices + * properties: + * prices: + * type: array + * description: 价格数据数组 + * items: + * type: object + * required: + * - region + * - material + * - price + * - date + * properties: + * region: + * type: string + * description: 地区 + * example: 昆明 + * city: + * type: string + * description: 城市 + * example: 昆明 + * material: + * type: string + * description: 材质 + * example: HPB300 + * specification: + * type: string + * description: 规格型号 + * example: Φ8 + * price: + * type: number + * format: decimal + * description: 价格 + * example: 3840.00 + * unit: + * type: string + * description: 单位 + * example: 元/吨 + * date: + * type: string + * format: date + * description: 日期 + * example: 2026-01-05 + * source: + * type: string + * description: 数据来源 + * example: 云南钢协 + * warehouse: + * type: string + * description: 仓库/厂家 + * example: 玉昆 + * examples: + * single_record: + * summary: 单条记录 + * value: + * prices: + * - region: 昆明 + * city: 昆明 + * material: HPB300 + * specification: Φ8 + * price: 3840 + * unit: 元/吨 + * date: 2026-01-05 + * source: 云南钢协 + * warehouse: 玉昆 + * multiple_records: + * summary: 多条记录 + * value: + * prices: + * - region: 昆明 + * material: HPB300 + * price: 3840 + * date: 2026-01-05 + * source: 云南钢协 + * - region: 玉溪 + * material: HRB400 + * price: 3750 + * date: 2026-01-05 + * source: 德钢指导价 + * responses: + * 200: + * description: 导入成功 + * content: + * application/json: + * schema: + * allOf: + * - $ref: '#/components/schemas/SuccessResponse' + * - type: object + * properties: + * message: + * type: string + * example: 成功导入 100 条数据 + * data: + * type: object + * properties: + * imported: + * type: integer + * description: 实际导入的记录数 + * example: 100 + * 400: + * description: 参数错误或数据格式错误 + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + * 500: + * description: 服务器错误 + * content: + * application/json: + * schema: + * $ref: '#/components/schemas/ErrorResponse' + */ +router.post('/prices/import', PriceController.importData); + +module.exports = router; diff --git a/src/routes/index.js b/src/routes/index.js new file mode 100644 index 0000000..fd339bd --- /dev/null +++ b/src/routes/index.js @@ -0,0 +1,44 @@ +const express = require('express'); +const apiRoutes = require('./api'); + +const router = express.Router(); + +// API 版本前缀 +router.use('/api', apiRoutes); + +// 根路径 - API 信息 +router.get('/', (req, res) => { + res.json({ + success: true, + message: 'Steel Prices Service API', + version: '1.0.0', + description: '钢材价格查询与分析服务平台', + endpoints: { + health: 'GET /api/health', + prices: { + byRegion: 'GET /api/prices/region?region={region}&date={date}', + search: 'GET /api/prices/search?material={material}&startDate={date}&endDate={date}', + stats: 'GET /api/prices/stats?region={region}&material={material}&days={days}', + trend: 'GET /api/prices/trend?region={region}&material={material}&days={days}', + import: 'POST /api/prices/import' + }, + documentation: { + swagger_ui: 'GET /api-docs', + json_spec: 'GET /api-docs.json' + } + }, + links: { + api_docs: `${req.protocol}://${req.get('host')}/api-docs`, + github: 'https://github.com/your-username/steel_prices_service' + } + }); +}); + +// Swagger JSON 规范 +router.get('/api-docs.json', (req, res) => { + res.setHeader('Content-Type', 'application/json'); + const swaggerSpec = require('../config/swagger'); + res.json(swaggerSpec); +}); + +module.exports = router; diff --git a/src/server.js b/src/server.js new file mode 100644 index 0000000..a26f3f7 --- /dev/null +++ b/src/server.js @@ -0,0 +1,56 @@ +require('dotenv').config(); +const createApp = require('./app'); + +/** + * 启动服务器 + */ +function startServer() { + const app = createApp(); + const PORT = process.env.PORT || 3000; + + const server = app.listen(PORT, () => { + console.log('='.repeat(60)); + console.log('🚀 Steel Prices Service 已启动'); + console.log('='.repeat(60)); + console.log(`📍 服务地址: http://localhost:${PORT}`); + console.log(`📍 Swagger文档地址: http://localhost:${PORT}/api-docs`); + console.log(`🌍 环境: ${process.env.NODE_ENV || 'development'}`); + console.log(`📊 API 文档: http://localhost:${PORT}/`); + console.log('='.repeat(60)); + }); + + // 优雅关闭 + const gracefulShutdown = (signal) => { + console.log(`\n${signal} 信号收到,正在关闭服务器...`); + server.close(() => { + console.log('✅ 服务器已关闭'); + process.exit(0); + }); + + // 10秒后强制关闭 + setTimeout(() => { + console.error('❌ 强制关闭服务器'); + process.exit(1); + }, 10000); + }; + + process.on('SIGTERM', () => gracefulShutdown('SIGTERM')); + process.on('SIGINT', () => gracefulShutdown('SIGINT')); + + // 未捕获的异常 + process.on('unhandledRejection', (reason, promise) => { + console.error('❌ 未处理的 Promise 拒绝:', reason); + }); + + process.on('uncaughtException', (error) => { + console.error('❌ 未捕获的异常:', error); + process.exit(1); + }); +} + +// 如果直接运行此文件 +if (require.main === module) { + startServer(); +} + +module.exports = startServer; diff --git a/src/services/priceService.js b/src/services/priceService.js new file mode 100644 index 0000000..7bad5b9 --- /dev/null +++ b/src/services/priceService.js @@ -0,0 +1,200 @@ +const Price = require('../models/Price'); +const { validateAndCleanPricesData } = require('../utils/validator'); + +/** + * 价格服务 + * 处理价格相关的业务逻辑 + */ +class PriceService { + /** + * 按地区查询价格 + */ + static async getByRegion(region, date, page = 1, pageSize = 20) { + try { + const prices = await Price.getByRegion(region, date); + + // 手动分页 + const total = prices.length; + const startIndex = (page - 1) * pageSize; + const endIndex = startIndex + parseInt(pageSize, 10); + const paginatedData = prices.slice(startIndex, endIndex); + + return { + success: true, + data: paginatedData, + pagination: { + page: parseInt(page, 10), + pageSize: parseInt(pageSize, 10), + total, + totalPages: Math.ceil(total / pageSize) + } + }; + } catch (error) { + throw error; + } + } + + /** + * 搜索价格数据 + */ + static async search(filters) { + try { + // 解析分页参数 + const page = parseInt(filters.page) || 1; + const pageSize = parseInt(filters.pageSize) || 20; + + const searchFilters = { + material: filters.material, + specification: filters.specification, + startDate: filters.startDate, + endDate: filters.endDate, + region: filters.region, + page, + pageSize + }; + + // 获取数据 + const data = await Price.search(searchFilters); + + // 获取总数 + const total = await Price.count({ + material: filters.material, + specification: filters.specification, + startDate: filters.startDate, + endDate: filters.endDate, + region: filters.region + }); + + return { + success: true, + data, + pagination: { + page, + pageSize, + total, + totalPages: Math.ceil(total / pageSize) + } + }; + } catch (error) { + throw error; + } + } + + /** + * 获取价格统计 + */ + static async getStats(filters) { + try { + const stats = await Price.getStats(filters); + + // 计算趋势(如果提供了天数) + let trend = null; + let changeRate = null; + + if (filters.days && stats.avgPrice) { + const previousStats = await Price.getStats({ + region: filters.region, + material: filters.material, + days: parseInt(filters.days) * 2 // 获取双倍天数的范围 + }); + + if (previousStats.avgPrice) { + const currentAvg = parseFloat(stats.avgPrice); + const previousAvg = parseFloat(previousStats.avgPrice); + const change = currentAvg - previousAvg; + changeRate = (change / previousAvg * 100).toFixed(2); + trend = change > 0 ? 'up' : change < 0 ? 'down' : 'stable'; + } + } + + return { + success: true, + data: { + count: stats.count, + avgPrice: stats.avgPrice ? parseFloat(parseFloat(stats.avgPrice).toFixed(2)) : null, + minPrice: stats.minPrice, + maxPrice: stats.maxPrice, + stdDev: stats.stdDev ? parseFloat(parseFloat(stats.stdDev).toFixed(2)) : null, + trend, + changeRate: changeRate ? `${changeRate > 0 ? '+' : ''}${changeRate}%` : null + } + }; + } catch (error) { + throw error; + } + } + + /** + * 获取价格趋势 + */ + static async getTrend(filters) { + try { + const trend = await Price.getTrend(filters); + + return { + success: true, + data: trend.map(item => ({ + date: item.date, + avgPrice: item.avgPrice ? parseFloat(parseFloat(item.avgPrice).toFixed(2)) : null, + minPrice: item.minPrice, + maxPrice: item.maxPrice + })), + meta: { + total: trend.length, + filters: { + region: filters.region || null, + material: filters.material || null, + days: filters.days || null + } + } + }; + } catch (error) { + throw error; + } + } + + /** + * 导入数据 + */ + static async importData(prices) { + try { + if (!Array.isArray(prices) || prices.length === 0) { + throw new Error('无效的数据格式'); + } + + // 验证并清洗数据 + const validation = validateAndCleanPricesData(prices); + + if (validation.validCount === 0) { + return { + success: false, + message: '没有有效的数据可以导入', + data: { + total: validation.total, + imported: 0, + errors: validation.errors + } + }; + } + + // 批量插入有效数据 + const result = await Price.batchInsert(validation.validData); + + return { + success: true, + message: `成功导入 ${result} 条数据${validation.errorCount > 0 ? `,${validation.errorCount} 条数据因格式错误被跳过` : ''}`, + data: { + imported: result, + total: validation.total, + validCount: validation.validCount, + errorCount: validation.errorCount, + errors: validation.errorCount > 0 ? validation.errors.slice(0, 10) : undefined // 只返回前 10 个错误 + } + }; + } catch (error) { + throw error; + } + } +} + +module.exports = PriceService; diff --git a/src/utils/validator.js b/src/utils/validator.js new file mode 100644 index 0000000..fc0472b --- /dev/null +++ b/src/utils/validator.js @@ -0,0 +1,119 @@ +/** + * 价格数据验证器 + */ + +/** + * 验证单条价格数据 + */ +function validatePriceData(item) { + const requiredFields = [ + 'goods_material', + 'goods_spec', + 'partsname_name', + 'productarea_name', + 'price_source', + 'price_region', + 'pntree_name', + 'price_date', + 'hang_price' + ]; + + const missingFields = []; + const invalidFields = []; + + // 检查必需字段 + for (const field of requiredFields) { + if (item[field] === undefined || item[field] === null || item[field] === '') { + missingFields.push(field); + } + } + + // 检查字段类型 + if (item.hang_price !== undefined && (typeof item.hang_price !== 'number' || isNaN(item.hang_price))) { + invalidFields.push({ field: 'hang_price', expected: 'number', received: typeof item.hang_price }); + } + + if (item.make_price !== undefined && item.make_price !== null && typeof item.make_price !== 'number') { + invalidFields.push({ field: 'make_price', expected: 'number or null', received: typeof item.make_price }); + } + + if (item.last_make_price !== undefined && item.last_make_price !== null && typeof item.last_make_price !== 'number') { + invalidFields.push({ field: 'last_make_price', expected: 'number or null', received: typeof item.last_make_price }); + } + + if (item.last_hang_price !== undefined && item.last_hang_price !== null && typeof item.last_hang_price !== 'number') { + invalidFields.push({ field: 'last_hang_price', expected: 'number or null', received: typeof item.last_hang_price }); + } + + // 检查价格日期格式 + if (item.price_date && !(item.price_date instanceof Date) && isNaN(Date.parse(item.price_date))) { + invalidFields.push({ field: 'price_date', expected: 'valid Date', received: item.price_date }); + } + + return { + valid: missingFields.length === 0 && invalidFields.length === 0, + missingFields, + invalidFields + }; +} + +/** + * 验证并清洗批量价格数据 + */ +function validateAndCleanPricesData(pricesArray) { + if (!Array.isArray(pricesArray)) { + throw new Error('数据必须是数组格式'); + } + + const validData = []; + const errors = []; + + pricesArray.forEach((item, index) => { + const validation = validatePriceData(item); + + if (!validation.valid) { + errors.push({ + index, + data: item, + reasons: { + missing: validation.missingFields, + invalid: validation.invalidFields + } + }); + } else { + // 清洗数据:确保所有字段都存在 + validData.push({ + price_id: item.price_id || null, + goods_material: item.goods_material, + goods_spec: item.goods_spec, + partsname_name: item.partsname_name, + productarea_name: item.productarea_name, + price_source: item.price_source, + price_region: item.price_region, + pntree_name: item.pntree_name || '钢筋', + price_date: item.price_date, + make_price: item.make_price || null, + hang_price: item.hang_price, + last_make_price: item.last_make_price || null, + last_hang_price: item.last_hang_price || null, + make_price_updw: item.make_price_updw || null, + hang_price_updw: item.hang_price_updw || null, + operator_code: item.operator_code || null, + operator_name: item.operator_name || null + }); + } + }); + + return { + validData, + errors, + total: pricesArray.length, + validCount: validData.length, + errorCount: errors.length + }; +} + +module.exports = { + validatePriceData, + validateAndCleanPricesData +};