from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from sqlalchemy import and_, desc, asc, func from pydantic import BaseModel, Field from typing import Optional import uuid from datetime import datetime from ..database import get_db from ..models import ( User, Notification, gen_uuid ) from ..auth import get_current_user from ..middleware.log_service import LogService router = APIRouter() @router.get("/") def list_notifications( type: Optional[str] = Query(None, description="通知类型"), is_read: Optional[bool] = Query(None), page: int = Query(default=1, ge=1), page_size: int = Query(default=20, ge=1, le=100), db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): query = db.query(Notification).filter( Notification.user_id == current_user.id ) if type: query = query.filter(Notification.type == type) if is_read is not None: query = query.filter(Notification.is_read == is_read) total = query.count() notifications = ( query.order_by(desc(Notification.created_at)) .offset((page - 1) * page_size) .limit(page_size) .all() ) result = [] for n in notifications: result.append({ "id": n.id, "type": n.type, "title": n.title, "content": n.content, "is_read": n.is_read, "related_id": n.related_id, "related_type": n.related_type, "created_at": str(n.created_at) if n.created_at else None, }) return { "code": 0, "data": { "total": total, "page": page, "page_size": page_size, "items": result, }, "message": "ok", } @router.put("/{notification_id}/read") def mark_as_read( notification_id: str, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): notification = db.query(Notification).filter( and_( Notification.id == notification_id, Notification.user_id == current_user.id, ) ).first() if not notification: raise HTTPException(status_code=404, detail="通知不存在") notification.is_read = True notification.read_at = datetime.now() db.commit() return {"code": 0, "message": "已标记为已读"} @router.put("/read-all") def mark_all_as_read( type: Optional[str] = Query(None), db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): query = db.query(Notification).filter( and_( Notification.user_id == current_user.id, Notification.is_read == False, ) ) if type: query = query.filter(Notification.type == type) notifications = query.all() now = datetime.now() count = 0 for n in notifications: n.is_read = True n.read_at = now count += 1 db.commit() return {"code": 0, "data": {"count": count}, "message": f"已标记 {count} 条为已读"} @router.get("/unread-count") def get_unread_count( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): count = db.query(func.count(Notification.id)).filter( and_( Notification.user_id == current_user.id, Notification.is_read == False, ) ).scalar() or 0 return {"code": 0, "data": {"count": count}, "message": "ok"}