135 lines
5.5 KiB
Python
135 lines
5.5 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="动作站点名称")
|
|
storage_location_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("动作站点名称不能重复")
|
|
|
|
# 检查库位名称是否重复
|
|
storage_location_names = [point.storage_location_name for point in v]
|
|
if len(storage_location_names) != len(set(storage_location_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="已占用分层数量") |