153 lines
5.4 KiB
JavaScript
153 lines
5.4 KiB
JavaScript
|
|
const swaggerJsdoc = require('swagger-jsdoc');
|
||
|
|
const swaggerUi = require('swagger-ui-express');
|
||
|
|
|
||
|
|
const options = {
|
||
|
|
definition: {
|
||
|
|
openapi: '3.0.0',
|
||
|
|
info: {
|
||
|
|
title: '爱鉴花小程序后端API',
|
||
|
|
version: '1.0.0',
|
||
|
|
description: '爱鉴花小程序后端RESTful API文档',
|
||
|
|
contact: {
|
||
|
|
name: 'API支持',
|
||
|
|
email: 'support@aijianhua.com'
|
||
|
|
},
|
||
|
|
license: {
|
||
|
|
name: 'MIT',
|
||
|
|
url: 'https://opensource.org/licenses/MIT'
|
||
|
|
}
|
||
|
|
},
|
||
|
|
servers: [
|
||
|
|
{
|
||
|
|
url: process.env.NODE_ENV === 'production'
|
||
|
|
? 'https://api.aijianhua.com'
|
||
|
|
: `http://localhost:${process.env.PORT || 3000}`,
|
||
|
|
description: process.env.NODE_ENV === 'production' ? '生产环境' : '开发环境'
|
||
|
|
}
|
||
|
|
],
|
||
|
|
components: {
|
||
|
|
securitySchemes: {
|
||
|
|
BearerAuth: {
|
||
|
|
type: 'http',
|
||
|
|
scheme: 'bearer',
|
||
|
|
bearerFormat: 'JWT'
|
||
|
|
}
|
||
|
|
},
|
||
|
|
schemas: {
|
||
|
|
User: {
|
||
|
|
type: 'object',
|
||
|
|
properties: {
|
||
|
|
id: { type: 'integer', example: 1 },
|
||
|
|
username: { type: 'string', example: 'testuser' },
|
||
|
|
phone: { type: 'string', example: '13800138000' },
|
||
|
|
email: { type: 'string', example: 'user@example.com' },
|
||
|
|
user_type: { type: 'string', enum: ['farmer', 'buyer', 'admin'], example: 'farmer' },
|
||
|
|
avatar_url: { type: 'string', example: '/uploads/avatars/avatar.jpg' },
|
||
|
|
created_at: { type: 'string', format: 'date-time', example: '2023-01-01T00:00:00Z' },
|
||
|
|
last_login: { type: 'string', format: 'date-time', example: '2023-01-01T00:00:00Z' }
|
||
|
|
}
|
||
|
|
},
|
||
|
|
Product: {
|
||
|
|
type: 'object',
|
||
|
|
properties: {
|
||
|
|
id: { type: 'integer', example: 1 },
|
||
|
|
name: { type: 'string', example: '玫瑰花' },
|
||
|
|
category_id: { type: 'integer', example: 1 },
|
||
|
|
price: { type: 'number', format: 'float', example: 29.9 },
|
||
|
|
stock: { type: 'integer', example: 100 },
|
||
|
|
image: { type: 'string', example: '/uploads/products/rose.jpg' },
|
||
|
|
description: { type: 'string', example: '新鲜玫瑰花,香气浓郁' },
|
||
|
|
status: { type: 'integer', enum: [0, 1], example: 1 },
|
||
|
|
created_at: { type: 'string', format: 'date-time', example: '2023-01-01T00:00:00Z' },
|
||
|
|
updated_at: { type: 'string', format: 'date-time', example: '2023-01-01T00:00:00Z' }
|
||
|
|
}
|
||
|
|
},
|
||
|
|
Order: {
|
||
|
|
type: 'object',
|
||
|
|
properties: {
|
||
|
|
id: { type: 'integer', example: 1 },
|
||
|
|
order_number: { type: 'string', example: 'O123456789' },
|
||
|
|
user_id: { type: 'integer', example: 1 },
|
||
|
|
total_amount: { type: 'number', format: 'float', example: 99.9 },
|
||
|
|
payment_status: { type: 'string', enum: ['pending', 'paid', 'cancelled'], example: 'pending' },
|
||
|
|
shipping_status: { type: 'string', enum: ['pending', 'shipped', 'delivered'], example: 'pending' },
|
||
|
|
shipping_address: { type: 'string', example: '北京市朝阳区xxx街道' },
|
||
|
|
created_at: { type: 'string', format: 'date-time', example: '2023-01-01T00:00:00Z' },
|
||
|
|
updated_at: { type: 'string', format: 'date-time', example: '2023-01-01T00:00:00Z' }
|
||
|
|
}
|
||
|
|
},
|
||
|
|
Identification: {
|
||
|
|
type: 'object',
|
||
|
|
properties: {
|
||
|
|
id: { type: 'integer', example: 1 },
|
||
|
|
user_id: { type: 'integer', example: 1 },
|
||
|
|
image_url: { type: 'string', example: '/uploads/identifications/identify-123.jpg' },
|
||
|
|
result: { type: 'string', description: 'JSON格式的识别结果' },
|
||
|
|
confidence: { type: 'number', format: 'float', example: 0.95 },
|
||
|
|
created_at: { type: 'string', format: 'date-time', example: '2023-01-01T00:00:00Z' }
|
||
|
|
}
|
||
|
|
},
|
||
|
|
Error: {
|
||
|
|
type: 'object',
|
||
|
|
properties: {
|
||
|
|
code: { type: 'integer', example: 400 },
|
||
|
|
message: { type: 'string', example: '参数验证失败' },
|
||
|
|
data: { type: 'object', nullable: true, example: null }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
responses: {
|
||
|
|
UnauthorizedError: {
|
||
|
|
description: '未授权访问',
|
||
|
|
content: {
|
||
|
|
'application/json': {
|
||
|
|
schema: { $ref: '#/components/schemas/Error' },
|
||
|
|
example: {
|
||
|
|
code: 401,
|
||
|
|
message: '未提供有效的认证token',
|
||
|
|
data: null
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
NotFoundError: {
|
||
|
|
description: '资源不存在',
|
||
|
|
content: {
|
||
|
|
'application/json': {
|
||
|
|
schema: { $ref: '#/components/schemas/Error' },
|
||
|
|
example: {
|
||
|
|
code: 404,
|
||
|
|
message: '资源不存在',
|
||
|
|
data: null
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
ValidationError: {
|
||
|
|
description: '参数验证失败',
|
||
|
|
content: {
|
||
|
|
'application/json': {
|
||
|
|
schema: { $ref: '#/components/schemas/Error' },
|
||
|
|
example: {
|
||
|
|
code: 400,
|
||
|
|
message: '参数验证失败',
|
||
|
|
data: null
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
security: [
|
||
|
|
{ BearerAuth: [] }
|
||
|
|
]
|
||
|
|
},
|
||
|
|
apis: [
|
||
|
|
'./routes/*.js',
|
||
|
|
'./middlewares/*.js'
|
||
|
|
]
|
||
|
|
};
|
||
|
|
|
||
|
|
const specs = swaggerJsdoc(options);
|
||
|
|
|
||
|
|
module.exports = { specs, swaggerUi };
|