init:代码初始化

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

228
docs/API_DOCUMENTATION.md Normal file
View File

@@ -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)

229
docs/API_RESPONSE_FORMAT.md Normal file
View File

@@ -0,0 +1,229 @@
# API 响应格式规范
## 统一响应结构
所有 API 响应都遵循以下基本结构:
```typescript
interface ApiResponse<T = any> {
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&region=昆明&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` 时区

299
docs/IMPORT_API.md Normal file
View File

@@ -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` | - | - | - | 自动生成 |

219
docs/PROJECT_STATUS.md Normal file
View File

@@ -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)

141
docs/QUICK_START.md Normal file
View File

@@ -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)

View File

@@ -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
**状态**: ✅ 完成

319
docs/SWAGGER_SUMMARY.md Normal file
View File

@@ -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