#!/usr/bin/env python3 """发布管理 API""" from fastapi import APIRouter, HTTPException, Depends, Request from pydantic import BaseModel from datetime import datetime from typing import Optional from app.database import get_db from app.models import Topic, PublishRecord, User from sqlalchemy.orm import Session from .auth import verify_token from ..core.audit_logger import audit_log router = APIRouter() class PublishRequest(BaseModel): topic_id: str class PublishResponse(BaseModel): ok: bool topic_id: str message: str def get_current_user(request: Request, db: Session = Depends(get_db)) -> User: """获取当前登录用户(可选,未登录也允许,但记录为 anonymous)""" auth_header = request.headers.get("Authorization") if not auth_header or not auth_header.startswith("Bearer "): return None token = auth_header.split(" ")[1] try: from .auth import verify_token return verify_token(token, db) except Exception: return None @router.post("/api/publishing/create", response_model=PublishResponse) async def create_publish_record( req: PublishRequest, request: Request, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """标记选题为已发布,并创建发布记录""" try: # 查找选题 topic = db.query(Topic).filter(Topic.id == req.topic_id).first() if not topic: raise HTTPException(status_code=404, detail=f"选题 {req.topic_id} 不存在") if topic.status != '待发布': raise HTTPException(status_code=400, detail=f"选题 {req.topic_id} 状态不是待发布") # 更新选题状态 topic.status = '已发布' topic.updated_at = datetime.now() topic.published_at = datetime.now().date() # 设置发布时间为今天 # 创建发布记录 operator = current_user.username if current_user else 'anonymous' record = PublishRecord( topic_id=req.topic_id, platform='all', action='publish', status='success', operator=operator, description=f"选题 {req.topic_id} 已发布" ) db.add(record) db.commit() # 强制刷新会话缓存,确保后续读取最新数据 db.expire_all() db.refresh(topic) # 审计日志 audit_log( action="publish", user=current_user, resource_type="topic", resource_id=req.topic_id, details={"operator": operator, "status": "success"}, ip_address=request.client.host if request.client else None, user_agent=request.headers.get("user-agent", ""), db=db ) return PublishResponse( ok=True, topic_id=req.topic_id, message=f"选题 {req.topic_id} 已成功发布" ) except HTTPException: raise except Exception as e: db.rollback() raise HTTPException(status_code=500, detail=str(e))