""" 任务输入参数模型 用于存储任务输入参数的数据 """ from sqlalchemy import Column, Integer, String, Text, DateTime, Boolean, ForeignKey, JSON, Enum, Index from sqlalchemy.orm import relationship, foreign from sqlalchemy.sql.expression import and_ from datetime import datetime import uuid import json from data.models.base import BaseModel from config.task_config import TaskInputParamType class TaskInputParam(BaseModel): """任务输入参数模型""" __tablename__ = "task_input_params" id = Column(Integer, primary_key=True, autoincrement=True, comment="主键ID") param_id = Column(String(36), nullable=False, unique=True, index=True, comment="参数唯一ID,用于外部引用") instance_id = Column(String(36), index=True, nullable=False, comment="关联的任务实例ID") task_id = Column(String(50), nullable=False, index=True, comment="任务ID,冗余存储便于查询") param_name = Column(String(50), nullable=True, comment="参数名称,变量名") label = Column(String(100), nullable=True, comment="参数标签,显示名称") param_type = Column(String(20), nullable=False, comment="参数类型") required = Column(Boolean, default=False, comment="是否必填") _default_value = Column('default_value', Text, nullable=True, comment="默认值") description = Column(Text, nullable=True, comment="参数说明") is_system = Column(Boolean, default=False, comment="是否系统参数") is_readonly = Column(Boolean, default=False, comment="是否只读参数") sort_order = Column(Integer, default=0, comment="排序顺序") # 手动创建索引而不是使用外键约束 __table_args__ = ( Index('idx_task_input_params_instance_id', 'instance_id'), {'mysql_engine': 'InnoDB'} ) # 关联关系 - 使用foreign()显式标记外键 instance = relationship( "TaskInstance", primaryjoin="and_(TaskInputParam.instance_id==foreign(TaskInstance.instance_id), " "TaskInstance.is_deleted==False)", foreign_keys=[instance_id], back_populates="input_params", viewonly=True ) def __init__(self, **kwargs): """初始化实例,自动生成param_id""" if 'param_id' not in kwargs: kwargs['param_id'] = str(uuid.uuid4()) # 处理default_value参数 if 'default_value' in kwargs: self.default_value = kwargs.pop('default_value') super(TaskInputParam, self).__init__(**kwargs) @property def default_value(self): """获取默认值""" if self._default_value is None: return None try: return json.loads(self._default_value) except (json.JSONDecodeError, TypeError): return self._default_value @default_value.setter def default_value(self, value): """设置默认值""" if value is None: self._default_value = None return if isinstance(value, (str, int, float, bool)): # 基本类型直接转为JSON字符串 self._default_value = json.dumps(value) elif isinstance(value, (list, dict)): # 复杂类型先验证是否可序列化,然后转为JSON字符串 try: self._default_value = json.dumps(value) except: self._default_value = None else: # 其他类型尝试序列化,失败则设为None try: self._default_value = json.dumps(value) except: self._default_value = None def to_dict(self): """转换为字典""" return { "id": self.param_id, # 使用param_id作为对外ID "param_id": self.param_id, "instance_id": self.instance_id, "task_id": self.task_id, "param_name": self.param_name, "label": self.label, "param_type": self.param_type, "required": self.required, "default_value": self.default_value, "description": self.description, "is_system": self.is_system, "is_readonly": self.is_readonly, "sort_order": self.sort_order, "created_at": int(self.created_at.timestamp() * 1000) if self.created_at else None, "updated_at": int(self.updated_at.timestamp() * 1000) if self.updated_at else None, "is_deleted": self.is_deleted }