Compare commits
3 Commits
af3d174ac6
...
87cc7b4d03
Author | SHA1 | Date | |
---|---|---|---|
87cc7b4d03 | |||
54f3fc6f61 | |||
9d7dcae1c8 |
@ -26,7 +26,20 @@ export default defineConfig({
|
||||
'/api': {
|
||||
target: 'http://127.0.0.1:5000',
|
||||
changeOrigin: true,
|
||||
}
|
||||
},
|
||||
// 新增Swagger UI的代理规则
|
||||
'/swagger': {
|
||||
target: 'http://127.0.0.1:5000',
|
||||
changeOrigin: true,
|
||||
},
|
||||
'/apispec.json': {
|
||||
target: 'http://127.0.0.1:5000',
|
||||
changeOrigin: true,
|
||||
},
|
||||
'/flasgger_static': {
|
||||
target: 'http://127.0.0.1:5000',
|
||||
changeOrigin: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
Binary file not shown.
992
server/swagger.json
Normal file
992
server/swagger.json
Normal file
@ -0,0 +1,992 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "药店销售预测系统API",
|
||||
"description": "用于药店销售预测的RESTful API",
|
||||
"version": "1.0.0",
|
||||
"contact": {
|
||||
"name": "API开发团队",
|
||||
"email": "support@example.com"
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "数据管理",
|
||||
"description": "数据上传和查询相关接口"
|
||||
},
|
||||
{
|
||||
"name": "模型训练",
|
||||
"description": "模型训练相关接口"
|
||||
},
|
||||
{
|
||||
"name": "模型预测",
|
||||
"description": "预测销售数据相关接口"
|
||||
},
|
||||
{
|
||||
"name": "模型管理",
|
||||
"description": "模型查询、导出和删除接口"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"/api/products": {
|
||||
"get": {
|
||||
"tags": ["数据管理"],
|
||||
"summary": "获取所有产品列表",
|
||||
"description": "返回系统中所有产品的ID和名称",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "成功获取产品列表",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"product_id": {"type": "string", "example": "P001"},
|
||||
"product_name": {"type": "string", "example": "产品A"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {"description": "服务器内部错误"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/products/{product_id}": {
|
||||
"get": {
|
||||
"tags": ["数据管理"],
|
||||
"summary": "获取单个产品详情",
|
||||
"description": "返回指定产品ID的详细信息",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "product_id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {"type": "string"},
|
||||
"description": "产品ID,例如P001"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "成功获取产品详情",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"product_id": {"type": "string", "example": "P001"},
|
||||
"product_name": {"type": "string", "example": "产品A"},
|
||||
"data_points": {"type": "integer", "example": 365},
|
||||
"date_range": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"start": {"type": "string", "example": "2023-01-01"},
|
||||
"end": {"type": "string", "example": "2023-12-31"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {"description": "产品不存在"},
|
||||
"500": {"description": "服务器内部错误"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/products/{product_id}/sales": {
|
||||
"get": {
|
||||
"tags": ["数据管理"],
|
||||
"summary": "获取产品销售数据",
|
||||
"description": "返回指定产品在特定日期范围内的销售数据",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "product_id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {"type": "string"},
|
||||
"description": "产品ID,例如P001"
|
||||
},
|
||||
{
|
||||
"name": "start_date",
|
||||
"in": "query",
|
||||
"schema": {"type": "string"},
|
||||
"description": "开始日期,格式为YYYY-MM-DD"
|
||||
},
|
||||
{
|
||||
"name": "end_date",
|
||||
"in": "query",
|
||||
"schema": {"type": "string"},
|
||||
"description": "结束日期,格式为YYYY-MM-DD"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "成功获取销售数据",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"date": {"type": "string", "example": "2023-12-01"},
|
||||
"sales": {"type": "integer", "example": 150}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {"description": "产品不存在"},
|
||||
"500": {"description": "服务器内部错误"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/data/upload": {
|
||||
"post": {
|
||||
"tags": ["数据管理"],
|
||||
"summary": "上传销售数据",
|
||||
"description": "上传新的销售数据文件(Excel格式)",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"multipart/form-data": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"file": {
|
||||
"type": "string",
|
||||
"format": "binary"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "数据上传成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"message": {"type": "string", "example": "数据上传成功"},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"products": {"type": "integer", "example": 10},
|
||||
"rows": {"type": "integer", "example": 3650}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {"description": "请求错误"},
|
||||
"500": {"description": "服务器内部错误"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/training": {
|
||||
"get": {
|
||||
"tags": ["模型训练"],
|
||||
"summary": "获取所有训练任务列表",
|
||||
"description": "返回所有正在进行、已完成或失败的训练任务",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "成功获取任务列表",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"task_id": {"type": "string", "example": "uuid-1234"},
|
||||
"product_id": {"type": "string", "example": "P001"},
|
||||
"model_type": {"type": "string", "example": "mlstm"},
|
||||
"status": {"type": "string", "example": "completed"},
|
||||
"start_time": {"type": "string", "example": "2023-12-25T10:00:00Z"},
|
||||
"metrics": {"type": "object", "example": {"R2": 0.95, "RMSE": 5.5}},
|
||||
"error": {"type": "string", "nullable": true},
|
||||
"model_path": {"type": "string", "example": "/path/to/model.pth"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"tags": ["模型训练"],
|
||||
"summary": "启动模型训练任务",
|
||||
"description": "为指定产品启动一个新的模型训练任务",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"product_id": {"type": "string", "example": "P001"},
|
||||
"model_type": {"type": "string", "enum": ["mlstm", "transformer", "kan", "optimized_kan", "tcn", "xgboost"]},
|
||||
"store_id": {"type": "string", "example": "S001"},
|
||||
"epochs": {"type": "integer", "default": 50}
|
||||
},
|
||||
"required": ["product_id", "model_type"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "训练任务已启动",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {"type": "string", "example": "模型训练已开始"},
|
||||
"task_id": {"type": "string", "example": "new-uuid-5678"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {"description": "请求错误"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/training/{task_id}": {
|
||||
"get": {
|
||||
"tags": ["模型训练"],
|
||||
"summary": "查询训练任务状态",
|
||||
"description": "获取特定训练任务的当前状态和详情",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "task_id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {"type": "string"},
|
||||
"description": "训练任务ID"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "成功获取任务状态",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"product_id": {"type": "string", "example": "P001"},
|
||||
"model_type": {"type": "string", "example": "mlstm"},
|
||||
"status": {"type": "string", "example": "running"},
|
||||
"progress": {"type": "number", "example": 50.5},
|
||||
"created_at": {"type": "string", "example": "2023-12-25T10:00:00Z"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {"description": "任务不存在"},
|
||||
"500": {"description": "服务器内部错误"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/prediction": {
|
||||
"post": {
|
||||
"tags": ["模型预测"],
|
||||
"summary": "使用模型进行预测",
|
||||
"description": "使用指定模型预测未来销售数据",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"product_id": {"type": "string"},
|
||||
"model_type": {"type": "string", "enum": ["mlstm", "transformer", "kan", "optimized_kan", "tcn"]},
|
||||
"store_id": {"type": "string"},
|
||||
"version": {"type": "string"},
|
||||
"future_days": {"type": "integer"},
|
||||
"include_visualization": {"type": "boolean"},
|
||||
"start_date": {"type": "string"}
|
||||
},
|
||||
"required": ["product_id", "model_type"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "预测成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"product_id": {"type": "string", "example": "P001"},
|
||||
"product_name": {"type": "string", "example": "产品A"},
|
||||
"model_type": {"type": "string", "example": "mlstm"},
|
||||
"predictions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"date": {"type": "string", "example": "2024-01-01"},
|
||||
"predicted_sales": {"type": "integer", "example": 100}
|
||||
}
|
||||
}
|
||||
},
|
||||
"visualization": {"type": "string", "example": "base64-encoded-image-string"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {"description": "请求错误"},
|
||||
"404": {"description": "产品或模型不存在"},
|
||||
"500": {"description": "服务器内部错误"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/prediction/compare": {
|
||||
"post": {
|
||||
"tags": ["模型预测"],
|
||||
"summary": "比较不同模型预测结果",
|
||||
"description": "比较不同模型对同一产品的预测结果",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"product_id": {"type": "string"},
|
||||
"model_types": {"type": "array", "items": {"type": "string"}},
|
||||
"versions": {"type": "array", "items": {"type": "string"}},
|
||||
"include_visualization": {"type": "boolean"}
|
||||
},
|
||||
"required": ["product_id", "model_types"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "比较成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"product_id": {"type": "string", "example": "P001"},
|
||||
"comparison": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"date": {"type": "string", "example": "2024-01-01"},
|
||||
"mlstm": {"type": "integer", "example": 100},
|
||||
"transformer": {"type": "integer", "example": 102}
|
||||
}
|
||||
}
|
||||
},
|
||||
"visualization": {"type": "string", "example": "base64-encoded-image-string"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {"description": "请求错误"},
|
||||
"404": {"description": "产品或模型不存在"},
|
||||
"500": {"description": "服务器内部错误"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/prediction/history": {
|
||||
"get": {
|
||||
"tags": ["模型预测"],
|
||||
"summary": "获取历史预测记录",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "获取成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"prediction_id": {"type": "string", "example": "pred-uuid-1"},
|
||||
"product_id": {"type": "string", "example": "P001"},
|
||||
"model_type": {"type": "string", "example": "mlstm"},
|
||||
"created_at": {"type": "string", "example": "2023-12-20T11:00:00Z"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/prediction/history/{prediction_id}": {
|
||||
"get": {
|
||||
"tags": ["模型预测"],
|
||||
"summary": "获取特定预测记录的详情",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "prediction_id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {"type": "string"}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "获取成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"prediction_id": {"type": "string", "example": "pred-uuid-1"},
|
||||
"product_id": {"type": "string", "example": "P001"},
|
||||
"model_type": {"type": "string", "example": "mlstm"},
|
||||
"predictions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"date": {"type": "string", "example": "2023-12-21"},
|
||||
"predicted_sales": {"type": "integer", "example": 110}
|
||||
}
|
||||
}
|
||||
},
|
||||
"analysis": {"type": "object", "example": {"trend": "upward"}}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {"description": "记录不存在"}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"tags": ["模型预测"],
|
||||
"summary": "删除预测记录",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "prediction_id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {"type": "string"}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "删除成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"message": {"type": "string", "example": "预测记录已删除"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {"description": "记录不存在"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/models": {
|
||||
"get": {
|
||||
"tags": ["模型管理"],
|
||||
"summary": "获取模型列表",
|
||||
"parameters": [
|
||||
{"name": "product_id", "in": "query", "schema": {"type": "string"}},
|
||||
{"name": "model_type", "in": "query", "schema": {"type": "string"}}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "获取成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"model_id": {"type": "string", "example": "P001_mlstm_v1"},
|
||||
"product_id": {"type": "string", "example": "P001"},
|
||||
"model_type": {"type": "string", "example": "mlstm"},
|
||||
"version": {"type": "string", "example": "v1"},
|
||||
"created_at": {"type": "string", "example": "2023-12-15T09:00:00Z"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/models/{model_id}": {
|
||||
"get": {
|
||||
"tags": ["模型管理"],
|
||||
"summary": "获取模型详情",
|
||||
"parameters": [
|
||||
{"name": "model_id", "in": "path", "required": true, "schema": {"type": "string"}}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "获取成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"model_id": {"type": "string", "example": "P001_mlstm_v1"},
|
||||
"product_id": {"type": "string", "example": "P001"},
|
||||
"model_type": {"type": "string", "example": "mlstm"},
|
||||
"version": {"type": "string", "example": "v1"},
|
||||
"metrics": {"type": "object", "example": {"R2": 0.95, "RMSE": 5.5}}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {"description": "模型不存在"}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"tags": ["模型管理"],
|
||||
"summary": "删除模型",
|
||||
"parameters": [
|
||||
{"name": "model_id", "in": "path", "required": true, "schema": {"type": "string"}}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "删除成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"message": {"type": "string", "example": "模型已删除"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {"description": "模型不存在"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/models/{model_id}/export": {
|
||||
"get": {
|
||||
"tags": ["模型管理"],
|
||||
"summary": "导出模型",
|
||||
"parameters": [
|
||||
{"name": "model_id", "in": "path", "required": true, "schema": {"type": "string"}}
|
||||
],
|
||||
"responses": {
|
||||
"200": {"description": "模型文件下载"},
|
||||
"404": {"description": "模型不存在"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/model_types": {
|
||||
"get": {
|
||||
"tags": ["模型管理"],
|
||||
"summary": "获取系统支持的所有模型类型",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "获取成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"type": "string", "example": "mlstm"},
|
||||
"name": {"type": "string", "example": "mLSTM"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/models/{product_id}/{model_type}/versions": {
|
||||
"get": {
|
||||
"tags": ["模型管理"],
|
||||
"summary": "获取模型版本列表",
|
||||
"parameters": [
|
||||
{"name": "product_id", "in": "path", "required": true, "schema": {"type": "string"}},
|
||||
{"name": "model_type", "in": "path", "required": true, "schema": {"type": "string"}}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "获取成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"product_id": {"type": "string", "example": "P001"},
|
||||
"model_type": {"type": "string", "example": "mlstm"},
|
||||
"versions": {"type": "array", "items": {"type": "string"}, "example": ["v1", "v2"]},
|
||||
"latest_version": {"type": "string", "example": "v2"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/stores": {
|
||||
"get": {
|
||||
"tags": ["数据管理"],
|
||||
"summary": "获取所有店铺列表",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "获取成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"store_id": {"type": "string", "example": "S001"},
|
||||
"store_name": {"type": "string", "example": "第一分店"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"count": {"type": "integer", "example": 2}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"tags": ["数据管理"],
|
||||
"summary": "创建新店铺",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "创建成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"message": {"type": "string", "example": "店铺创建成功"},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"store_id": {"type": "string", "example": "S003"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/stores/{store_id}": {
|
||||
"get": {
|
||||
"tags": ["数据管理"],
|
||||
"summary": "获取单个店铺信息",
|
||||
"parameters": [
|
||||
{"name": "store_id", "in": "path", "required": true, "schema": {"type": "string"}}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "获取成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"store_id": {"type": "string", "example": "S001"},
|
||||
"store_name": {"type": "string", "example": "第一分店"},
|
||||
"location": {"type": "string", "example": "市中心"},
|
||||
"size": {"type": "number", "example": 120.5},
|
||||
"type": {"type": "string", "example": "旗舰店"},
|
||||
"opening_date": {"type": "string", "example": "2022-01-01"},
|
||||
"status": {"type": "string", "example": "active"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {"description": "店铺不存在"}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"tags": ["数据管理"],
|
||||
"summary": "更新店铺信息",
|
||||
"parameters": [
|
||||
{"name": "store_id", "in": "path", "required": true, "schema": {"type": "string"}}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "更新成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"message": {"type": "string", "example": "店铺更新成功"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {"description": "店铺不存在"}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"tags": ["数据管理"],
|
||||
"summary": "删除店铺",
|
||||
"parameters": [
|
||||
{"name": "store_id", "in": "path", "required": true, "schema": {"type": "string"}}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "删除成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"message": {"type": "string", "example": "店铺删除成功"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {"description": "店铺不存在"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/stores/{store_id}/products": {
|
||||
"get": {
|
||||
"tags": ["数据管理"],
|
||||
"summary": "获取店铺的产品列表",
|
||||
"parameters": [
|
||||
{"name": "store_id", "in": "path", "required": true, "schema": {"type": "string"}}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "获取成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"product_id": {"type": "string", "example": "P001"},
|
||||
"product_name": {"type": "string", "example": "产品A"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"count": {"type": "integer", "example": 1}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/stores/{store_id}/statistics": {
|
||||
"get": {
|
||||
"tags": ["数据管理"],
|
||||
"summary": "获取店铺销售统计信息",
|
||||
"parameters": [
|
||||
{"name": "store_id", "in": "path", "required": true, "schema": {"type": "string"}}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "获取成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"total_sales": {"type": "number", "example": 150000.0},
|
||||
"total_quantity": {"type": "integer", "example": 7500},
|
||||
"products_count": {"type": "integer", "example": 50}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/sales/data": {
|
||||
"get": {
|
||||
"tags": ["数据管理"],
|
||||
"summary": "获取销售数据列表",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "获取成功",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {"type": "string", "example": "success"},
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"date": {"type": "string", "example": "2023-12-01"},
|
||||
"store_id": {"type": "string", "example": "S001"},
|
||||
"product_id": {"type": "string", "example": "P001"},
|
||||
"sales": {"type": "integer", "example": 150},
|
||||
"price": {"type": "number", "example": 25.5}
|
||||
}
|
||||
}
|
||||
},
|
||||
"total": {"type": "integer", "example": 100},
|
||||
"page": {"type": "integer", "example": 1},
|
||||
"page_size": {"type": "integer", "example": 1}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -6,25 +6,29 @@ CNN-BiLSTM-Attention 模型训练器
|
||||
import torch
|
||||
import torch.optim as optim
|
||||
import numpy as np
|
||||
import time
|
||||
import copy
|
||||
|
||||
from models.model_registry import register_trainer
|
||||
from utils.model_manager import model_manager
|
||||
from analysis.metrics import evaluate_model
|
||||
from utils.data_utils import create_dataset
|
||||
from sklearn.preprocessing import MinMaxScaler
|
||||
from utils.visualization import plot_loss_curve # 导入绘图函数
|
||||
|
||||
# 导入新创建的模型
|
||||
from models.cnn_bilstm_attention import CnnBiLstmAttention
|
||||
|
||||
def train_with_cnn_bilstm_attention(product_id, model_identifier, product_df, store_id, training_mode, aggregation_method, epochs, sequence_length, forecast_horizon, model_dir, **kwargs):
|
||||
"""
|
||||
使用 CNN-BiLSTM-Attention 模型进行训练。
|
||||
函数签名遵循系统标准。
|
||||
使用 CNN-BiLSTM-Attention 模型进行训练,并实现早停和最佳模型保存。
|
||||
"""
|
||||
print(f"🚀 CNN-BiLSTM-Attention 训练器启动: model_identifier='{model_identifier}'")
|
||||
start_time = time.time()
|
||||
|
||||
# --- 1. 数据准备 ---
|
||||
features = ['sales', 'weekday', 'month', 'is_holiday', 'is_weekend', 'is_promotion', 'temperature']
|
||||
product_name = product_df['product_name'].iloc[0] if 'product_name' in product_df.columns else model_identifier
|
||||
|
||||
X = product_df[features].values
|
||||
y = product_df[['sales']].values
|
||||
@ -42,7 +46,6 @@ def train_with_cnn_bilstm_attention(product_id, model_identifier, product_df, st
|
||||
trainX, trainY = create_dataset(X_train_raw, y_train_raw, sequence_length, forecast_horizon)
|
||||
testX, testY = create_dataset(X_test_raw, y_test_raw, sequence_length, forecast_horizon)
|
||||
|
||||
# 转换为 PyTorch Tensors
|
||||
trainX = torch.from_numpy(trainX).float()
|
||||
trainY = torch.from_numpy(trainY).float()
|
||||
testX = torch.from_numpy(testX).float()
|
||||
@ -60,22 +63,56 @@ def train_with_cnn_bilstm_attention(product_id, model_identifier, product_df, st
|
||||
optimizer = optim.Adam(model.parameters(), lr=kwargs.get('learning_rate', 0.001))
|
||||
criterion = torch.nn.MSELoss()
|
||||
|
||||
# --- 3. 训练循环 ---
|
||||
print("开始训练 CNN-BiLSTM-Attention 模型...")
|
||||
# --- 3. 训练循环与早停 ---
|
||||
print("开始训练 CNN-BiLSTM-Attention 模型 (含早停)...")
|
||||
loss_history = {'train': [], 'val': []}
|
||||
best_val_loss = float('inf')
|
||||
best_model_state = None
|
||||
patience = kwargs.get('patience', 15)
|
||||
patience_counter = 0
|
||||
|
||||
for epoch in range(epochs):
|
||||
model.train()
|
||||
optimizer.zero_grad()
|
||||
|
||||
outputs = model(trainX)
|
||||
loss = criterion(outputs, trainY.squeeze(-1)) # 确保目标维度匹配
|
||||
train_loss = criterion(outputs, trainY.squeeze(-1))
|
||||
|
||||
loss.backward()
|
||||
train_loss.backward()
|
||||
optimizer.step()
|
||||
|
||||
# 验证
|
||||
model.eval()
|
||||
with torch.no_grad():
|
||||
val_outputs = model(testX)
|
||||
val_loss = criterion(val_outputs, testY.squeeze(-1))
|
||||
|
||||
loss_history['train'].append(train_loss.item())
|
||||
loss_history['val'].append(val_loss.item())
|
||||
|
||||
if (epoch + 1) % 10 == 0:
|
||||
print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')
|
||||
print(f'Epoch [{epoch+1}/{epochs}], Train Loss: {train_loss.item():.4f}, Val Loss: {val_loss.item():.4f}')
|
||||
|
||||
# 早停逻辑
|
||||
if val_loss.item() < best_val_loss:
|
||||
best_val_loss = val_loss.item()
|
||||
best_model_state = copy.deepcopy(model.state_dict())
|
||||
patience_counter = 0
|
||||
print(f"✨ 新的最佳模型! Epoch: {epoch+1}, Val Loss: {best_val_loss:.4f}")
|
||||
else:
|
||||
patience_counter += 1
|
||||
if patience_counter >= patience:
|
||||
print(f"🚫 早停触发! 在 epoch {epoch+1} 停止。")
|
||||
break
|
||||
|
||||
training_time = time.time() - start_time
|
||||
print(f"模型训练完成,耗时: {training_time:.2f}秒")
|
||||
|
||||
# --- 4. 使用最佳模型进行评估 ---
|
||||
if best_model_state:
|
||||
model.load_state_dict(best_model_state)
|
||||
print("最佳模型已加载用于最终评估。")
|
||||
|
||||
# --- 4. 模型评估 ---
|
||||
model.eval()
|
||||
with torch.no_grad():
|
||||
test_pred_scaled = model(testX)
|
||||
@ -84,11 +121,26 @@ def train_with_cnn_bilstm_attention(product_id, model_identifier, product_df, st
|
||||
test_true_unscaled = scaler_y.inverse_transform(testY.squeeze(-1).numpy())
|
||||
|
||||
metrics = evaluate_model(test_true_unscaled.flatten(), test_pred_unscaled.flatten())
|
||||
print(f"模型评估完成: RMSE={metrics['rmse']:.4f}")
|
||||
metrics['training_time'] = training_time
|
||||
metrics['best_val_loss'] = best_val_loss
|
||||
metrics['stopped_epoch'] = epoch + 1
|
||||
|
||||
print("\n最佳模型评估指标:")
|
||||
print(f"MSE: {metrics['mse']:.4f}, RMSE: {metrics['rmse']:.4f}, MAE: {metrics['mae']:.4f}, R²: {metrics['r2']:.4f}, MAPE: {metrics['mape']:.2f}%")
|
||||
|
||||
# 绘制损失曲线
|
||||
loss_curve_path = plot_loss_curve(
|
||||
loss_history['train'],
|
||||
loss_history['val'],
|
||||
product_name,
|
||||
'cnn_bilstm_attention',
|
||||
model_dir=model_dir
|
||||
)
|
||||
print(f"📈 损失曲线已保存到: {loss_curve_path}")
|
||||
|
||||
# --- 5. 模型保存 ---
|
||||
model_data = {
|
||||
'model_state_dict': model.state_dict(),
|
||||
'model_state_dict': best_model_state, # 保存最佳模型的状态
|
||||
'scaler_X': scaler_X,
|
||||
'scaler_y': scaler_y,
|
||||
'config': {
|
||||
@ -98,9 +150,12 @@ def train_with_cnn_bilstm_attention(product_id, model_identifier, product_df, st
|
||||
'sequence_length': sequence_length,
|
||||
'features': features
|
||||
},
|
||||
'metrics': metrics
|
||||
'metrics': metrics,
|
||||
'loss_history': loss_history, # 保存损失历史
|
||||
'loss_curve_path': loss_curve_path # 添加损失图路径
|
||||
}
|
||||
|
||||
# 保存最终版本模型
|
||||
final_model_path, final_version = model_manager.save_model(
|
||||
model_data=model_data,
|
||||
product_id=product_id,
|
||||
@ -108,10 +163,23 @@ def train_with_cnn_bilstm_attention(product_id, model_identifier, product_df, st
|
||||
store_id=store_id,
|
||||
training_mode=training_mode,
|
||||
aggregation_method=aggregation_method,
|
||||
product_name=product_df['product_name'].iloc[0]
|
||||
product_name=product_name
|
||||
)
|
||||
print(f"✅ CNN-BiLSTM-Attention 最终模型已保存,版本: {final_version}")
|
||||
|
||||
# 保存最佳版本模型
|
||||
best_model_path, best_version = model_manager.save_model(
|
||||
model_data=model_data,
|
||||
product_id=product_id,
|
||||
model_type='cnn_bilstm_attention',
|
||||
store_id=store_id,
|
||||
training_mode=training_mode,
|
||||
aggregation_method=aggregation_method,
|
||||
product_name=product_name,
|
||||
version='best' # 明确指定版本为 'best'
|
||||
)
|
||||
print(f"✅ CNN-BiLSTM-Attention 最佳模型已保存,版本: {best_version}")
|
||||
|
||||
print(f"✅ CNN-BiLSTM-Attention 模型已保存,版本: {final_version}")
|
||||
return model, metrics, final_version, final_model_path
|
||||
|
||||
# --- 关键步骤: 将训练器注册到系统中 ---
|
||||
|
@ -14,6 +14,7 @@ from utils.data_utils import create_dataset
|
||||
from analysis.metrics import evaluate_model
|
||||
from utils.model_manager import model_manager
|
||||
from models.model_registry import register_trainer
|
||||
from utils.visualization import plot_loss_curve # 导入绘图函数
|
||||
|
||||
def train_product_model_with_xgboost(product_id, model_identifier, product_df, store_id, training_mode, aggregation_method, epochs, sequence_length, forecast_horizon, model_dir, **kwargs):
|
||||
"""
|
||||
@ -91,7 +92,7 @@ def train_product_model_with_xgboost(product_id, model_identifier, product_df, s
|
||||
training_time = time.time() - start_time
|
||||
print(f"XGBoost模型训练完成,耗时: {training_time:.2f}秒")
|
||||
|
||||
# --- 4. 模型评估 ---
|
||||
# --- 4. 模型评估与可视化 ---
|
||||
# 使用 model.best_iteration 获取最佳轮次的预测结果
|
||||
test_pred = model.predict(dtest, iteration_range=(0, model.best_iteration))
|
||||
|
||||
@ -100,13 +101,24 @@ def train_product_model_with_xgboost(product_id, model_identifier, product_df, s
|
||||
|
||||
metrics = evaluate_model(test_true_inv.flatten(), test_pred_inv.flatten())
|
||||
metrics['training_time'] = training_time
|
||||
metrics['best_iteration'] = model.best_iteration
|
||||
|
||||
print("\n模型评估指标:")
|
||||
print(f"MSE: {metrics['mse']:.4f}, RMSE: {metrics['rmse']:.4f}, MAE: {metrics['mae']:.4f}, R²: {metrics['r2']:.4f}, MAPE: {metrics['mape']:.2f}%")
|
||||
|
||||
# 提取损失并绘制曲线
|
||||
train_losses = evals_result['train']['rmse']
|
||||
test_losses = evals_result['test']['rmse']
|
||||
loss_curve_path = plot_loss_curve(
|
||||
train_losses,
|
||||
test_losses,
|
||||
product_name,
|
||||
'xgboost',
|
||||
model_dir=model_dir
|
||||
)
|
||||
print(f"📈 损失曲线已保存到: {loss_curve_path}")
|
||||
|
||||
# --- 5. 模型保存 (借道 utils.model_manager) ---
|
||||
# **关键适配点**: 我们将完整的XGBoost模型对象存入字典
|
||||
# torch.save 可以序列化多种Python对象,包括sklearn模型
|
||||
model_data = {
|
||||
'model_state_dict': model, # 直接保存模型对象
|
||||
'scaler_X': scaler_X,
|
||||
@ -119,10 +131,11 @@ def train_product_model_with_xgboost(product_id, model_identifier, product_df, s
|
||||
'xgb_params': xgb_params
|
||||
},
|
||||
'metrics': metrics,
|
||||
'loss_history': evals_result
|
||||
'loss_history': evals_result,
|
||||
'loss_curve_path': loss_curve_path # 添加损失图路径
|
||||
}
|
||||
|
||||
# 调用全局管理器进行保存,复用其命名和版本逻辑
|
||||
# 保存最终版本模型
|
||||
final_model_path, final_version = model_manager.save_model(
|
||||
model_data=model_data,
|
||||
product_id=product_id,
|
||||
@ -132,8 +145,20 @@ def train_product_model_with_xgboost(product_id, model_identifier, product_df, s
|
||||
aggregation_method=aggregation_method,
|
||||
product_name=product_name
|
||||
)
|
||||
|
||||
print(f"XGBoost模型已通过统一管理器保存,版本: {final_version}, 路径: {final_model_path}")
|
||||
print(f"✅ XGBoost最终模型已通过统一管理器保存,版本: {final_version}, 路径: {final_model_path}")
|
||||
|
||||
# 保存最佳版本模型
|
||||
best_model_path, best_version = model_manager.save_model(
|
||||
model_data=model_data,
|
||||
product_id=product_id,
|
||||
model_type='xgboost',
|
||||
store_id=store_id,
|
||||
training_mode=training_mode,
|
||||
aggregation_method=aggregation_method,
|
||||
product_name=product_name,
|
||||
version='best' # 明确指定版本为 'best'
|
||||
)
|
||||
print(f"✅ XGBoost最佳模型已通过统一管理器保存,版本: {best_version}, 路径: {best_model_path}")
|
||||
|
||||
# 返回值遵循统一格式
|
||||
return model, metrics, final_version, final_model_path
|
||||
|
679
xz系统API注解和swagger访问.md
Normal file
679
xz系统API注解和swagger访问.md
Normal file
@ -0,0 +1,679 @@
|
||||
## 访问Swagger UI:
|
||||
## 服务启动后,在您的浏览器中打开以下地址即可查看交互式API文档:
|
||||
## http://localhost:5173/swagger/
|
||||
## 文件路径:C:\WorkSpace\ShopTRAINING\server\swagger.json
|
||||
|
||||
# 药店销售预测系统 API 文档
|
||||
|
||||
**版本:** 1.0.0
|
||||
**联系方式:** [API开发团队](mailto:support@example.com)
|
||||
|
||||
本文档详细描述了用于药店销售预测的RESTful API。
|
||||
|
||||
---
|
||||
|
||||
## 数据管理
|
||||
|
||||
数据上传和查询相关接口。
|
||||
|
||||
### `GET /api/products`
|
||||
|
||||
**摘要:** 获取所有产品列表
|
||||
|
||||
**描述:** 返回系统中所有产品的ID和名称。
|
||||
|
||||
**响应:**
|
||||
* `200`: 成功获取产品列表。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": [
|
||||
{
|
||||
"product_id": "P001",
|
||||
"product_name": "产品A"
|
||||
},
|
||||
{
|
||||
"product_id": "P002",
|
||||
"product_name": "产品B"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
* `500`: 服务器内部错误。
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/products/{product_id}`
|
||||
|
||||
**摘要:** 获取单个产品详情
|
||||
|
||||
**描述:** 返回指定产品ID的详细信息。
|
||||
|
||||
**路径参数:**
|
||||
* `product_id` (string, required): 产品ID,例如P001。
|
||||
|
||||
**响应:**
|
||||
* `200`: 成功获取产品详情。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"product_id": "P001",
|
||||
"product_name": "产品A",
|
||||
"data_points": 365,
|
||||
"date_range": {
|
||||
"start": "2023-01-01",
|
||||
"end": "2023-12-31"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
* `404`: 产品不存在。
|
||||
* `500`: 服务器内部错误。
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/products/{product_id}/sales`
|
||||
|
||||
**摘要:** 获取产品销售数据
|
||||
|
||||
**描述:** 返回指定产品在特定日期范围内的销售数据。
|
||||
|
||||
**路径参数:**
|
||||
* `product_id` (string, required): 产品ID,例如P001。
|
||||
|
||||
**查询参数:**
|
||||
* `start_date` (string): 开始日期,格式为YYYY-MM-DD。
|
||||
* `end_date` (string): 结束日期,格式为YYYY-MM-DD。
|
||||
|
||||
**响应:**
|
||||
* `200`: 成功获取销售数据。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": [
|
||||
{
|
||||
"date": "2023-12-01",
|
||||
"sales": 150
|
||||
},
|
||||
{
|
||||
"date": "2023-12-02",
|
||||
"sales": 155
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
* `404`: 产品不存在。
|
||||
* `500`: 服务器内部错误。
|
||||
|
||||
---
|
||||
|
||||
### `POST /api/data/upload`
|
||||
|
||||
**摘要:** 上传销售数据
|
||||
|
||||
**描述:** 上传新的销售数据文件(Excel格式)。
|
||||
|
||||
**请求体:** `multipart/form-data`
|
||||
* `file` (binary, required): Excel文件(.xlsx),包含销售数据。
|
||||
|
||||
**响应:**
|
||||
* `200`: 数据上传成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"message": "数据上传成功",
|
||||
"data": {
|
||||
"products": 10,
|
||||
"rows": 3650
|
||||
}
|
||||
}
|
||||
```
|
||||
* `400`: 请求错误。
|
||||
* `500`: 服务器内部错误。
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/stores`
|
||||
|
||||
**摘要:** 获取所有店铺列表
|
||||
|
||||
**响应:**
|
||||
* `200`: 获取成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": [
|
||||
{
|
||||
"store_id": "S001",
|
||||
"store_name": "第一分店"
|
||||
},
|
||||
{
|
||||
"store_id": "S002",
|
||||
"store_name": "第二分店"
|
||||
}
|
||||
],
|
||||
"count": 2
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `POST /api/stores`
|
||||
|
||||
**摘要:** 创建新店铺
|
||||
|
||||
**响应:**
|
||||
* `200`: 创建成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"message": "店铺创建成功",
|
||||
"data": {
|
||||
"store_id": "S003"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/stores/{store_id}`
|
||||
|
||||
**摘要:** 获取单个店铺信息
|
||||
|
||||
**路径参数:**
|
||||
* `store_id` (string, required): 店铺ID。
|
||||
|
||||
**响应:**
|
||||
* `200`: 获取成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"store_id": "S001",
|
||||
"store_name": "第一分店",
|
||||
"location": "市中心",
|
||||
"size": 120.5,
|
||||
"type": "旗舰店",
|
||||
"opening_date": "2022-01-01",
|
||||
"status": "active"
|
||||
}
|
||||
}
|
||||
```
|
||||
* `404`: 店铺不存在。
|
||||
|
||||
---
|
||||
|
||||
### `PUT /api/stores/{store_id}`
|
||||
|
||||
**摘要:** 更新店铺信息
|
||||
|
||||
**路径参数:**
|
||||
* `store_id` (string, required): 店铺ID。
|
||||
|
||||
**响应:**
|
||||
* `200`: 更新成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"message": "店铺更新成功"
|
||||
}
|
||||
```
|
||||
* `404`: 店铺不存在。
|
||||
|
||||
---
|
||||
|
||||
### `DELETE /api/stores/{store_id}`
|
||||
|
||||
**摘要:** 删除店铺
|
||||
|
||||
**路径参数:**
|
||||
* `store_id` (string, required): 店铺ID。
|
||||
|
||||
**响应:**
|
||||
* `200`: 删除成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"message": "店铺删除成功"
|
||||
}
|
||||
```
|
||||
* `404`: 店铺不存在。
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/stores/{store_id}/products`
|
||||
|
||||
**摘要:** 获取店铺的产品列表
|
||||
|
||||
**路径参数:**
|
||||
* `store_id` (string, required): 店铺ID。
|
||||
|
||||
**响应:**
|
||||
* `200`: 获取成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": [
|
||||
{
|
||||
"product_id": "P001",
|
||||
"product_name": "产品A"
|
||||
}
|
||||
],
|
||||
"count": 1
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/stores/{store_id}/statistics`
|
||||
|
||||
**摘要:** 获取店铺销售统计信息
|
||||
|
||||
**路径参数:**
|
||||
* `store_id` (string, required): 店铺ID。
|
||||
|
||||
**响应:**
|
||||
* `200`: 获取成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"total_sales": 150000.0,
|
||||
"total_quantity": 7500,
|
||||
"products_count": 50
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/sales/data`
|
||||
|
||||
**摘要:** 获取销售数据列表
|
||||
|
||||
**响应:**
|
||||
* `200`: 获取成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": [
|
||||
{
|
||||
"date": "2023-12-01",
|
||||
"store_id": "S001",
|
||||
"product_id": "P001",
|
||||
"sales": 150,
|
||||
"price": 25.5
|
||||
}
|
||||
],
|
||||
"total": 100,
|
||||
"page": 1,
|
||||
"page_size": 1
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 模型训练
|
||||
|
||||
模型训练相关接口。
|
||||
|
||||
### `GET /api/training`
|
||||
|
||||
**摘要:** 获取所有训练任务列表
|
||||
|
||||
**描述:** 返回所有正在进行、已完成或失败的训练任务。
|
||||
|
||||
**响应:**
|
||||
* `200`: 成功获取任务列表。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": [
|
||||
{
|
||||
"task_id": "uuid-1234",
|
||||
"product_id": "P001",
|
||||
"model_type": "mlstm",
|
||||
"status": "completed",
|
||||
"start_time": "2023-12-25T10:00:00Z",
|
||||
"metrics": {"R2": 0.95, "RMSE": 5.5},
|
||||
"error": null,
|
||||
"model_path": "/path/to/model.pth"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `POST /api/training`
|
||||
|
||||
**摘要:** 启动模型训练任务
|
||||
|
||||
**描述:** 为指定产品启动一个新的模型训练任务。
|
||||
|
||||
**请求体:** `application/json`
|
||||
```json
|
||||
{
|
||||
"product_id": "P001",
|
||||
"model_type": "mlstm",
|
||||
"store_id": "S001",
|
||||
"epochs": 50
|
||||
}
|
||||
```
|
||||
|
||||
**响应:**
|
||||
* `200`: 训练任务已启动。
|
||||
```json
|
||||
{
|
||||
"message": "模型训练已开始",
|
||||
"task_id": "new-uuid-5678"
|
||||
}
|
||||
```
|
||||
* `400`: 请求错误。
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/training/{task_id}`
|
||||
|
||||
**摘要:** 查询训练任务状态
|
||||
|
||||
**描述:** 获取特定训练任务的当前状态和详情。
|
||||
|
||||
**路径参数:**
|
||||
* `task_id` (string, required): 训练任务ID。
|
||||
|
||||
**响应:**
|
||||
* `200`: 成功获取任务状态。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"product_id": "P001",
|
||||
"model_type": "mlstm",
|
||||
"status": "running",
|
||||
"progress": 50.5,
|
||||
"created_at": "2023-12-25T10:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
* `404`: 任务不存在。
|
||||
* `500`: 服务器内部错误。
|
||||
|
||||
---
|
||||
|
||||
## 模型预测
|
||||
|
||||
预测销售数据相关接口。
|
||||
|
||||
### `POST /api/prediction`
|
||||
|
||||
**摘要:** 使用模型进行预测
|
||||
|
||||
**描述:** 使用指定模型预测未来销售数据。
|
||||
|
||||
**请求体:** `application/json`
|
||||
```json
|
||||
{
|
||||
"product_id": "string",
|
||||
"model_type": "mlstm",
|
||||
"store_id": "string",
|
||||
"version": "string",
|
||||
"future_days": 7,
|
||||
"include_visualization": true,
|
||||
"start_date": "2024-01-01"
|
||||
}
|
||||
```
|
||||
|
||||
**响应:**
|
||||
* `200`: 预测成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"product_id": "P001",
|
||||
"product_name": "产品A",
|
||||
"model_type": "mlstm",
|
||||
"predictions": [
|
||||
{"date": "2024-01-01", "predicted_sales": 100},
|
||||
{"date": "2024-01-02", "predicted_sales": 105}
|
||||
],
|
||||
"visualization": "base64-encoded-image-string"
|
||||
}
|
||||
}
|
||||
```
|
||||
* `400`: 请求错误。
|
||||
* `404`: 产品或模型不存在。
|
||||
* `500`: 服务器内部错误。
|
||||
|
||||
---
|
||||
|
||||
### `POST /api/prediction/compare`
|
||||
|
||||
**摘要:** 比较不同模型预测结果
|
||||
|
||||
**描述:** 比较不同模型对同一产品的预测结果。
|
||||
|
||||
**请求体:** `application/json`
|
||||
```json
|
||||
{
|
||||
"product_id": "string",
|
||||
"model_types": ["mlstm", "transformer"],
|
||||
"versions": ["v1", "v2"],
|
||||
"include_visualization": true
|
||||
}
|
||||
```
|
||||
|
||||
**响应:**
|
||||
* `200`: 比较成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"product_id": "P001",
|
||||
"comparison": [
|
||||
{"date": "2024-01-01", "mlstm": 100, "transformer": 102},
|
||||
{"date": "2024-01-02", "mlstm": 105, "transformer": 106}
|
||||
],
|
||||
"visualization": "base64-encoded-image-string"
|
||||
}
|
||||
}
|
||||
```
|
||||
* `400`: 请求错误。
|
||||
* `404`: 产品或模型不存在。
|
||||
* `500`: 服务器内部错误。
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/prediction/history`
|
||||
|
||||
**摘要:** 获取历史预测记录
|
||||
|
||||
**响应:**
|
||||
* `200`: 获取成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": [
|
||||
{
|
||||
"prediction_id": "pred-uuid-1",
|
||||
"product_id": "P001",
|
||||
"model_type": "mlstm",
|
||||
"created_at": "2023-12-20T11:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/prediction/history/{prediction_id}`
|
||||
|
||||
**摘要:** 获取特定预测记录的详情
|
||||
|
||||
**路径参数:**
|
||||
* `prediction_id` (string, required): 预测记录ID。
|
||||
|
||||
**响应:**
|
||||
* `200`: 获取成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"prediction_id": "pred-uuid-1",
|
||||
"product_id": "P001",
|
||||
"model_type": "mlstm",
|
||||
"predictions": [{"date": "2023-12-21", "predicted_sales": 110}],
|
||||
"analysis": {"trend": "upward"}
|
||||
}
|
||||
}
|
||||
```
|
||||
* `404`: 记录不存在。
|
||||
|
||||
---
|
||||
|
||||
### `DELETE /api/prediction/history/{prediction_id}`
|
||||
|
||||
**摘要:** 删除预测记录
|
||||
|
||||
**路径参数:**
|
||||
* `prediction_id` (string, required): 预测记录ID。
|
||||
|
||||
**响应:**
|
||||
* `200`: 删除成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"message": "预测记录已删除"
|
||||
}
|
||||
```
|
||||
* `404`: 记录不存在。
|
||||
|
||||
---
|
||||
|
||||
## 模型管理
|
||||
|
||||
模型查询、导出和删除接口。
|
||||
|
||||
### `GET /api/models`
|
||||
|
||||
**摘要:** 获取模型列表
|
||||
|
||||
**查询参数:**
|
||||
* `product_id` (string): 按产品ID筛选。
|
||||
* `model_type` (string): 按模型类型筛选。
|
||||
|
||||
**响应:**
|
||||
* `200`: 获取成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": [
|
||||
{
|
||||
"model_id": "P001_mlstm_v1",
|
||||
"product_id": "P001",
|
||||
"model_type": "mlstm",
|
||||
"version": "v1",
|
||||
"created_at": "2023-12-15T09:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/models/{model_id}`
|
||||
|
||||
**摘要:** 获取模型详情
|
||||
|
||||
**路径参数:**
|
||||
* `model_id` (string, required): 模型ID。
|
||||
|
||||
**响应:**
|
||||
* `200`: 获取成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"model_id": "P001_mlstm_v1",
|
||||
"product_id": "P001",
|
||||
"model_type": "mlstm",
|
||||
"version": "v1",
|
||||
"metrics": {"R2": 0.95, "RMSE": 5.5}
|
||||
}
|
||||
}
|
||||
```
|
||||
* `404`: 模型不存在。
|
||||
|
||||
---
|
||||
|
||||
### `DELETE /api/models/{model_id}`
|
||||
|
||||
**摘要:** 删除模型
|
||||
|
||||
**路径参数:**
|
||||
* `model_id` (string, required): 模型ID。
|
||||
|
||||
**响应:**
|
||||
* `200`: 删除成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"message": "模型已删除"
|
||||
}
|
||||
```
|
||||
* `404`: 模型不存在。
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/models/{model_id}/export`
|
||||
|
||||
**摘要:** 导出模型
|
||||
|
||||
**路径参数:**
|
||||
* `model_id` (string, required): 模型ID。
|
||||
|
||||
**响应:**
|
||||
* `200`: 模型文件下载 (二进制流)。
|
||||
* `404`: 模型不存在。
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/model_types`
|
||||
|
||||
**摘要:** 获取系统支持的所有模型类型
|
||||
|
||||
**响应:**
|
||||
* `200`: 获取成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": [
|
||||
{"id": "mlstm", "name": "mLSTM"},
|
||||
{"id": "transformer", "name": "Transformer"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/models/{product_id}/{model_type}/versions`
|
||||
|
||||
**摘要:** 获取模型版本列表
|
||||
|
||||
**路径参数:**
|
||||
* `product_id` (string, required): 产品ID。
|
||||
* `model_type` (string, required): 模型类型。
|
||||
|
||||
**响应:**
|
||||
* `200`: 获取成功。
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"product_id": "P001",
|
||||
"model_type": "mlstm",
|
||||
"versions": ["v1", "v2"],
|
||||
"latest_version": "v2"
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user