Files
steel_prices_service/README.md
2026-01-06 18:00:43 +08:00

473 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

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

# 🏗️ Steel Prices Service
node scripts/import-data.js api --startDate 2025-01-01 --endDate 2026-01-01
> 一个专业的钢材价格查询与分析服务平台
[![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
---
<div align="center">
**如果这个项目对您有帮助,请给一个 ⭐️ Star 支持一下!**
[⬆ 返回顶部](#-steel-prices-service)
</div>