from pathlib import Path from fastapi import APIRouter, Depends, File, HTTPException, UploadFile from sqlalchemy.orm import Session from backend.auth import get_current_user from backend.database import get_db from backend.models import ImportHistory, Question from backend.schemas import ImportHistoryOut, QuestionOut from backend.services.excel_service import create_template_bytes, parse_excel_file from backend.services.file_utils import save_upload from backend.services.parser import DMXAPIService, extract_metadata router = APIRouter(dependencies=[Depends(get_current_user)]) @router.post("/ai/parse") def parse_by_ai(file: UploadFile = File(...)) -> dict: path = save_upload(file) parser = DMXAPIService() metadata = extract_metadata(file.filename or path.name) questions = parser.parse_file(str(path)) preview = [] for q in questions: preview.append( { "chapter": metadata["chapter"], "primary_knowledge": "", "secondary_knowledge": metadata["secondary_knowledge"], "question_type": metadata["question_type"], "difficulty": metadata["difficulty"], "stem": q.get("题干", ""), "option_a": q.get("选项A", ""), "option_b": q.get("选项B", ""), "option_c": q.get("选项C", ""), "option_d": q.get("选项D", ""), "answer": q.get("正确答案", ""), "explanation": q.get("解析", ""), "notes": q.get("备注", ""), "source_file": metadata["source_file"], } ) return {"filename": file.filename, "preview": preview} @router.post("/ai/confirm", response_model=list[QuestionOut]) def confirm_ai_import(payload: list[dict], db: Session = Depends(get_db)) -> list[QuestionOut]: if not payload: raise HTTPException(status_code=400, detail="没有可导入数据") items = [Question(**item) for item in payload] db.add_all(items) db.add( ImportHistory( filename=items[0].source_file if items else "", method="ai", question_count=len(items), status="success", ) ) db.commit() for item in items: db.refresh(item) return [QuestionOut.model_validate(item) for item in items] @router.post("/excel", response_model=list[QuestionOut]) def import_excel(file: UploadFile = File(...), db: Session = Depends(get_db)) -> list[QuestionOut]: path = save_upload(file) if Path(path).suffix.lower() not in [".xlsx", ".xlsm", ".xltx", ".xltm"]: raise HTTPException(status_code=400, detail="仅支持 Excel 文件") rows = parse_excel_file(Path(path)) items = [Question(**row) for row in rows] db.add_all(items) db.add( ImportHistory( filename=file.filename or "", method="excel", question_count=len(items), status="success", ) ) db.commit() for item in items: db.refresh(item) return [QuestionOut.model_validate(item) for item in items] @router.get("/template") def download_template() -> dict: content = create_template_bytes() return {"filename": "question_template.xlsx", "content_base64": content.hex()} @router.get("/history", response_model=list[ImportHistoryOut]) def import_history(db: Session = Depends(get_db)) -> list[ImportHistoryOut]: rows = db.query(ImportHistory).order_by(ImportHistory.created_at.desc()).limit(100).all() return [ImportHistoryOut.model_validate(r) for r in rows]