233e23016c
- 文章 HTML 存储从文件系统迁移至 articles 表,删除 releases 目录 - 合规审查从 DB 读取 HTML,审查结果写回 DB,通过后自动推进至待发布 - 新增 todayCount 筛选按钮,与系统概览统计数据一致 - 全屏预览修复:提升 z-index 超过侧边栏,添加退出全屏/关闭按钮 - 统一 '优化' → '审查' 命名,消除前后端术语不一致 - 调度器创作完成后自动触发审查(生成 → 审查 → 待发布) - 清理旧备份/调试文件、过期大纲和研究笔记
191 lines
5.9 KiB
Python
191 lines
5.9 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, Query
|
|
from sqlalchemy.orm import Session
|
|
from typing import List, Optional
|
|
from datetime import datetime, date
|
|
from calendar import monthrange
|
|
|
|
from ..database import get_db
|
|
from ..models import ContentCalendar, Topic
|
|
from ..schemas import (
|
|
ContentCalendarCreate, ContentCalendarUpdate, ContentCalendarResponse,
|
|
ContentCalendarBase
|
|
)
|
|
from .auth import get_current_user
|
|
|
|
router = APIRouter(prefix="/api/calendar", tags=["calendar"])
|
|
|
|
|
|
@router.get("", response_model=List[ContentCalendarResponse])
|
|
def get_calendar(
|
|
year: Optional[int] = Query(None),
|
|
month: Optional[int] = Query(None),
|
|
db: Session = Depends(get_db),
|
|
current_user=Depends(get_current_user)
|
|
):
|
|
today = date.today()
|
|
year = year or today.year
|
|
month = month or today.month
|
|
start = date(year, month, 1)
|
|
last_day = monthrange(year, month)[1]
|
|
end = date(year, month, last_day)
|
|
return db.query(ContentCalendar).filter(
|
|
ContentCalendar.planned_date >= start,
|
|
ContentCalendar.planned_date <= end
|
|
).order_by(ContentCalendar.planned_date).all()
|
|
|
|
|
|
@router.get("/entries", response_model=List[ContentCalendarResponse])
|
|
def list_entries(
|
|
start_date: Optional[date] = None,
|
|
end_date: Optional[date] = None,
|
|
status: Optional[str] = None,
|
|
platform: Optional[str] = None,
|
|
limit: int = Query(50, le=200),
|
|
db: Session = Depends(get_db),
|
|
current_user=Depends(get_current_user)
|
|
):
|
|
query = db.query(ContentCalendar)
|
|
if start_date:
|
|
query = query.filter(ContentCalendar.planned_date >= start_date)
|
|
if end_date:
|
|
query = query.filter(ContentCalendar.planned_date <= end_date)
|
|
if status:
|
|
query = query.filter(ContentCalendar.status == status)
|
|
if platform:
|
|
query = query.filter(ContentCalendar.platform == platform)
|
|
return query.order_by(ContentCalendar.planned_date.desc()).limit(limit).all()
|
|
|
|
|
|
@router.post("/entries", response_model=ContentCalendarResponse)
|
|
def create_entry(
|
|
data: ContentCalendarCreate,
|
|
db: Session = Depends(get_db),
|
|
current_user=Depends(get_current_user)
|
|
):
|
|
if data.topic_id:
|
|
topic = db.query(Topic).filter(Topic.id == data.topic_id).first()
|
|
if not topic:
|
|
raise HTTPException(status_code=404, detail="选题不存在")
|
|
|
|
entry = ContentCalendar(**data.model_dump())
|
|
db.add(entry)
|
|
db.commit()
|
|
db.refresh(entry)
|
|
|
|
if data.topic_id and data.title:
|
|
if not topic.title or topic.title != data.title:
|
|
topic.title = data.title
|
|
db.commit()
|
|
return entry
|
|
|
|
|
|
@router.put("/entries/{entry_id}", response_model=ContentCalendarResponse)
|
|
def update_entry(
|
|
entry_id: int,
|
|
data: ContentCalendarUpdate,
|
|
db: Session = Depends(get_db),
|
|
current_user=Depends(get_current_user)
|
|
):
|
|
entry = db.query(ContentCalendar).filter(ContentCalendar.id == entry_id).first()
|
|
if not entry:
|
|
raise HTTPException(status_code=404, detail="日历条目不存在")
|
|
|
|
for k, v in data.model_dump(exclude_unset=True).items():
|
|
setattr(entry, k, v)
|
|
db.commit()
|
|
db.refresh(entry)
|
|
|
|
if entry.topic_id:
|
|
topic = db.query(Topic).filter(Topic.id == entry.topic_id).first()
|
|
if topic and entry.status == "published" and not entry.published_date:
|
|
entry.published_date = date.today()
|
|
if topic.status == "pending" or topic.status == "ready":
|
|
topic.status = "published"
|
|
topic.published_at = date.today()
|
|
topic.updated_at = datetime.now()
|
|
db.commit()
|
|
|
|
return entry
|
|
|
|
|
|
@router.delete("/entries/{entry_id}")
|
|
def delete_entry(
|
|
entry_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_user=Depends(get_current_user)
|
|
):
|
|
entry = db.query(ContentCalendar).filter(ContentCalendar.id == entry_id).first()
|
|
if not entry:
|
|
raise HTTPException(status_code=404, detail="日历条目不存在")
|
|
db.delete(entry)
|
|
db.commit()
|
|
return {"ok": True}
|
|
|
|
|
|
@router.post("/entries/bind-topic")
|
|
def bind_topic_to_entry(
|
|
entry_id: int,
|
|
topic_id: str,
|
|
db: Session = Depends(get_db),
|
|
current_user=Depends(get_current_user)
|
|
):
|
|
entry = db.query(ContentCalendar).filter(ContentCalendar.id == entry_id).first()
|
|
if not entry:
|
|
raise HTTPException(status_code=404, detail="日历条目不存在")
|
|
topic = db.query(Topic).filter(Topic.id == topic_id).first()
|
|
if not topic:
|
|
raise HTTPException(status_code=404, detail="选题不存在")
|
|
entry.topic_id = topic_id
|
|
entry.title = topic.title
|
|
if topic.field_name:
|
|
entry.field_id = topic.field_id
|
|
db.commit()
|
|
db.refresh(entry)
|
|
return entry
|
|
|
|
|
|
@router.get("/stats")
|
|
def calendar_stats(
|
|
year: int = Query(...),
|
|
month: int = Query(...),
|
|
db: Session = Depends(get_db),
|
|
current_user=Depends(get_current_user)
|
|
):
|
|
start = date(year, month, 1)
|
|
last_day = monthrange(year, month)[1]
|
|
end = date(year, month, last_day)
|
|
entries = db.query(ContentCalendar).filter(
|
|
ContentCalendar.planned_date >= start,
|
|
ContentCalendar.planned_date <= end
|
|
).all()
|
|
|
|
stats = {"total": len(entries), "planned": 0, "published": 0, "delayed": 0, "cancelled": 0}
|
|
for e in entries:
|
|
if e.status in stats:
|
|
stats[e.status] += 1
|
|
return stats
|
|
|
|
|
|
@router.post("/entries/from-topic")
|
|
def create_from_topic(
|
|
topic_id: str,
|
|
planned_date: date,
|
|
platform: str = Query(...),
|
|
db: Session = Depends(get_db),
|
|
current_user=Depends(get_current_user)
|
|
):
|
|
topic = db.query(Topic).filter(Topic.id == topic_id).first()
|
|
if not topic:
|
|
raise HTTPException(status_code=404, detail="选题不存在")
|
|
entry = ContentCalendar(
|
|
topic_id=topic_id,
|
|
field_id=topic.field_id,
|
|
title=topic.title,
|
|
planned_date=planned_date,
|
|
platform=platform,
|
|
created_by=current_user.username
|
|
)
|
|
db.add(entry)
|
|
db.commit()
|
|
db.refresh(entry)
|
|
return entry |