202 lines
6.0 KiB
Python
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) |