From e90be8b54e4a72baf2670b8270455a001cced1d1 Mon Sep 17 00:00:00 2001 From: andrei Date: Sat, 29 Nov 2025 09:02:32 +0500 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20?= =?UTF-8?q?=D1=83=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D1=84=D0=B0=D0=B9=D0=BB=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/app/controllers/lessons_router.py | 5 ++-- api/app/infrastructure/lessons_service.py | 20 ++++++++++++++ .../CourseDetailPage/CourseDetailPage.jsx | 16 ++++++++---- .../CourseDetailPage/useCourseDetailPage.js | 26 ++++++++++++++++++- 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/api/app/controllers/lessons_router.py b/api/app/controllers/lessons_router.py index 974159a..0562c65 100644 --- a/api/app/controllers/lessons_router.py +++ b/api/app/controllers/lessons_router.py @@ -78,7 +78,7 @@ async def update_lesson( @lessons_router.delete( - '/{lesson_id}', + '/{lesson_id}/', response_model=Optional[LessonRead], summary='Delete a lesson', description='Delete a lesson', @@ -89,8 +89,7 @@ async def delete_lesson( current_user: User = Depends(require_teacher), ): lessons_service = LessonsService(db) - await lessons_service.delete(lesson_id, current_user) - return None + return await lessons_service.delete(lesson_id, current_user) @lessons_router.get( diff --git a/api/app/infrastructure/lessons_service.py b/api/app/infrastructure/lessons_service.py index 8f610cc..b8e47f8 100644 --- a/api/app/infrastructure/lessons_service.py +++ b/api/app/infrastructure/lessons_service.py @@ -1,12 +1,16 @@ +import os + from fastapi import HTTPException, status from typing import List, Optional from sqlalchemy.ext.asyncio import AsyncSession from app.application.courses_repository import CoursesRepository +from app.application.lesson_files_repository import LessonFilesRepository from app.application.lessons_repository import LessonsRepository from app.domain.entities.lessons import LessonCreate, LessonUpdate, LessonRead from app.domain.models import Lesson, User +from app.infrastructure.lesson_files_service import LessonFilesService from app.settings import Settings @@ -14,6 +18,7 @@ class LessonsService: def __init__(self, db: AsyncSession): self.lessons_repository = LessonsRepository(db) self.courses_repository = CoursesRepository(db) + self.lesson_files_repository = LessonFilesRepository(db) self.settings = Settings() async def get_all_by_course(self, course_id: int) -> List[LessonRead]: @@ -91,4 +96,19 @@ class LessonsService: detail="Доступ запрещён" ) + lesson_files = await self.lesson_files_repository.get_by_lesson_id(lesson_id) + for file in lesson_files: + lesson_file = await self.lesson_files_repository.get_by_id(file.id) + + if lesson_file is None: + raise HTTPException(404, "Файл не найден") + + if not os.path.exists(lesson_file.file_path): + raise HTTPException(404, "Файл не найден на диске") + + if os.path.exists(lesson_file.file_path): + os.remove(lesson_file.file_path) + + await self.lesson_files_repository.delete(lesson_file) + await self.lessons_repository.delete(lesson) diff --git a/web/src/Components/Pages/CourseDetailPage/CourseDetailPage.jsx b/web/src/Components/Pages/CourseDetailPage/CourseDetailPage.jsx index ff4ca65..9eb3cb7 100644 --- a/web/src/Components/Pages/CourseDetailPage/CourseDetailPage.jsx +++ b/web/src/Components/Pages/CourseDetailPage/CourseDetailPage.jsx @@ -46,6 +46,7 @@ const CourseDetailPage = () => { handleCreateLesson, handleOpenLesson, handleEditLesson, + handleDeleteLesson, } = useCourseDetailPage(courseId); if (isLoading) { @@ -112,10 +113,10 @@ const CourseDetailPage = () => { { - // e?.stopPropagation(); - // handleDeleteLesson(lesson.id); - // }} + onConfirm={(e) => { + e?.stopPropagation(); + handleDeleteLesson(lesson.id); + }} okText="Удалить" cancelText="Отмена" > @@ -132,12 +133,17 @@ const CourseDetailPage = () => { >
{lesson.description ? ( - {lesson.description} + + {lesson.description.slice(0, 100)}... + ) : ( Описание отсутствует )}
+ + Лекционный материал +
{userData?.first_name?.[0] || "У"} diff --git a/web/src/Components/Pages/CourseDetailPage/useCourseDetailPage.js b/web/src/Components/Pages/CourseDetailPage/useCourseDetailPage.js index bf55101..bd73e4a 100644 --- a/web/src/Components/Pages/CourseDetailPage/useCourseDetailPage.js +++ b/web/src/Components/Pages/CourseDetailPage/useCourseDetailPage.js @@ -7,9 +7,10 @@ import { setSelectedLessonToUpdate, setSelectedLessonToView } from "../../../Redux/Slices/lessonsSlice.js"; -import {useGetLessonsByCourseIdQuery} from "../../../Api/lessonsApi.js"; +import {useDeleteLessonMutation, useGetLessonsByCourseIdQuery} from "../../../Api/lessonsApi.js"; import {ROLES} from "../../../Core/constants.js"; import CONFIG from "../../../Core/сonfig.js"; +import {notification} from "antd"; const useCourseDetailPage = (courseId) => { @@ -39,6 +40,28 @@ const useCourseDetailPage = (courseId) => { pollingInterval: 10000, }); + const [ + deleteLesson, + ] = useDeleteLessonMutation(); + + const handleDeleteLesson = async (lessonId) => { + try { + await deleteLesson(lessonId); + + notification.success({ + title: "Успешно", + description: "Лекция удалена", + placement: "topRight", + }); + } catch (error) { + notification.error({ + title: "Ошибка", + description: error?.data?.detail || "Произошла ошибка при удалении лекции", + placement: "topRight", + }) + } + }; + useEffect(() => { window.document.title = `Система обучения lectio - Курс: ${courseData?.title}`; }, [courseData]); @@ -67,6 +90,7 @@ const useCourseDetailPage = (courseId) => { handleCreateLesson, handleOpenLesson, handleEditLesson, + handleDeleteLesson, } };