"""通知服务 — 创建与查询系统通知""" from __future__ import annotations import logging from datetime import datetime from typing import List, Optional from sqlalchemy.orm import Session from app.models.notification import Notification logger = logging.getLogger(__name__) def create_notification( db: Session, user_id: str, title: str, content: Optional[str] = None, category: str = "system", ref_type: Optional[str] = None, ref_id: Optional[str] = None, ) -> Notification: """创建一条通知。 Args: db: 数据库会话 user_id: 接收用户 ID title: 通知标题 content: 通知正文(可选) category: 分类,如 schedule / alert / system ref_type: 关联对象类型 ref_id: 关联对象 ID Returns: 创建的 Notification ORM 对象 """ notification = Notification( user_id=user_id, title=title, content=content, category=category, ref_type=ref_type, ref_id=ref_id, ) db.add(notification) db.flush() logger.info("通知已创建: user=%s title=%s category=%s", user_id, title, category) return notification def get_user_notifications( db: Session, user_id: str, unread_only: bool = False, category: Optional[str] = None, limit: int = 50, offset: int = 0, ) -> List[Notification]: """获取用户的通知列表(按创建时间倒序)。 Args: db: 数据库会话 user_id: 用户 ID unread_only: 仅未读 category: 按分类过滤 limit: 分页大小 offset: 分页偏移 Returns: 通知列表 """ query = db.query(Notification).filter(Notification.user_id == user_id) if unread_only: query = query.filter(Notification.is_read == False) # noqa: E712 if category: query = query.filter(Notification.category == category) return query.order_by(Notification.created_at.desc()).offset(offset).limit(limit).all() def get_unread_count(db: Session, user_id: str) -> int: """获取用户未读通知数。""" return ( db.query(Notification) .filter(Notification.user_id == user_id, Notification.is_read == False) # noqa: E712 .count() ) def mark_as_read(db: Session, notification_id: str, user_id: str) -> Optional[Notification]: """将指定通知标记为已读。""" notification = ( db.query(Notification) .filter(Notification.id == notification_id, Notification.user_id == user_id) .first() ) if not notification: return None notification.is_read = True db.flush() return notification def mark_all_as_read(db: Session, user_id: str) -> int: """将用户所有通知标记为已读。返回更新的条数。""" count = ( db.query(Notification) .filter(Notification.user_id == user_id, Notification.is_read == False) # noqa: E712 .update({"is_read": True}) ) db.flush() return count def delete_notification(db: Session, notification_id: str, user_id: str) -> bool: """删除一条通知。""" notification = ( db.query(Notification) .filter(Notification.id == notification_id, Notification.user_id == user_id) .first() ) if not notification: return False db.delete(notification) db.flush() return True