VWED_server/routes/model/map_model.py
2025-07-17 15:47:56 +08:00

130 lines
5.2 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
地图数据推送相关模型
用于处理地图数据推送时的动作点和库区信息
"""
from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field, validator
from enum import Enum
class StorageAreaTypeEnum(str, Enum):
"""库区类型枚举"""
GENERAL = "general"
DENSE = "dense"
class OperatePointLayerData(BaseModel):
"""动作点分层数据"""
layer_name: Optional[str] = Field(None, description="层名称")
max_weight: Optional[int] = Field(None, ge=0, description="最大承重(克)")
max_volume: Optional[int] = Field(None, ge=0, description="最大体积(立方厘米)")
layer_height: Optional[int] = Field(None, ge=0, description="层高(毫米)")
description: Optional[str] = Field(None, description="层描述")
tags: Optional[str] = Field(None, description="层标签")
class OperatePointData(BaseModel):
"""动作点数据"""
station_name: str = Field(..., description="动作站点名称")
area_name: Optional[str] = Field(None, description="所属库区名称")
max_layers: int = Field(1, ge=1, description="最大层数")
position_x: Optional[int] = Field(None, description="X坐标")
position_y: Optional[int] = Field(None, description="Y坐标")
position_z: Optional[int] = Field(None, description="Z坐标")
content: Optional[str] = Field("", description="内容")
tags: Optional[str] = Field("", description="标签")
description: Optional[str] = Field(None, description="动作点描述")
layers: Optional[List[OperatePointLayerData]] = Field(None, description="库位名称")
@validator('layers')
def validate_layers(cls, v, values):
"""验证分层数据"""
if v is None:
return v
max_layers = values.get('max_layers', 1)
if len(v) > max_layers:
raise ValueError(f"分层数量({len(v)})不能超过最大层数({max_layers})")
# 检查层名称是否重复
if v:
layer_names = [layer.layer_name for layer in v if layer.layer_name]
if len(layer_names) != len(set(layer_names)):
raise ValueError("层名称不能重复")
return v
class StorageAreaData(BaseModel):
"""库区数据"""
area_name: str = Field(..., description="库区名称")
area_type: StorageAreaTypeEnum = Field(StorageAreaTypeEnum.GENERAL, description="库区类型")
description: Optional[str] = Field(None, description="库区描述")
tags: Optional[str] = Field(None, description="库区标签")
select_logic: int = Field(..., description="选择库位逻辑 1 先进先出 2 先进后出 ")
class MapDataPushRequest(BaseModel):
"""地图数据推送请求"""
scene_id: str = Field(..., description="场景ID")
storage_areas: List[StorageAreaData] = Field(..., description="库区数据列表")
operate_points: List[OperatePointData] = Field(..., description="动作点数据列表")
@validator('operate_points')
def validate_operate_points(cls, v, values):
"""验证动作点数据"""
if not v:
return v
# 检查站点名称是否重复
station_names = [point.station_name for point in v]
if len(station_names) != len(set(station_names)):
raise ValueError("动作站点名称不能重复")
return v
@validator('storage_areas')
def validate_storage_areas(cls, v):
"""验证库区数据"""
if not v:
return v
# 检查库区名称是否重复
area_names = [area.area_name for area in v]
if len(area_names) != len(set(area_names)):
raise ValueError("库区名称不能重复")
return v
class MapDataPushResponse(BaseModel):
"""地图数据推送响应"""
scene_id: str = Field(..., description="场景ID")
storage_areas_count: int = Field(..., description="创建的库区数量")
operate_points_count: int = Field(..., description="创建的动作点数量")
layers_count: int = Field(..., description="创建的分层数量")
message: str = Field("推送成功,已覆盖现有数据", description="推送结果说明")
class MapDataQueryRequest(BaseModel):
"""地图数据查询请求"""
scene_id: str = Field(..., description="场景ID")
area_type: Optional[StorageAreaTypeEnum] = Field(None, description="库区类型筛选")
include_layers: bool = Field(True, description="是否包含分层数据")
class MapDataQueryResponse(BaseModel):
"""地图数据查询响应"""
scene_id: str = Field(..., description="场景ID")
storage_areas: List[Dict[str, Any]] = Field(..., description="库区数据列表")
operate_points: List[Dict[str, Any]] = Field(..., description="动作点数据列表")
total_capacity: int = Field(0, description="总容量")
used_capacity: int = Field(0, description="已使用容量")
dense_areas_count: int = Field(0, description="密集库区数量")
general_areas_count: int = Field(0, description="一般库区数量")
total_layers: int = Field(0, description="总分层数量")
occupied_layers: int = Field(0, description="已占用分层数量")