from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from database import get_db from models.notification import Notification from models.user import User from schemas.notification import NotificationOut from services.auth import get_current_user router = APIRouter(prefix="/api/notifications", tags=["通知"]) def push_notification( db: Session, user_id: int, actor_id: Optional[int], ntype: str, title: str, content: str = "", link: str = "", ) -> None: """创建一条通知,不通知自己。""" if actor_id and actor_id == user_id: return db.add(Notification( user_id=user_id, actor_id=actor_id, ntype=ntype, title=title, content=content, link=link, is_read=False, )) @router.get("", response_model=list[NotificationOut]) def list_notifications( skip: int = Query(0, ge=0), limit: int = Query(20, ge=1, le=100), unread_only: bool = Query(False), current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): query = db.query(Notification).filter(Notification.user_id == current_user.id) if unread_only: query = query.filter(Notification.is_read == False) return query.order_by(Notification.created_at.desc()).offset(skip).limit(limit).all() @router.get("/unread-count") def unread_count( current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): count = db.query(Notification).filter( Notification.user_id == current_user.id, Notification.is_read == False, ).count() return {"count": count} @router.put("/{notification_id}/read", response_model=dict) def mark_read( notification_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): item = db.query(Notification).filter( Notification.id == notification_id, Notification.user_id == current_user.id, ).first() if not item: raise HTTPException(status_code=404, detail="通知不存在") item.is_read = True db.commit() return {"success": True} @router.put("/read-all", response_model=dict) def mark_all_read( current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): db.query(Notification).filter( Notification.user_id == current_user.id, Notification.is_read == False, ).update({"is_read": True}, synchronize_session=False) db.commit() return {"success": True} @router.delete("/{notification_id}", status_code=204) def delete_notification( notification_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): item = db.query(Notification).filter( Notification.id == notification_id, Notification.user_id == current_user.id, ).first() if not item: raise HTTPException(status_code=404, detail="通知不存在") db.delete(item) db.commit() return None