97 lines
3.4 KiB
Python
97 lines
3.4 KiB
Python
#!/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"<Notification {self.notification_uuid}: {self.title}>"
|
||
|
||
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}" # 連結到任務詳情頁
|
||
) |