VWED_server/routes/map_data_api.py
2025-07-14 10:29:37 +08:00

202 lines
6.0 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
地图数据推送API路由
实现地图数据推送时的动作点和库区数据存储功能
"""
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import Any, Dict
from data.session import get_db
from services.map_data_service import MapDataService
from routes.model.base import ApiResponse
from routes.model.map_model import (
MapDataPushRequest, MapDataPushResponse,
MapDataQueryRequest, MapDataQueryResponse
)
from routes.common_api import format_response, error_response
from utils.logger import get_logger
# 创建路由
router = APIRouter(prefix="/api/vwed-map-data", tags=["地图数据推送"])
# 设置日志
logger = get_logger("app.map_data_api")
# 标准API响应格式
def api_response(code: int = 200, message: str = "操作成功", data: Any = None) -> Dict[str, Any]:
"""
标准API响应格式
Args:
code: 状态码
message: 响应消息
data: 响应数据
Returns:
Dict[str, Any]: 格式化的响应数据
"""
return {
"code": code,
"message": message,
"data": data
}
@router.post("/push", response_model=ApiResponse[MapDataPushResponse])
async def push_map_data(
request: MapDataPushRequest,
db: Session = Depends(get_db)
):
"""
推送地图数据
当用户推送新的地图时,将地图相关的动作点和库区数据存入数据库
支持库区分类(密集库区、一般库区)和动作点分层存储
重要功能:
- 自动为新创建的库位层同步所有已启用的扩展属性
- 新库位层会自动包含系统中定义的扩展属性配置
- 扩展属性使用默认值进行初始化
Args:
request: 地图数据推送请求
db: 数据库会话
Returns:
ApiResponse[MapDataPushResponse]: 推送结果响应
"""
try:
# 调用服务层方法推送地图数据
result = MapDataService.push_map_data(db=db, request=request)
return api_response(message="地图数据推送成功", data=result)
except ValueError as e:
# 数据验证错误
return error_response(str(e), 400)
except Exception as e:
logger.error(f"地图数据推送失败: {str(e)}")
return error_response(f"地图数据推送失败: {str(e)}", 500)
@router.post("/query", response_model=ApiResponse[MapDataQueryResponse])
async def query_map_data(
request: MapDataQueryRequest,
db: Session = Depends(get_db)
):
"""
查询地图数据
根据场景ID查询地图中的库区和动作点数据
支持按库区类型筛选和是否包含分层数据的选项
Args:
request: 地图数据查询请求
db: 数据库会话
Returns:
ApiResponse[MapDataQueryResponse]: 查询结果响应
"""
try:
# 调用服务层方法查询地图数据
result = MapDataService.query_map_data(db=db, request=request)
return api_response(message="查询成功", data=result)
except ValueError as e:
# 数据验证错误
return error_response(str(e), 400)
except Exception as e:
logger.error(f"查询地图数据失败: {str(e)}")
return error_response(f"查询地图数据失败: {str(e)}", 500)
@router.delete("/scene/{scene_id}")
async def delete_scene_data(
scene_id: str,
db: Session = Depends(get_db)
):
"""
删除场景数据
删除指定场景的所有地图数据,包括库区、动作点和分层数据
Args:
scene_id: 场景ID
db: 数据库会话
Returns:
ApiResponse: 删除结果响应
"""
try:
# 调用服务层的删除方法
MapDataService._delete_existing_data(db=db, scene_id=scene_id)
db.commit()
logger.info(f"场景数据删除成功: 场景ID={scene_id}")
return api_response(message="场景数据删除成功")
except Exception as e:
db.rollback()
logger.error(f"删除场景数据失败: {str(e)}")
return error_response(f"删除场景数据失败: {str(e)}", 500)
@router.get("/scene/{scene_id}/summary")
async def get_scene_summary(
scene_id: str,
db: Session = Depends(get_db)
):
"""
获取场景数据摘要
获取指定场景的数据统计信息,包括库区和动作点的数量统计
Args:
scene_id: 场景ID
db: 数据库会话
Returns:
ApiResponse: 场景摘要信息
"""
try:
# 构造查询请求
query_request = MapDataQueryRequest(
scene_id=scene_id,
include_layers=True
)
# 调用服务层方法获取数据
result = MapDataService.query_map_data(db=db, request=query_request)
# 提取摘要信息
summary = {
"scene_id": result.scene_id,
"total_storage_areas": len(result.storage_areas),
"total_operate_points": len(result.operate_points),
"total_capacity": result.total_capacity,
"used_capacity": result.used_capacity,
"capacity_usage_rate": round(
(result.used_capacity / result.total_capacity * 100) if result.total_capacity > 0 else 0, 2
),
"dense_areas_count": result.dense_areas_count,
"general_areas_count": result.general_areas_count,
"total_layers": result.total_layers,
"occupied_layers": result.occupied_layers,
"layer_usage_rate": round(
(result.occupied_layers / result.total_layers * 100) if result.total_layers > 0 else 0, 2
)
}
return api_response(message="获取场景摘要成功", data=summary)
except Exception as e:
logger.error(f"获取场景摘要失败: {str(e)}")
return error_response(f"获取场景摘要失败: {str(e)}", 500)