#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 通知系統資料模型 Author: PANJIT IT Team Created: 2024-01-28 Modified: 2024-01-28 """ from datetime import datetime from enum import Enum from sqlalchemy import func from sqlalchemy.orm import relationship from app import db import uuid import json class NotificationType(str, Enum): """通知類型枚舉""" SUCCESS = "success" # 成功 ERROR = "error" # 錯誤 WARNING = "warning" # 警告 INFO = "info" # 資訊 SYSTEM = "system" # 系統 class Notification(db.Model): """通知模型""" __tablename__ = 'dt_notifications' # 主鍵 id = db.Column(db.Integer, primary_key=True, autoincrement=True) notification_uuid = db.Column(db.String(36), unique=True, nullable=False, index=True, default=lambda: str(uuid.uuid4()), comment='通知唯一識別碼') # 基本資訊 user_id = db.Column(db.Integer, db.ForeignKey('dt_users.id'), nullable=False, comment='使用者ID') type = db.Column(db.String(20), nullable=False, default=NotificationType.INFO.value, comment='通知類型') title = db.Column(db.String(255), nullable=False, comment='通知標題') message = db.Column(db.Text, nullable=False, comment='通知內容') # 關聯資訊(可選) job_uuid = db.Column(db.String(36), nullable=True, comment='關聯任務UUID') link = db.Column(db.String(500), nullable=True, comment='相關連結') # 狀態 is_read = db.Column(db.Boolean, default=False, nullable=False, comment='是否已讀') read_at = db.Column(db.DateTime, nullable=True, comment='閱讀時間') # 時間戳記 created_at = db.Column(db.DateTime, default=func.now(), nullable=False, comment='建立時間') expires_at = db.Column(db.DateTime, nullable=True, comment='過期時間') # 額外數據(JSON 格式儲存) extra_data = db.Column(db.JSON, nullable=True, comment='額外數據') # 關聯 user = db.relationship("User", backref="notifications") def __repr__(self): return f"" def to_dict(self): """轉換為字典格式""" return { 'id': self.notification_uuid, # 前端使用 UUID 'user_id': self.user_id, 'type': self.type, 'title': self.title, 'message': self.message, 'job_uuid': self.job_uuid, 'link': self.link, 'is_read': self.is_read, 'read': self.is_read, # 為了前端相容 'read_at': self.read_at.isoformat() if self.read_at else None, 'created_at': self.created_at.isoformat() if self.created_at else None, 'expires_at': self.expires_at.isoformat() if self.expires_at else None, 'extra_data': self.extra_data } def mark_as_read(self): """標記為已讀""" self.is_read = True self.read_at = datetime.now() @classmethod def create_job_notification(cls, user_id, job_uuid, title, message, notification_type=NotificationType.INFO): """創建任務相關通知""" return cls( user_id=user_id, job_uuid=job_uuid, type=notification_type.value, title=title, message=message, link=f"/job/{job_uuid}" # 連結到任務詳情頁 )