145 lines
4.4 KiB
Python
145 lines
4.4 KiB
Python
"""
|
|
通知管理 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="系统通知发送成功")
|