from fastapi import APIRouter, Depends, File, Form, UploadFile from sqlalchemy.orm import Session from app.core.response import ApiResponse, ok from app.core.user_context import UserContext, get_user_context from app.db.session import get_db from app.repositories.knowledge_base_repository import KnowledgeBaseRepository from app.schemas.knowledge_admin import ( KnowledgeDocumentDetailResponse, KnowledgeDocumentListResponse, KnowledgeDocumentUploadResponse, ) from app.services.document_ingestion_service import DocumentIngestionService from app.services.knowledge_space_service import KnowledgeSpaceService router = APIRouter() @router.post("/documents/upload", response_model=ApiResponse[KnowledgeDocumentUploadResponse]) async def upload_knowledge_document( file: UploadFile = File(..., description="PDF 文件"), document_title: str | None = Form(default=None, description="文档标题"), document_category: str = Form(default="textbook", description="文档分类:textbook/guideline/manual/other"), version: str = Form(default="v1", description="文档版本"), ctx: UserContext = Depends(get_user_context), db: Session = Depends(get_db), ): """知识库上传:内容管理员上传 PDF,并触发机构知识库构建。""" result = await DocumentIngestionService(db).upload_pdf( ctx, file, document_title=document_title, document_category=document_category, version=version, ) db.commit() return ok(result) @router.get("/documents", response_model=ApiResponse[KnowledgeDocumentListResponse]) def list_knowledge_documents( ctx: UserContext = Depends(get_user_context), db: Session = Depends(get_db), ): """知识库文档列表:内容管理员查看本机构已上传文档。""" repo = KnowledgeBaseRepository(db) KnowledgeSpaceService(repo).ensure_content_admin(ctx) institution_id = KnowledgeSpaceService(repo).require_institution_id(ctx) items = [_to_detail(item) for item in repo.list_documents(institution_id)] return ok(KnowledgeDocumentListResponse(items=items)) @router.get("/documents/{document_id}", response_model=ApiResponse[KnowledgeDocumentDetailResponse]) def get_knowledge_document( document_id: int, ctx: UserContext = Depends(get_user_context), db: Session = Depends(get_db), ): """知识库文档详情:按机构隔离返回 PDF 构建状态。""" repo = KnowledgeBaseRepository(db) KnowledgeSpaceService(repo).ensure_content_admin(ctx) institution_id = KnowledgeSpaceService(repo).require_institution_id(ctx) document = repo.get_document(document_id, institution_id) if not document: from app.core.exceptions import AppError raise AppError("KNOWLEDGE_DOCUMENT_NOT_FOUND", "knowledge document not found", 404) return ok(_to_detail(document)) def _to_detail(document) -> KnowledgeDocumentDetailResponse: """响应转换:把 ORM 文档对象转换为 API 文档详情。""" return KnowledgeDocumentDetailResponse( document_id=document.id, institution_id=document.institution_id, file_name=document.file_name, document_title=document.document_title, document_category=document.document_category, version=document.version, status=document.status, parse_status=document.parse_status, embedding_status=document.embedding_status, chunk_count=document.chunk_count, error_message=document.error_message, created_at=getattr(document, "created_at", None), updated_at=getattr(document, "updated_at", None), )