init:代码初始化
This commit is contained in:
228
docs/API_DOCUMENTATION.md
Normal file
228
docs/API_DOCUMENTATION.md
Normal 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
229
docs/API_RESPONSE_FORMAT.md
Normal 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®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` 时区
|
||||
299
docs/IMPORT_API.md
Normal file
299
docs/IMPORT_API.md
Normal 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
219
docs/PROJECT_STATUS.md
Normal 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
141
docs/QUICK_START.md
Normal 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)
|
||||
328
docs/SWAGGER_IMPLEMENTATION_REPORT.md
Normal file
328
docs/SWAGGER_IMPLEMENTATION_REPORT.md
Normal 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
319
docs/SWAGGER_SUMMARY.md
Normal 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!
|
||||
Reference in New Issue
Block a user