from typing import Optional from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy import or_ from sqlalchemy.orm import Session from database import get_db from models.material import Material from models.user import User from schemas.material import MaterialCreate, MaterialOut, MaterialUpdate from services.auth import get_current_user router = APIRouter(prefix="/api/materials", tags=["素材库"]) @router.post("/", response_model=MaterialOut, status_code=201) def create_material( data: MaterialCreate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): material = Material(user_id=current_user.id, **data.model_dump()) db.add(material) db.commit() db.refresh(material) return material @router.get("/", response_model=list[MaterialOut]) def list_materials( material_type: Optional[str] = None, subject: Optional[str] = None, keyword: Optional[str] = None, skip: int = Query(0, ge=0), limit: int = Query(20, ge=1, le=100), current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): query = db.query(Material).filter(Material.user_id == current_user.id, Material.status == "active") if material_type: query = query.filter(Material.material_type == material_type) if subject: query = query.filter(Material.subject == subject) if keyword: query = query.filter(or_( Material.title.contains(keyword), Material.filename.contains(keyword), Material.summary.contains(keyword), Material.subject.contains(keyword), Material.grade.contains(keyword), )) return query.order_by(Material.updated_at.desc()).offset(skip).limit(limit).all() @router.get("/{material_id}", response_model=MaterialOut) def get_material( material_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): material = db.query(Material).filter( Material.id == material_id, Material.user_id == current_user.id, Material.status == "active", ).first() if not material: raise HTTPException(status_code=404, detail="素材不存在") return material @router.put("/{material_id}", response_model=MaterialOut) def update_material( material_id: int, data: MaterialUpdate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): material = db.query(Material).filter(Material.id == material_id, Material.user_id == current_user.id).first() if not material or material.status == "archived": raise HTTPException(status_code=404, detail="素材不存在") for key, value in data.model_dump(exclude_unset=True).items(): setattr(material, key, value) db.commit() db.refresh(material) return material @router.delete("/{material_id}", status_code=204) def delete_material( material_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ): material = db.query(Material).filter(Material.id == material_id, Material.user_id == current_user.id).first() if not material or material.status == "archived": raise HTTPException(status_code=404, detail="素材不存在") material.status = "archived" db.commit()