Files
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

185 lines
6.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# app/routers/home_experts.py
# 已迁移到新栏目体系(columns/articles),post_id 语义现在指向 Article.id
from typing import List, Union, Optional
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from sqlalchemy.orm import Session
from app.database import get_db
from app.models.home_expert import HomeExpert
from app.models.article import Article
from app.models.admin import Admin
from app.auth import get_current_admin
router = APIRouter()
# Schemas
class HomeExpertCreate(BaseModel):
post_id: int # 语义:article.id
sort_order: int = 0
is_enabled: bool = True
class HomeExpertUpdate(BaseModel):
post_id: Optional[int] = None
sort_order: Optional[int] = None
is_enabled: Optional[bool] = None
class HomeExpertResponse(BaseModel):
code: int = 200
data: Union[dict, list] = None
message: str = "success"
# Helper
def expert_to_dict(expert: HomeExpert, article: Article = None) -> dict:
"""转换为字典。保持对外字段名 `post` 不变,避免破坏前端展示。"""
result = {
"id": expert.id,
"post_id": expert.post_id,
"sort_order": expert.sort_order,
"is_enabled": expert.is_enabled,
}
if article:
result["post"] = {
"id": article.id,
"title": article.title,
"slug": article.slug,
"summary": article.summary,
"cover_image": article.cover_image,
"column_id": article.column_id,
# 兼容老字段名
"category_id": article.column_id,
}
return result
# Public routes
@router.get("/home-experts", response_model=HomeExpertResponse)
def get_public_experts(
limit: int = 6,
db: Session = Depends(get_db)
):
"""访客端:获取启用的专家团队(关联已发布的文章)"""
experts = db.query(HomeExpert).filter(
HomeExpert.is_enabled == True
).order_by(HomeExpert.sort_order.asc()).limit(limit).all()
result = []
for expert in experts:
article = db.query(Article).filter(
Article.id == expert.post_id,
Article.status == "published"
).first()
if article:
result.append(expert_to_dict(expert, article))
return HomeExpertResponse(data=result)
# Admin routes
@router.get("/admin/home-experts", response_model=HomeExpertResponse)
def get_admin_experts(
db: Session = Depends(get_db),
current_admin: Admin = Depends(get_current_admin)
):
"""后台:获取所有专家团队(含文章信息)"""
experts = db.query(HomeExpert).order_by(HomeExpert.sort_order.asc()).all()
result = []
for expert in experts:
article = db.query(Article).filter(Article.id == expert.post_id).first()
result.append(expert_to_dict(expert, article))
return HomeExpertResponse(data=result)
@router.get("/admin/home-experts/available-posts", response_model=HomeExpertResponse)
def get_available_posts(
keyword: Optional[str] = None,
db: Session = Depends(get_db),
current_admin: Admin = Depends(get_current_admin)
):
"""后台:获取可选的已发布文章列表(供挑选作为专家)"""
query = db.query(Article).filter(Article.status == "published")
if keyword:
query = query.filter(Article.title.contains(keyword))
articles = query.order_by(Article.created_at.desc()).limit(50).all()
return HomeExpertResponse(data=[
{
"id": a.id,
"title": a.title,
"slug": a.slug,
"summary": a.summary,
"cover_image": a.cover_image,
"column_id": a.column_id,
"created_at": a.created_at.isoformat() if a.created_at else None,
}
for a in articles
])
@router.post("/admin/home-experts", response_model=HomeExpertResponse)
def create_expert(
request: HomeExpertCreate,
db: Session = Depends(get_db),
current_admin: Admin = Depends(get_current_admin)
):
"""添加一篇文章为专家团队成员"""
article = db.query(Article).filter(Article.id == request.post_id).first()
if not article:
raise HTTPException(status_code=404, detail="资讯不存在")
existing = db.query(HomeExpert).filter(HomeExpert.post_id == request.post_id).first()
if existing:
raise HTTPException(status_code=400, detail="该资讯已添加到专家团队")
expert = HomeExpert(
post_id=request.post_id,
sort_order=request.sort_order,
is_enabled=request.is_enabled,
)
db.add(expert)
db.commit()
db.refresh(expert)
return HomeExpertResponse(message="添加成功", data=expert_to_dict(expert, article))
@router.put("/admin/home-experts/{expert_id}", response_model=HomeExpertResponse)
def update_expert(
expert_id: int,
request: HomeExpertUpdate,
db: Session = Depends(get_db),
current_admin: Admin = Depends(get_current_admin)
):
"""更新专家团队条目"""
expert = db.query(HomeExpert).filter(HomeExpert.id == expert_id).first()
if not expert:
raise HTTPException(status_code=404, detail="专家不存在")
for field, value in request.dict(exclude_unset=True).items():
setattr(expert, field, value)
db.commit()
db.refresh(expert)
article = db.query(Article).filter(Article.id == expert.post_id).first()
return HomeExpertResponse(message="更新成功", data=expert_to_dict(expert, article))
@router.delete("/admin/home-experts/{expert_id}", response_model=HomeExpertResponse)
def delete_expert(
expert_id: int,
db: Session = Depends(get_db),
current_admin: Admin = Depends(get_current_admin)
):
"""从首页专家团队移除(不删除原文章)"""
expert = db.query(HomeExpert).filter(HomeExpert.id == expert_id).first()
if not expert:
raise HTTPException(status_code=404, detail="专家不存在")
db.delete(expert)
db.commit()
return HomeExpertResponse(message="移除成功")