""" 知识库 API — 上传 / 列表 / 删除 / 来源筛选 """ from typing import Optional from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Query, status from sqlmodel import Session from app.core.deps import get_current_user, require_role from app.db.session import get_session from app.models.user import User, UserRole from app.services.knowledge_service import KnowledgeService router = APIRouter(prefix="/api/knowledge", tags=["知识库"]) @router.post("/upload") async def upload_md_files( files: list[UploadFile] = File(...), session: Session = Depends(get_session), current_user: User = Depends(require_role(UserRole.zhipianren, UserRole.zebian)), ): """ 上传单个或多个 .md 文件,解析 frontmatter,写入知识库(含向量)。 仅制片人/责编可用。 """ svc = KnowledgeService() results = [] errors = [] for f in files: if not f.filename.endswith(".md"): errors.append({"file": f.filename, "error": "仅支持 .md 文件"}) continue try: content = await f.read() item = svc.store_md_file(content, f.filename) results.append({ "id": item.id, "title": item.title, "source_type": item.source_type, }) except Exception as e: errors.append({"file": f.filename, "error": str(e)}) return {"uploaded": results, "errors": errors} @router.get("/items") def list_knowledge_items( source_type: Optional[str] = Query(None), session: Session = Depends(get_session), current_user: User = Depends(require_role(UserRole.zhipianren, UserRole.zebian, UserRole.biandao)), ): """ 知识库列表,支持按 source_type 筛选。三角色均可读。 """ svc = KnowledgeService() items = svc.list_items(source_type=source_type) return items @router.delete("/items/{item_id}") def delete_knowledge_item( item_id: int, session: Session = Depends(get_session), current_user: User = Depends(require_role(UserRole.zhipianren, UserRole.zebian)), ): """ 删除知识库条目(级联删除向量)。仅制片人/责编可用。 """ svc = KnowledgeService() deleted = svc.delete_item(item_id) if not deleted: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="条目不存在") return {"message": "删除成功"} @router.get("/sources") def list_distinct_sources( session: Session = Depends(get_session), current_user: User = Depends(require_role(UserRole.zhipianren, UserRole.zebian, UserRole.biandao)), ): """ 返回库里所有不重复的具体出处(source_detail),供来源筛选下拉动态生成。 三角色均可读。 """ svc = KnowledgeService() sources = svc.get_distinct_sources() return [{"source": s} for s in sources]