127 lines
4.7 KiB
Python
127 lines
4.7 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
动作点数据模型
|
|
基于现有的vwed_operate_point表结构进行扩展
|
|
动作点和库位是同一个概念
|
|
"""
|
|
|
|
from sqlalchemy import Column, String, Integer, Boolean, Text, DateTime, ForeignKey, Enum
|
|
from sqlalchemy.orm import relationship
|
|
from sqlalchemy.dialects.mysql import CHAR
|
|
from .base import BaseModel
|
|
from .storage_area import StorageAreaType
|
|
|
|
|
|
class OperatePoint(BaseModel):
|
|
"""
|
|
动作点数据模型
|
|
继承现有的vwed_operate_point表结构并扩展
|
|
"""
|
|
__tablename__ = 'vwed_operate_point'
|
|
|
|
id = Column(CHAR(64), primary_key=True, comment='动作点ID')
|
|
station_name = Column(String(64), nullable=False, comment='动作站点名称')
|
|
storage_location_name = Column(String(64), nullable=False, comment='库位名称')
|
|
scene_id = Column(String(64), nullable=False, comment='场景ID')
|
|
|
|
# 原有字段
|
|
# is_occupied = Column(Boolean, nullable=False, default=False, comment='是否占用')
|
|
# is_locked = Column(Boolean, nullable=False, default=False, comment='是否锁定')
|
|
is_disabled = Column(Boolean, nullable=False, default=False, comment='是否禁用')
|
|
# is_empty_tray = Column(Boolean, nullable=False, default=False, comment='是否空托盘')
|
|
content = Column(String(100), nullable=False, default='', comment='内容')
|
|
tags = Column(String(100), nullable=False, default='', comment='标签')
|
|
|
|
# 库区关联
|
|
storage_area_id = Column(CHAR(64), ForeignKey('vwed_storage_area.id'), nullable=True, comment='所属库区ID')
|
|
|
|
# 库区类型
|
|
storage_area_type = Column(Enum(StorageAreaType), nullable=True, comment='库区类型')
|
|
|
|
# 库区名称
|
|
area_name = Column(String(64), nullable=True, comment='库区名称')
|
|
|
|
# 动作点属性
|
|
max_layers = Column(Integer, nullable=False, default=1, comment='最大层数')
|
|
current_layers = Column(Integer, nullable=False, default=0, comment='当前使用层数')
|
|
|
|
# 动作点位置信息
|
|
position_x = Column(Integer, comment='X坐标', nullable=True)
|
|
position_y = Column(Integer, comment='Y坐标', nullable=True)
|
|
position_z = Column(Integer, comment='Z坐标', nullable=True)
|
|
|
|
# 动作点配置
|
|
description = Column(Text, comment='动作点描述')
|
|
|
|
# 关联关系
|
|
storage_area = relationship("StorageArea", back_populates="operate_points")
|
|
layers = relationship(
|
|
"OperatePointLayer",
|
|
back_populates="operate_point",
|
|
cascade="all, delete-orphan",
|
|
order_by="OperatePointLayer.layer_index"
|
|
)
|
|
|
|
def __repr__(self):
|
|
return f"<OperatePoint(id={self.id}, station_name={self.station_name}, storage_location_name={self.storage_location_name}, storage_area_id={self.storage_area_id}, storage_area_type={self.storage_area_type}, area_name={self.area_name})>"
|
|
|
|
def get_available_layers(self):
|
|
"""获取可用层数"""
|
|
return self.max_layers - self.current_layers
|
|
|
|
def get_layer_usage_rate(self):
|
|
"""获取层使用率"""
|
|
if self.max_layers == 0:
|
|
return 0.0
|
|
return (self.current_layers / self.max_layers) * 100.0
|
|
|
|
def is_full(self):
|
|
"""是否已满"""
|
|
return self.current_layers >= self.max_layers
|
|
|
|
def is_empty(self):
|
|
"""是否为空"""
|
|
return self.current_layers == 0
|
|
|
|
def can_store_goods(self):
|
|
"""是否可以存放货物"""
|
|
return (not self.is_disabled and
|
|
not self.is_full() and
|
|
self.max_layers > 0)
|
|
|
|
def can_retrieve_goods(self):
|
|
"""是否可以取货"""
|
|
return (not self.is_disabled and
|
|
not self.is_empty())
|
|
|
|
def get_occupied_layers(self):
|
|
"""获取有货物的层列表"""
|
|
return [layer for layer in self.layers if layer.is_occupied]
|
|
|
|
def get_empty_layers(self):
|
|
"""获取空层列表"""
|
|
return [layer for layer in self.layers if not layer.is_occupied]
|
|
|
|
def has_storage_area(self):
|
|
"""是否属于某个库区"""
|
|
return self.storage_area_id is not None
|
|
|
|
def get_storage_area_info(self):
|
|
"""获取库区信息"""
|
|
if self.storage_area_id is None:
|
|
return None
|
|
return self.storage_area
|
|
|
|
def is_dense_storage(self):
|
|
"""是否为密集库区类型"""
|
|
return self.storage_area_type == StorageAreaType.DENSE
|
|
|
|
def is_general_storage(self):
|
|
"""是否为一般库区类型"""
|
|
return self.storage_area_type == StorageAreaType.GENERAL
|
|
|
|
def get_storage_area_display_name(self):
|
|
"""获取库区显示名称"""
|
|
return self.area_name or "未分配库区" |