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

321 lines
17 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
动作点管理相关模型
用于处理动作点和库位的管理操作
"""
from typing import Optional, List, Dict, Any
from pydantic import BaseModel, Field
from enum import Enum
from datetime import datetime
from data.models.extended_property import ExtendedPropertyTypeEnum
class StorageAreaTypeEnum(str, Enum):
"""库区类型枚举"""
GENERAL = "general"
DENSE = "dense"
class StorageLocationActionEnum(str, Enum):
"""库位操作类型枚举"""
OCCUPY = "occupy" # 占用库位
RELEASE = "release" # 释放库位
LOCK = "lock" # 锁定库位
UNLOCK = "unlock" # 解锁库位
ENABLE = "enable" # 启用库位
DISABLE = "disable" # 禁用库位
SET_EMPTY_TRAY = "set_empty_tray" # 设置为空托盘
CLEAR_EMPTY_TRAY = "clear_empty_tray" # 清除空托盘状态
class OperatePointLayerInfo(BaseModel):
"""动作点分层信息"""
id: str = Field(..., description="层ID")
layer_index: int = Field(..., description="层索引")
layer_name: Optional[str] = Field(None, description="层名称")
is_occupied: bool = Field(..., description="是否占用")
is_locked: bool = Field(..., description="是否锁定")
is_disabled: bool = Field(..., description="是否禁用")
is_empty_tray: bool = Field(..., description="是否空托盘")
goods_content: str = Field(..., description="货物内容")
goods_weight: Optional[int] = Field(None, description="货物重量(克)")
goods_volume: Optional[int] = Field(None, description="货物体积(立方厘米)")
max_weight: Optional[int] = Field(None, description="最大承重(克)")
max_volume: Optional[int] = Field(None, description="最大体积(立方厘米)")
layer_height: Optional[int] = Field(None, description="层高(毫米)")
locked_by: Optional[str] = Field(None, description="锁定者")
tags: Optional[str] = Field(None, description="标签")
description: Optional[str] = Field(None, description="层描述")
goods_stored_at: Optional[datetime] = Field(None, description="货物存放时间")
goods_retrieved_at: Optional[datetime] = Field(None, description="货物取出时间")
last_access_at: Optional[datetime] = Field(None, description="最后访问时间")
# 库位列表相关模型
class StorageLocationInfo(BaseModel):
"""库位信息(基于动作点分层)"""
# 库位基本信息
id: str = Field(..., description="库位ID层ID")
layer_index: int = Field(..., description="层索引")
layer_name: Optional[str] = Field(None, description="层名称")
# 库位状态
is_occupied: bool = Field(..., description="是否占用")
is_locked: bool = Field(..., description="是否锁定")
is_disabled: bool = Field(..., description="是否禁用")
is_empty_tray: bool = Field(..., description="是否空托盘")
locked_by: Optional[str] = Field(None, description="锁定者")
# 货物信息
goods_content: str = Field(..., description="货物内容")
goods_weight: Optional[int] = Field(None, description="货物重量(克)")
goods_volume: Optional[int] = Field(None, description="货物体积(立方厘米)")
goods_stored_at: Optional[datetime] = Field(None, description="货物存放时间")
goods_retrieved_at: Optional[datetime] = Field(None, description="货物取出时间")
last_access_at: Optional[datetime] = Field(None, description="最后访问时间")
# 库位规格
max_weight: Optional[int] = Field(None, description="最大承重(克)")
max_volume: Optional[int] = Field(None, description="最大体积(立方厘米)")
layer_height: Optional[int] = Field(None, description="层高(毫米)")
# 扩展信息
tags: Optional[str] = Field(None, description="标签")
description: Optional[str] = Field(None, description="库位描述")
created_at: Optional[datetime] = Field(None, description="创建时间")
updated_at: Optional[datetime] = Field(None, description="更新时间")
# 扩展字段
extended_fields: Optional[Dict[str, Any]] = Field(None, description="扩展字段")
# 动作点信息(直接平铺)
operate_point_id: Optional[str] = Field(None, description="所属动作点ID")
station_name: Optional[str] = Field(None, description="动作站点名称")
storage_location_name: Optional[str] = Field(None, description="库位名称")
scene_id: Optional[str] = Field(None, description="场景ID")
storage_area_id: Optional[str] = Field(None, description="所属库区ID")
storage_area_type: Optional[str] = Field(None, description="库区类型")
area_name: Optional[str] = Field(None, description="库区名称")
max_layers: Optional[int] = Field(None, description="最大层数")
current_layers: Optional[int] = Field(None, 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坐标")
operate_point_description: Optional[str] = Field(None, description="动作点描述")
class StorageLocationListRequest(BaseModel):
"""库位列表查询请求"""
scene_id: Optional[str] = Field(None, description="场景ID")
storage_area_id: Optional[str] = Field(None, description="库区ID")
station_name: Optional[str] = Field(None, description="站点名称(支持模糊搜索)")
storage_location_name: Optional[str] = Field(None, description="库位名称(支持模糊搜索)")
layer_name: Optional[str] = Field(None, description="层名称(支持模糊搜索)")
is_disabled: Optional[bool] = Field(None, description="是否禁用")
is_occupied: Optional[bool] = Field(None, description="是否占用")
is_locked: Optional[bool] = Field(None, description="是否锁定")
is_empty_tray: Optional[bool] = Field(None, description="是否空托盘")
include_operate_point_info: bool = Field(True, description="是否包含动作点信息")
include_extended_fields: bool = Field(True, description="是否包含扩展字段")
page: int = Field(1, ge=1, description="页码")
page_size: int = Field(20, ge=1, le=100, description="每页数量")
class StorageLocationListResponse(BaseModel):
"""库位列表查询响应"""
total: int = Field(..., description="总数量")
page: int = Field(..., description="当前页码")
page_size: int = Field(..., description="每页数量")
total_pages: int = Field(..., description="总页数")
storage_locations: List[StorageLocationInfo] = Field(..., description="库位列表")
class StorageLocationStatistics(BaseModel):
"""库位统计信息"""
total_storage_locations: int = Field(..., description="总库位数")
occupied_storage_locations: int = Field(..., description="已占用库位数")
available_storage_locations: int = Field(..., description="可用库位数")
disabled_storage_locations: int = Field(..., description="禁用库位数")
locked_storage_locations: int = Field(..., description="锁定库位数")
empty_tray_storage_locations: int = Field(..., description="空托盘库位数")
dense_area_storage_locations: int = Field(..., description="密集库区库位数")
general_area_storage_locations: int = Field(..., description="一般库区库位数")
occupancy_rate: float = Field(..., description="占用率")
availability_rate: float = Field(..., description="可用率")
# 库位状态管理相关模型
class StorageLocationStatusUpdateRequest(BaseModel):
"""库位状态更新请求"""
storage_location_id: str = Field(..., description="库位ID层ID")
action: StorageLocationActionEnum = Field(..., description="操作类型")
locked_by: Optional[str] = Field(None, description="锁定者(锁定操作时必填)")
reason: Optional[str] = Field(None, description="操作原因")
class StorageLocationStatusUpdateResponse(BaseModel):
"""库位状态更新响应"""
storage_location_id: str = Field(..., description="库位ID")
action: StorageLocationActionEnum = Field(..., description="执行的操作")
success: bool = Field(..., description="操作是否成功")
message: str = Field(..., description="操作结果消息")
new_status: Dict[str, Any] = Field(..., description="更新后的状态信息")
class BatchStorageLocationStatusUpdateRequest(BaseModel):
"""批量库位状态更新请求"""
storage_location_ids: List[str] = Field(..., description="库位ID列表")
action: StorageLocationActionEnum = Field(..., description="操作类型")
locked_by: Optional[str] = Field(None, description="锁定者(锁定操作时必填)")
reason: Optional[str] = Field(None, description="操作原因")
class BatchStorageLocationStatusUpdateResponse(BaseModel):
"""批量库位状态更新响应"""
total_count: int = Field(..., description="总操作数量")
success_count: int = Field(..., description="成功操作数量")
failed_count: int = Field(..., description="失败操作数量")
results: List[StorageLocationStatusUpdateResponse] = Field(..., description="详细操作结果列表")
# 扩展属性管理相关模型
class ExtendedPropertyCreateRequest(BaseModel):
"""扩展属性创建请求"""
property_name: str = Field(..., description="属性名称(唯一标识)", min_length=1, max_length=200)
property_type: ExtendedPropertyTypeEnum = Field(ExtendedPropertyTypeEnum.STRING, description="属性类型")
is_required: bool = Field(False, description="是否必填")
is_enabled: bool = Field(True, description="是否启用")
description: Optional[str] = Field(None, description="属性描述")
placeholder: Optional[str] = Field(None, description="输入提示", max_length=500)
default_value: Optional[str] = Field(None, description="默认值")
options: Optional[List[Dict[str, Any]]] = Field(None, description="选项值用于select和multiselect类型")
validation_rules: Optional[Dict[str, Any]] = Field(None, description="验证规则")
category: Optional[str] = Field(None, description="属性分类", max_length=100)
sort_order: int = Field(0, description="排序顺序")
display_width: int = Field(200, description="显示宽度(像素)")
display_format: Optional[str] = Field(None, description="显示格式", max_length=100)
class ExtendedPropertyInfo(BaseModel):
"""扩展属性信息"""
id: str = Field(..., description="属性ID")
property_name: str = Field(..., description="属性名称(唯一标识)")
property_type: ExtendedPropertyTypeEnum = Field(..., description="属性类型")
is_required: bool = Field(..., description="是否必填")
is_enabled: bool = Field(..., description="是否启用")
description: Optional[str] = Field(None, description="属性描述")
placeholder: Optional[str] = Field(None, description="输入提示")
default_value: Optional[str] = Field(None, description="默认值")
options: Optional[List[Dict[str, Any]]] = Field(None, description="选项值")
validation_rules: Optional[Dict[str, Any]] = Field(None, description="验证规则")
category: Optional[str] = Field(None, description="属性分类")
sort_order: int = Field(..., description="排序顺序")
display_width: int = Field(..., description="显示宽度(像素)")
display_format: Optional[str] = Field(None, description="显示格式")
created_at: datetime = Field(..., description="创建时间")
updated_at: datetime = Field(..., description="更新时间")
class ExtendedPropertyCreateResponse(BaseModel):
"""扩展属性创建响应"""
id: str = Field(..., description="创建的属性ID")
property_name: str = Field(..., description="属性名称(唯一标识)")
message: str = Field(..., description="创建结果消息")
class ExtendedPropertyListRequest(BaseModel):
"""扩展属性列表查询请求"""
property_name: Optional[str] = Field(None, description="属性名称(支持模糊搜索)")
property_type: Optional[ExtendedPropertyTypeEnum] = Field(None, description="属性类型")
category: Optional[str] = Field(None, description="属性分类")
is_enabled: Optional[bool] = Field(None, description="是否启用")
page: int = Field(1, ge=1, description="页码")
page_size: int = Field(20, ge=1, le=100, description="每页数量")
class ExtendedPropertyListResponse(BaseModel):
"""扩展属性列表响应"""
total: int = Field(..., description="总数量")
page: int = Field(..., description="当前页码")
page_size: int = Field(..., description="每页数量")
total_pages: int = Field(..., description="总页数")
properties: List[ExtendedPropertyInfo] = Field(..., description="扩展属性列表")
class ExtendedPropertyDeleteResponse(BaseModel):
"""扩展属性删除响应"""
property_id: str = Field(..., description="删除的属性ID")
property_name: str = Field(..., description="属性名称(唯一标识)")
message: str = Field(..., description="删除结果消息")
# 库位详情相关模型
class StorageLocationDetailResponse(BaseModel):
"""库位详情响应"""
storage_location: StorageLocationInfo = Field(..., description="库位详细信息")
operate_point_info: Optional[Dict[str, Any]] = Field(None, description="动作点详细信息")
extended_fields_definitions: Optional[List[ExtendedPropertyInfo]] = Field(None, description="扩展字段定义")
status_history: Optional[List[Dict[str, Any]]] = Field(None, description="状态变更历史")
# 库位编辑相关模型
class StorageLocationEditRequest(BaseModel):
"""库位编辑请求"""
goods_content: Optional[str] = Field(None, description="货物内容", max_length=500)
goods_weight: Optional[int] = Field(None, description="货物重量(克)", ge=0)
goods_volume: Optional[int] = Field(None, description="货物体积(立方厘米)", ge=0)
max_weight: Optional[int] = Field(None, description="最大承重(克)", ge=0)
max_volume: Optional[int] = Field(None, description="最大体积(立方厘米)", ge=0)
layer_height: Optional[int] = Field(None, description="层高(毫米)", ge=0)
is_locked: Optional[bool] = Field(None, description="是否锁定")
is_disabled: Optional[bool] = Field(None, description="是否禁用")
is_empty_tray: Optional[bool] = Field(None, description="是否空托盘")
tags: Optional[str] = Field(None, description="标签", max_length=500)
description: Optional[str] = Field(None, description="库位描述", max_length=1000)
extended_fields: Optional[Dict[str, Any]] = Field(None, description="扩展字段值")
class StorageLocationEditResponse(BaseModel):
"""库位编辑响应"""
storage_location_id: str = Field(..., description="库位ID")
success: bool = Field(..., description="编辑是否成功")
message: str = Field(..., description="操作结果消息")
updated_fields: List[str] = Field(..., description="已更新的字段列表")
updated_storage_location: StorageLocationInfo = Field(..., description="更新后的库位信息")
# 库位操作记录相关模型
class StorageLocationLogInfo(BaseModel):
"""库位操作记录信息"""
id: str = Field(..., description="记录ID")
operation_time: datetime = Field(..., description="操作时间")
operator: str = Field(..., description="操作人")
operation_type: str = Field(..., description="操作类型")
affected_storage_locations: List[str] = Field(..., description="影响的库位ID列表")
description: Optional[str] = Field(None, description="操作描述")
created_at: datetime = Field(..., description="创建时间")
class StorageLocationLogListRequest(BaseModel):
"""库位操作记录查询请求"""
storage_location_id: Optional[str] = Field(None, description="库位ID")
operator: Optional[str] = Field(None, description="操作人(支持模糊搜索)")
operation_type: Optional[str] = Field(None, description="操作类型")
start_time: Optional[datetime] = Field(None, description="开始时间")
end_time: Optional[datetime] = Field(None, description="结束时间")
page: int = Field(1, ge=1, description="页码")
page_size: int = Field(20, ge=1, le=100, description="每页数量")
class StorageLocationLogListResponse(BaseModel):
"""库位操作记录查询响应"""
total: int = Field(..., description="总数量")
page: int = Field(..., description="当前页码")
page_size: int = Field(..., description="每页数量")
total_pages: int = Field(..., description="总页数")
logs: List[StorageLocationLogInfo] = Field(..., description="操作记录列表")