""" 消息业务模型 定义消息的数据结构和业务逻辑 """ from dataclasses import dataclass, field from datetime import datetime from typing import Optional, List from config import ProtocolType, SerializationType from models.field import Field @dataclass class Message: """ 消息模型类 Attributes: id: 消息ID full_name: 完整名称(如 Radar.Receiver.v3) system_name: 系统名(如 Radar) message_type: 消息类型(如 Receiver) version: 版本号(如 v3) fields: 关联的字段列表 description: 描述信息 protocol: 传输协议 serialization: 序列化格式 created_time: 创建时间 updated_time: 更新时间 """ full_name: str system_name: str message_type: str version: str protocol: ProtocolType serialization: SerializationType id: Optional[int] = None fields: List[Field] = field(default_factory=list) description: Optional[str] = None created_time: Optional[datetime] = None updated_time: Optional[datetime] = None def __post_init__(self): """初始化后处理""" # 确保protocol和serialization是枚举类型 if isinstance(self.protocol, str): self.protocol = ProtocolType(self.protocol) if isinstance(self.serialization, str): self.serialization = SerializationType(self.serialization) # 从full_name解析system_name、message_type和version if self.full_name and not self.system_name: self._parse_full_name() def _parse_full_name(self): """从完整名称解析系统名、消息类型和版本""" parts = self.full_name.split('.') if len(parts) >= 3: self.system_name = parts[0] self.message_type = parts[1] self.version = parts[2] elif len(parts) == 2: self.system_name = parts[0] self.message_type = parts[1] self.version = "v1" @staticmethod def build_full_name(system_name: str, message_type: str, version: str) -> str: """ 构建完整消息名 Args: system_name: 系统名 message_type: 消息类型 version: 版本号 Returns: 完整消息名 """ return f"{system_name}.{message_type}.{version}" def add_field(self, field_obj: Field): """添加字段""" if field_obj not in self.fields: self.fields.append(field_obj) def remove_field(self, field_obj: Field): """移除字段""" if field_obj in self.fields: self.fields.remove(field_obj) def get_field_by_name(self, full_name: str) -> Optional[Field]: """根据完整名称获取字段""" for f in self.fields: if f.full_name == full_name: return f return None def validate(self) -> tuple[bool, str]: """ 验证消息数据的有效性 Returns: (是否有效, 错误信息) """ if not self.full_name: return False, "消息完整名称不能为空" if not self.system_name: return False, "系统名不能为空" if not self.message_type: return False, "消息类型不能为空" if not self.version: return False, "版本号不能为空" if not self.fields or len(self.fields) == 0: return False, "消息至少需要包含一个字段" if not self.protocol: return False, "传输协议不能为空" if not self.serialization: return False, "序列化格式不能为空" return True, "" def to_dict(self) -> dict: """转换为字典""" return { 'id': self.id, 'full_name': self.full_name, 'system_name': self.system_name, 'message_type': self.message_type, 'version': self.version, 'description': self.description, 'protocol': self.protocol.value if isinstance(self.protocol, ProtocolType) else self.protocol, 'serialization': self.serialization.value if isinstance(self.serialization, SerializationType) else self.serialization, 'fields': [f.to_dict() for f in self.fields], 'created_time': self.created_time.isoformat() if self.created_time else None, 'updated_time': self.updated_time.isoformat() if self.updated_time else None, } @classmethod def from_dict(cls, data: dict) -> 'Message': """从字典创建对象""" # 解析字段列表 fields = [] if 'fields' in data: fields = [Field.from_dict(f) if isinstance(f, dict) else f for f in data['fields']] # 解析时间 created_time = None if data.get('created_time'): if isinstance(data['created_time'], str): created_time = datetime.fromisoformat(data['created_time']) else: created_time = data['created_time'] updated_time = None if data.get('updated_time'): if isinstance(data['updated_time'], str): updated_time = datetime.fromisoformat(data['updated_time']) else: updated_time = data['updated_time'] return cls( id=data.get('id'), full_name=data['full_name'], system_name=data['system_name'], message_type=data['message_type'], version=data['version'], protocol=data['protocol'], serialization=data['serialization'], fields=fields, description=data.get('description'), created_time=created_time, updated_time=updated_time, ) def __str__(self) -> str: """字符串表示""" return f"Message(id={self.id}, full_name={self.full_name}, fields={len(self.fields)})" def __repr__(self) -> str: """详细字符串表示""" return self.__str__()