add algam

This commit is contained in:
2025-09-22 11:54:42 +05:00
parent 3c418a97b4
commit 5b9c55a4dc
34 changed files with 4700 additions and 426 deletions

View File

@@ -256,4 +256,205 @@ async def delete_setting(key: str, db_session: Session = Depends(get_db)):
db_session.delete(setting)
db_session.commit()
return MessageResponseModel(message=f"Настройка '{key}' удалена")
return MessageResponseModel(message=f"Настройка '{key}' удалена")
# Добавляем импорты для работы с тестами
from database.models import Test, TestCategory, Question, AnswerOption, Image
from database.services import ImageService, TestService, QuestionService
from database.repositories import TestRepository, QuestionRepository, ImageRepository
from api.schemas import (
TestCategoryCreate, TestCategoryResponse, TestCreate, TestResponse,
QuestionCreate, QuestionResponse, AnswerOptionCreate, AnswerOptionResponse,
ImageUploadResponse
)
from fastapi import UploadFile, File
# Роутер для работы с категориями тестов
test_categories_router = APIRouter(prefix="/test-categories", tags=["Test Categories"])
@test_categories_router.post("/", response_model=TestCategoryResponse)
async def create_test_category(
category_data: TestCategoryCreate,
db_session: Session = Depends(get_db)
):
"""Создание новой категории тестов"""
category = TestCategory(
name=category_data.name,
description=category_data.description
)
db_session.add(category)
db_session.commit()
db_session.refresh(category)
return category
@test_categories_router.get("/", response_model=List[TestCategoryResponse])
async def get_test_categories(db_session: Session = Depends(get_db)):
"""Получение всех категорий тестов"""
categories = db_session.query(TestCategory).all()
return categories
# Роутер для работы с тестами
tests_router = APIRouter(prefix="/tests", tags=["Tests"])
@tests_router.post("/", response_model=TestResponse)
async def create_test(
test_data: TestCreate,
db_session: Session = Depends(get_db)
):
"""Создание нового теста"""
test_repo = TestRepository(db_session)
test = test_repo.create_test(
title=test_data.title,
description=test_data.description,
category_id=test_data.category_id,
is_active=test_data.is_active,
time_limit_minutes=test_data.time_limit_minutes
)
return test
@tests_router.get("/", response_model=List[TestResponse])
async def get_tests(
is_active: Optional[bool] = Query(default=None),
category_id: Optional[int] = Query(default=None),
db_session: Session = Depends(get_db)
):
"""Получение списка тестов с фильтрацией"""
test_repo = TestRepository(db_session)
tests = test_repo.get_tests(is_active=is_active, category_id=category_id)
return tests
@tests_router.get("/{test_id}", response_model=TestResponse)
async def get_test_by_id(test_id: int, db_session: Session = Depends(get_db)):
"""Получение теста по ID"""
test_repo = TestRepository(db_session)
test = test_repo.get_test_by_id(test_id)
if not test:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Тест не найден"
)
return test
# Роутер для работы с вопросами
questions_router = APIRouter(prefix="/questions", tags=["Questions"])
@questions_router.post("/", response_model=QuestionResponse)
async def create_question(
question_data: QuestionCreate,
db_session: Session = Depends(get_db)
):
"""Создание нового вопроса"""
question_repo = QuestionRepository(db_session)
question = question_repo.create_question(
test_id=question_data.test_id,
question_text=question_data.question_text,
question_type=question_data.question_type,
order_number=question_data.order_number,
points=question_data.points,
image_id=question_data.image_id
)
return question
@questions_router.get("/test/{test_id}", response_model=List[QuestionResponse])
async def get_questions_by_test(test_id: int, db_session: Session = Depends(get_db)):
"""Получение всех вопросов для теста"""
question_repo = QuestionRepository(db_session)
questions = question_repo.get_questions_by_test_id(test_id)
return questions
@questions_router.get("/{question_id}", response_model=QuestionResponse)
async def get_question_by_id(question_id: int, db_session: Session = Depends(get_db)):
"""Получение вопроса по ID"""
question_repo = QuestionRepository(db_session)
question = question_repo.get_question_by_id(question_id)
if not question:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Вопрос не найден"
)
return question
# Роутер для работы с вариантами ответов
answer_options_router = APIRouter(prefix="/answer-options", tags=["Answer Options"])
@answer_options_router.post("/", response_model=AnswerOptionResponse)
async def create_answer_option(
option_data: AnswerOptionCreate,
db_session: Session = Depends(get_db)
):
"""Создание нового варианта ответа"""
option = AnswerOption(
question_id=option_data.question_id,
option_text=option_data.option_text,
is_correct=option_data.is_correct,
order_number=option_data.order_number
)
db_session.add(option)
db_session.commit()
db_session.refresh(option)
return option
@answer_options_router.get("/question/{question_id}", response_model=List[AnswerOptionResponse])
async def get_answer_options_by_question(question_id: int, db_session: Session = Depends(get_db)):
"""Получение всех вариантов ответов для вопроса"""
options = db_session.query(AnswerOption).filter(
AnswerOption.question_id == question_id
).order_by(AnswerOption.order_number).all()
return options
# Роутер для работы с изображениями
images_router = APIRouter(prefix="/images", tags=["Images"])
@images_router.post("/upload", response_model=ImageUploadResponse)
async def upload_image(
file: UploadFile = File(...),
alt_text: Optional[str] = None,
db_session: Session = Depends(get_db)
):
"""Загрузка изображения в базу данных"""
# Проверяем тип файла
if not file.content_type.startswith('image/'):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Загружаемый файл должен быть изображением"
)
# Читаем содержимое файла
image_data = await file.read()
# Сохраняем в БД через сервис
image = ImageService.save_image_to_db(
db=db_session,
filename=file.filename,
content_type=file.content_type,
image_data=image_data,
alt_text=alt_text
)
return ImageUploadResponse(
id=image.id,
filename=image.filename,
content_type=image.content_type,
file_size=image.file_size
)
@images_router.get("/{image_id}")
async def get_image(image_id: int, db_session: Session = Depends(get_db)):
"""Получение изображения по ID"""
from fastapi.responses import Response
image_repo = ImageRepository(db_session)
image = image_repo.get_image_by_id(image_id)
if not image:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Изображение не найдено"
)
return Response(
content=image.image_data,
media_type=image.content_type,
headers={"Content-Disposition": f"inline; filename={image.filename}"}
)