"""通知 API — 列表、已读、删除""" from __future__ import annotations import logging from datetime import datetime from typing import List, Optional from fastapi import APIRouter, Depends, HTTPException, Query from pydantic import BaseModel from sqlalchemy.orm import Session from app.api.auth import get_current_user from app.core.database import get_db from app.models.user import User from app.services.notification_service import ( delete_notification, get_unread_count, get_user_notifications, mark_all_as_read, mark_as_read, ) logger = logging.getLogger(__name__) router = APIRouter(prefix="/api/v1/notifications", tags=["notifications"]) # ─── Pydantic Schemas ────────────────────────────────────────────── class NotificationResponse(BaseModel): id: str user_id: str title: str content: Optional[str] = None category: str ref_type: Optional[str] = None ref_id: Optional[str] = None is_read: bool created_at: datetime class Config: from_attributes = True class UnreadCountResponse(BaseModel): count: int # ─── API Endpoints ───────────────────────────────────────────────── @router.get("", response_model=List[NotificationResponse]) async def list_notifications( unread_only: bool = Query(False, description="仅未读"), category: Optional[str] = Query(None, description="按分类过滤"), limit: int = Query(50, ge=1, le=200), offset: int = Query(0, ge=0), current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """获取当前用户的通知列表。""" return get_user_notifications( db, user_id=current_user.id, unread_only=unread_only, category=category, limit=limit, offset=offset, ) @router.get("/unread-count", response_model=UnreadCountResponse) async def unread_count( current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """获取当前用户的未读通知数。""" count = get_unread_count(db, current_user.id) return {"count": count} @router.put("/{notification_id}/read") async def read_notification( notification_id: str, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """将一条通知标记为已读。""" result = mark_as_read(db, notification_id, current_user.id) if not result: raise HTTPException(status_code=404, detail="通知不存在") return {"message": "已标记为已读"} @router.put("/read-all") async def read_all_notifications( current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """将所有通知标记为已读。""" count = mark_all_as_read(db, current_user.id) return {"message": f"已将 {count} 条通知标记为已读"} @router.delete("/{notification_id}") async def remove_notification( notification_id: str, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): """删除一条通知。""" ok = delete_notification(db, notification_id, current_user.id) if not ok: raise HTTPException(status_code=404, detail="通知不存在") return {"message": "通知已删除"}