diff --git a/.gitignore b/.gitignore index 31af5a6..60ec3ca 100644 --- a/.gitignore +++ b/.gitignore @@ -135,6 +135,7 @@ venv/ ENV/ env.bak/ venv.bak/ +SG/ # Spyder project settings .spyderproject diff --git a/app/crud/survey2.py b/app/crud/survey2.py new file mode 100644 index 0000000..ab80c69 --- /dev/null +++ b/app/crud/survey2.py @@ -0,0 +1,106 @@ +from sqlalchemy.orm import Session +from app.models.survey2 import Survey, Question, Option, UserResponse + +def get_survey(db: Session, survey_id: int): + return db.query(Survey).filter(Survey.id == survey_id).first() + +def get_active_survey(db: Session): + return db.query(Survey).filter(Survey.is_active == True).first() + +def create_survey(db: Session, survey_data): + db_survey = Survey( + title=survey_data.title, + description=survey_data.description, + is_active=survey_data.is_active + ) + db.add(db_survey) + db.commit() + db.refresh(db_survey) + + for question_data in survey_data.questions: + db_question = Question( + text=question_data.text, + question_type=question_data.question_type, + survey_id=db_survey.id + ) + db.add(db_question) + db.commit() + db.refresh(db_question) + + for option_data in question_data.options: + db_option = Option( + text=option_data.text, + score=option_data.score, + question_id=db_question.id + ) + db.add(db_option) + + db.commit() + db.refresh(db_survey) + return db_survey + +def save_response(db: Session, response_data): + db_response = UserResponse(**response_data.dict()) + db.add(db_response) + db.commit() + db.refresh(db_response) + return db_response + +def calculate_results(db: Session, user_id: str, survey_id: int): + responses = db.query(UserResponse).filter( + UserResponse.user_id == user_id, + UserResponse.survey_id == survey_id + ).all() + + if not responses: + return None + + # Вопросы для экранной зависимости (2-6) + screen_questions = {2, 3, 4, 5, 6} + # Вопросы для игровой зависимости (7-11) + game_questions = {7, 8, 9, 10, 11} + + screen_score = 0 + game_score = 0 + + for response in responses: + option = db.query(Option).filter(Option.id == response.option_id).first() + if response.question_id in screen_questions: + screen_score += option.score + elif response.question_id in game_questions: + game_score += option.score + + # Определение уровней зависимости + def get_dependency_level(score, dependency_type): + if score >= 11: + level = "высокий уровень риска" + if dependency_type == "screen": + desc = "Ребенок зависим от гаджета, возможны нарушения сна и успеваемости" + else: + desc = "Ребенок зависим от игр, возможны проблемы с учебой и общением" + elif 6 <= score <= 10: + level = "средний уровень риска" + if dependency_type == "screen": + desc = "Регулярное, но не чрезмерное использование устройств" + else: + desc = "Чрезмерное увлечение играми с небольшим влиянием на учебу" + else: + level = "низкий уровень риска" + if dependency_type == "screen": + desc = "Умеренное использование гаджетов без нарушений" + else: + desc = "Контролируемое использование игр, хороший баланс" + + return level, desc + + screen_level, screen_desc = get_dependency_level(screen_score, "screen") + game_level, game_desc = get_dependency_level(game_score, "game") + + return { + "screen_dependency_score": screen_score, + "game_dependency_score": game_score, + "screen_dependency_level": screen_level, + "game_dependency_level": game_level, + "screen_dependency_description": screen_desc, + "game_dependency_description": game_desc + } \ No newline at end of file diff --git a/app/main.py b/app/main.py index 238b98b..3804410 100644 --- a/app/main.py +++ b/app/main.py @@ -1,7 +1,7 @@ from fastapi import FastAPI from app.config import get_settings -from app.router import geo, session +from app.router import geo, session, survey2 from app.database import Base, engine settings = get_settings() @@ -10,6 +10,7 @@ app.include_router(geo.router, prefix="/geo", tags=["Geo"]) app.include_router(session.router, prefix="/session", tags=["Session"]) +app.include_router(survey2.router) @app.get("/") async def root(): diff --git a/app/models/survey2.py b/app/models/survey2.py new file mode 100644 index 0000000..19a56b6 --- /dev/null +++ b/app/models/survey2.py @@ -0,0 +1,47 @@ +from sqlalchemy import Column, Integer, String, ForeignKey, Boolean, DateTime +from sqlalchemy.orm import relationship +from datetime import datetime +from app.database import Base + +class Survey(Base): #Опрос + __tablename__ = "surve2" + + id = Column(Integer, primary_key=True, index=True) + title = Column(String, nullable=False) + description = Column(String) + is_active = Column(Boolean, default=True) + created_at = Column(DateTime, default=datetime.utcnow) + + questions = relationship("Question", back_populates="survey", cascade="all, delete-orphan") + +class Question(Base):#Вопрос + __tablename__ = "questions" + + id = Column(Integer, primary_key=True, index=True) + text = Column(String, nullable=False) + survey_id = Column(Integer, ForeignKey("surve2.id")) + + survey = relationship("Survey", back_populates="questions") + options = relationship("Option", back_populates="question", cascade="all, delete-orphan") + +class Option(Base): # Ответ + __tablename__ = "options" + + id = Column(Integer, primary_key=True, index=True) + text = Column(String, nullable=False) + score = Column(Integer, nullable=False) # Баллы за вариант ответа + question_id = Column(Integer, ForeignKey("questions.id")) + + question = relationship("Question", back_populates="options") + +class UserResponse(Base):# Результаты + __tablename__ = "user_responses" + + id = Column(Integer, primary_key=True, index=True) + question_id = Column(Integer, ForeignKey("questions.id")) + option_id = Column(Integer, ForeignKey("options.id")) + survey_id = Column(Integer, ForeignKey("surve2.id")) + + question = relationship("Question") + option = relationship("Option") + survey = relationship("Survey") \ No newline at end of file diff --git a/app/router/survey2.py b/app/router/survey2.py new file mode 100644 index 0000000..3ef89c2 --- /dev/null +++ b/app/router/survey2.py @@ -0,0 +1,46 @@ +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from typing import List +from app.logger import get_logger + +from app.database import get_db +from app.schemas.survey2 import ( + Survey, SurveyCreate, SurveyResult, + Response, ResponseCreate +) +from app.crud.survey2 import ( + get_survey, get_active_survey, + create_survey, save_response, + calculate_results +) + +router = APIRouter(prefix="/surveys", tags=["Surveys"]) +logger = get_logger() + +@router.get("/active", response_model=Survey) +def get_active_survey_endpoint(db: Session = Depends(get_db)): + survey = get_active_survey(db) + if not survey: + raise HTTPException(status_code=404, detail="No active survey found") + return survey + +@router.post("/responses", response_model=Response) +def create_response( + response: ResponseCreate, + db: Session = Depends(get_db) +): + return save_response(db, response) + +@router.get("/results/{user_id}", response_model=SurveyResult) +def get_survey_results( + user_id: str, + db: Session = Depends(get_db) +): + survey = get_active_survey(db) + if not survey: + raise HTTPException(status_code=404, detail="No active survey found") + + results = calculate_results(db, user_id=user_id, survey_id=survey.id) + if not results: + raise HTTPException(status_code=404, detail="Responses not found") + return results \ No newline at end of file diff --git a/app/schemas/survey2.py b/app/schemas/survey2.py new file mode 100644 index 0000000..a6613bb --- /dev/null +++ b/app/schemas/survey2.py @@ -0,0 +1,71 @@ +from pydantic import BaseModel +from typing import List, Optional +from datetime import datetime + +class OptionBase(BaseModel): + text: str + score: int + +class OptionCreate(OptionBase): + pass + +class Option(OptionBase): + id: int + question_id: int + + class Config: + from_attributes = True + +class QuestionBase(BaseModel): + text: str + +class QuestionCreate(QuestionBase): + options: List[OptionCreate] = [] + +class Question(QuestionBase): + id: int + survey_id: int + options: List[Option] = [] + + class Config: + from_attributes = True + +class SurveyBase(BaseModel): + title: str + description: Optional[str] = None + is_active: Optional[bool] = True + +class SurveyCreate(SurveyBase): + questions: List[QuestionCreate] = [] + +class Survey(SurveyBase): + id: int + created_at: datetime + questions: List[Question] = [] + + class Config: + from_attributes = True + +class ResponseBase(BaseModel): + user_id: str + question_id: int + option_id: int + survey_id: int + +class ResponseCreate(ResponseBase): + pass + +class Response(ResponseBase): + id: int + created_at: datetime + + class Config: + from_attributes = True + +class SurveyResult(BaseModel): + screen_dependency_score: int + game_dependency_score: int + screen_dependency_level: str + game_dependency_level: str + screen_dependency_description: str + game_dependency_description: str \ No newline at end of file