Files
opsxsql/backend/app/api/v1/endpoints/announcement.py
T
logan bab55d3927 feat: 审核规则模版+设置页面整合+去掉角色切换demo
后端:
- AuditRule 新增 value 字段, rule_type 扩展 DDL/DML
- MySQL/PG/Redis 预设规则种子接口 POST /audit-rules/seed/{db_type}
- 公告管理 CRUD (announcements)
- 消息推送 CRUD+测试 (notifications: 钉钉/飞书/邮件)
- LDAP 配置 CRUD+测试连接 (ldap-config)
- 164 tests passing (+31 新增)

前端:
- AuditRulesPage 重写: DB类型Tab+DDL/DML分组+参数编辑
- SettingsPage: 系统设置主页(审核规则/公告/推送/LDAP)
- NotificationPage: 钉钉/飞书/SMTP配置
- LdapConfigPage: LDAP设置+测试连接
- AnnouncementPage: 公告Markdown编辑
- 去掉左下角角色切换demo
- 侧边栏合并为: 系统设置(含审核规则+公告+推送+LDAP)
2026-05-22 22:26:10 +08:00

94 lines
2.9 KiB
Python

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": "公告已删除"}