diff --git a/app/models.py b/app/models.py index 820ad87..93a833a 100644 --- a/app/models.py +++ b/app/models.py @@ -368,6 +368,138 @@ class AlarmLlmAnalysis(Base): } +# ==================== 工单体系 ==================== + +class SecurityUser(Base): + """安保人员表""" + __tablename__ = "security_user" + + id = Column(Integer, primary_key=True, autoincrement=True) + user_id = Column(String(64), unique=True, nullable=False, index=True, comment="人员唯一ID") + name = Column(String(100), nullable=False, comment="姓名") + phone = Column(String(20), nullable=True, comment="手机号") + wechat_uid = Column(String(100), nullable=True, comment="企微userid") + role = Column(String(50), default="guard", comment="角色: guard/supervisor/manager") + team_id = Column(String(64), nullable=True, index=True, comment="班组ID") + status = Column(String(20), default="active", comment="状态: active/inactive") + created_at = Column(DateTime, default=lambda: beijing_now()) + updated_at = Column(DateTime, default=lambda: beijing_now(), + onupdate=lambda: beijing_now()) + + def to_dict(self) -> dict: + fmt = '%Y-%m-%d %H:%M:%S' + return { + "id": self.id, + "user_id": self.user_id, + "name": self.name, + "phone": self.phone, + "wechat_uid": self.wechat_uid, + "role": self.role, + "team_id": self.team_id, + "status": self.status, + "created_at": self.created_at.strftime(fmt) if self.created_at else None, + "updated_at": self.updated_at.strftime(fmt) if self.updated_at else None, + } + + +class SecurityWorkOrder(Base): + """安保工单表""" + __tablename__ = "security_work_order" + + order_id = Column(String(64), primary_key=True, comment="工单ID: WO + 时间戳 + uuid") + + # 来源告警(告警工单必填,手动工单可空) + alarm_id = Column(String(64), nullable=True, unique=True, comment="关联 alarm_event.alarm_id") + + # 工单内容 + title = Column(String(200), nullable=False, comment="工单标题") + description = Column(Text, nullable=True, comment="工单描述") + priority = Column(SmallInteger, default=2, comment="优先级: 1低 2中 3高 4紧急") + + # 设备/区域信息(冗余,方便查询和责任追溯) + camera_id = Column(String(64), nullable=True, comment="摄像头ID") + roi_id = Column(String(64), nullable=True, comment="ROI区域ID") + alarm_type = Column(String(50), nullable=True, comment="告警类型") + image_url = Column(String(512), nullable=True, comment="截图URL") + + # 派发信息(写入时确定,不依赖实时查询,确保责任可追溯) + assigned_user_id = Column(String(64), nullable=True, index=True, comment="处理人user_id") + assigned_user_name = Column(String(100), nullable=True, comment="处理人姓名") + assigned_team_id = Column(String(64), nullable=True, comment="班组ID") + + # 状态: PENDING / DISPATCHED / PROCESSING / DONE / CLOSED + status = Column(String(20), default="PENDING", nullable=False, index=True, comment="工单状态") + + # 处理结果 + result = Column(Text, nullable=True, comment="处理结果描述") + + # 创建人 + created_by = Column(String(64), nullable=True, comment="创建人") + + # 时间 + created_at = Column(DateTime, default=lambda: beijing_now()) + updated_at = Column(DateTime, default=lambda: beijing_now(), + onupdate=lambda: beijing_now()) + dispatch_time = Column(DateTime, nullable=True, comment="派单时间") + finish_time = Column(DateTime, nullable=True, comment="完成时间") + + __table_args__ = ( + Index('idx_swo_status', 'status'), + Index('idx_swo_assigned', 'assigned_user_id'), + Index('idx_swo_created_at', 'created_at'), + Index('idx_swo_camera_roi_type', 'camera_id', 'roi_id', 'alarm_type'), + ) + + def to_dict(self) -> dict: + fmt = '%Y-%m-%d %H:%M:%S' + return { + "order_id": self.order_id, + "alarm_id": self.alarm_id, + "title": self.title, + "description": self.description, + "priority": self.priority, + "camera_id": self.camera_id, + "roi_id": self.roi_id, + "alarm_type": self.alarm_type, + "image_url": self.image_url, + "assigned_user_id": self.assigned_user_id, + "assigned_user_name": self.assigned_user_name, + "assigned_team_id": self.assigned_team_id, + "status": self.status, + "result": self.result, + "created_by": self.created_by, + "created_at": self.created_at.strftime(fmt) if self.created_at else None, + "updated_at": self.updated_at.strftime(fmt) if self.updated_at else None, + "dispatch_time": self.dispatch_time.strftime(fmt) if self.dispatch_time else None, + "finish_time": self.finish_time.strftime(fmt) if self.finish_time else None, + } + + +class WorkOrderLog(Base): + """工单操作记录表""" + __tablename__ = "work_order_log" + + id = Column(Integer, primary_key=True, autoincrement=True) + order_id = Column(String(64), nullable=False, index=True, comment="关联工单ID") + action = Column(String(50), nullable=False, + comment="操作: CREATE/DISPATCH/ACCEPT/FINISH/CLOSE") + operator_id = Column(String(64), nullable=True, comment="操作人ID") + operator_name = Column(String(100), nullable=True, comment="操作人姓名") + remark = Column(Text, nullable=True, comment="备注") + created_at = Column(DateTime, default=lambda: beijing_now()) + + def to_dict(self) -> dict: + return { + "id": self.id, + "order_id": self.order_id, + "action": self.action, + "operator_id": self.operator_id, + "operator_name": self.operator_name, + "remark": self.remark, + "created_at": self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None, + } + + # ==================== 数据库管理 ==================== _engine = None