""" 通知管理 API """ from fastapi import APIRouter, Depends, HTTPException, Request from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, update, func, desc from typing import List, Optional from datetime import datetime from app.core.database import get_db from app.core.deps import get_current_user from app.models.user import User from app.models.notification import Notification from app.schemas.notification import ( NotificationResponse, NotificationUpdate, UnreadCountResponse, NotificationCreate ) from app.schemas.response import success_response from app.services.notification_service import notification_service router = APIRouter() @router.get("/", response_model=dict) async def get_notifications( page: int = 1, page_size: int = 20, unread_only: bool = False, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ): """获取当前用户的通知列表""" query = select(Notification).where(Notification.user_id == current_user.id) if unread_only: query = query.where(Notification.is_read == 0) query = query.order_by(desc(Notification.created_at)) # 分页 offset = (page - 1) * page_size query = query.offset(offset).limit(page_size) result = await db.execute(query) notifications = result.scalars().all() # 获取总数 count_query = select(func.count()).select_from(Notification).where(Notification.user_id == current_user.id) if unread_only: count_query = count_query.where(Notification.is_read == 0) total_result = await db.execute(count_query) total = total_result.scalar() data = [NotificationResponse.from_orm(n).dict() for n in notifications] return { "code": 200, "message": "success", "data": data, "total": total, "page": page, "page_size": page_size } @router.get("/unread-count", response_model=dict) async def get_unread_count( current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ): """获取未读通知数量""" result = await db.execute( select(func.count()).select_from(Notification).where( Notification.user_id == current_user.id, Notification.is_read == 0 ) ) count = result.scalar() return success_response(data={"unread_count": count}) @router.put("/{notification_id}/read", response_model=dict) async def mark_as_read( notification_id: int, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ): """标记单条通知为已读""" result = await db.execute( select(Notification).where( Notification.id == notification_id, Notification.user_id == current_user.id ) ) notification = result.scalar_one_or_none() if not notification: raise HTTPException(status_code=404, detail="通知不存在") if notification.is_read == 0: notification.is_read = 1 notification.read_at = datetime.now() await db.commit() return success_response(message="已标记为已读") @router.put("/read-all", response_model=dict) async def mark_all_as_read( current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ): """标记所有通知为已读""" await db.execute( update(Notification) .where(Notification.user_id == current_user.id, Notification.is_read == 0) .values(is_read=1, read_at=datetime.now()) ) await db.commit() return success_response(message="全部标记为已读") @router.post("/system", response_model=dict) async def send_system_notification( notification_in: NotificationCreate, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ): """发送系统通知(仅限超级管理员)""" if not current_user.is_superuser: raise HTTPException(status_code=403, detail="只有管理员可以发送系统通知") await notification_service.create_notification( db=db, user_id=notification_in.user_id, title=notification_in.title, content=notification_in.content, type=notification_in.type, category="system", link=notification_in.link ) await db.commit() return success_response(message="系统通知发送成功")