from datetime import datetime, timezone from typing import List from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.core.database import get_db from app.core.security import get_current_user, require_role from app.models.user import User from app.models.announcement import Announcement from app.schemas.announcement import ( AnnouncementCreate, AnnouncementUpdate, AnnouncementResponse, ) router = APIRouter(prefix="/announcements", tags=["公告管理"]) @router.get("", response_model=List[AnnouncementResponse]) async def list_announcements( db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ): """所有登录用户可查看公告列表""" stmt = select(Announcement).order_by(Announcement.id.desc()) result = await db.execute(stmt) return result.scalars().all() @router.post("", response_model=AnnouncementResponse, status_code=201) async def create_announcement( data: AnnouncementCreate, db: AsyncSession = Depends(get_db), current_user: User = Depends(require_role("admin")), ): """管理员创建公告""" announcement = Announcement( title=data.title, content=data.content, is_published=False, ) db.add(announcement) await db.commit() await db.refresh(announcement) return announcement @router.put("/{announcement_id}", response_model=AnnouncementResponse) async def update_announcement( announcement_id: int, data: AnnouncementUpdate, db: AsyncSession = Depends(get_db), current_user: User = Depends(require_role("admin")), ): """管理员更新公告""" result = await db.execute( select(Announcement).where(Announcement.id == announcement_id) ) announcement = result.scalar_one_or_none() if not announcement: raise HTTPException(status_code=404, detail="公告不存在") update_data = data.model_dump(exclude_unset=True) # If publishing for the first time, set published_at if update_data.get("is_published") and not announcement.published_at: announcement.published_at = datetime.now(timezone.utc) for key, value in update_data.items(): setattr(announcement, key, value) await db.commit() await db.refresh(announcement) return announcement @router.delete("/{announcement_id}") async def delete_announcement( announcement_id: int, db: AsyncSession = Depends(get_db), current_user: User = Depends(require_role("admin")), ): """管理员删除公告""" result = await db.execute( select(Announcement).where(Announcement.id == announcement_id) ) announcement = result.scalar_one_or_none() if not announcement: raise HTTPException(status_code=404, detail="公告不存在") await db.delete(announcement) await db.commit() return {"message": "公告已删除"}