97 lines
2.7 KiB
Python
97 lines
2.7 KiB
Python
"""在线课程:只有外链的视频/课程资源,与教材分表维护。"""
|
|
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy.orm import Session
|
|
|
|
from database import get_db
|
|
from dependencies import get_current_user, require_permission
|
|
from models import Course, User
|
|
from schemas import CourseCreate, CourseOut, CourseUpdate
|
|
|
|
router = APIRouter(prefix="/courses", tags=["courses"])
|
|
|
|
|
|
def _load(db: Session, course_id: int) -> Course:
|
|
course = db.get(Course, course_id)
|
|
if course is None:
|
|
raise HTTPException(status_code=404, detail="课程不存在")
|
|
return course
|
|
|
|
|
|
def _clean_url(url: str | None) -> str:
|
|
url = (url or "").strip()
|
|
if not url:
|
|
raise HTTPException(status_code=400, detail="请填写课程链接")
|
|
return url
|
|
|
|
|
|
@router.get("", response_model=list[CourseOut])
|
|
def list_courses(
|
|
db: Session = Depends(get_db),
|
|
_: User = Depends(get_current_user),
|
|
):
|
|
return (
|
|
db.query(Course)
|
|
.order_by(Course.position.asc(), Course.id.asc())
|
|
.all()
|
|
)
|
|
|
|
|
|
@router.post("", response_model=CourseOut)
|
|
def create_course(
|
|
payload: CourseCreate,
|
|
db: Session = Depends(get_db),
|
|
_: User = Depends(require_permission("catalog:manage")),
|
|
):
|
|
if db.query(Course).filter(Course.name == payload.name).first():
|
|
raise HTTPException(status_code=400, detail="同名课程已存在")
|
|
course = Course(
|
|
name=payload.name,
|
|
provider=payload.provider,
|
|
url=_clean_url(payload.url),
|
|
grade=payload.grade,
|
|
description=payload.description,
|
|
position=db.query(Course).count(),
|
|
)
|
|
db.add(course)
|
|
db.commit()
|
|
return course
|
|
|
|
|
|
@router.put("/{course_id}", response_model=CourseOut)
|
|
def update_course(
|
|
course_id: int,
|
|
payload: CourseUpdate,
|
|
db: Session = Depends(get_db),
|
|
_: User = Depends(require_permission("catalog:manage")),
|
|
):
|
|
course = _load(db, course_id)
|
|
fields = payload.model_dump(exclude_unset=True)
|
|
if "name" in fields and fields["name"] != course.name:
|
|
exists = (
|
|
db.query(Course)
|
|
.filter(Course.name == fields["name"], Course.id != course.id)
|
|
.first()
|
|
)
|
|
if exists:
|
|
raise HTTPException(status_code=400, detail="同名课程已存在")
|
|
if "url" in fields:
|
|
fields["url"] = _clean_url(fields["url"])
|
|
for field, value in fields.items():
|
|
setattr(course, field, value)
|
|
db.commit()
|
|
return course
|
|
|
|
|
|
@router.delete("/{course_id}")
|
|
def delete_course(
|
|
course_id: int,
|
|
db: Session = Depends(get_db),
|
|
_: User = Depends(require_permission("catalog:manage")),
|
|
):
|
|
course = _load(db, course_id)
|
|
db.delete(course)
|
|
db.commit()
|
|
return {"deleted": course_id}
|