diff --git a/api/app/application/solutions_repository.py b/api/app/application/solutions_repository.py
index d768965..f5779a8 100644
--- a/api/app/application/solutions_repository.py
+++ b/api/app/application/solutions_repository.py
@@ -23,6 +23,9 @@ class SolutionsRepository:
query = (
select(Solution)
.filter_by(task_id=task_id)
+ .options(
+ selectinload(Solution.files),
+ )
)
result = await self.db.execute(query)
return result.scalars().all()
@@ -44,6 +47,11 @@ class SolutionsRepository:
await self.db.refresh(solution)
return solution
+ async def update(self, solution: Solution) -> Solution:
+ await self.db.merge(solution)
+ await self.db.commit()
+ return solution
+
async def delete(self, solution: Solution) -> Solution:
await self.db.delete(solution)
await self.db.commit()
diff --git a/api/app/controllers/solutions_router.py b/api/app/controllers/solutions_router.py
index 8ef7550..d1e1eb4 100644
--- a/api/app/controllers/solutions_router.py
+++ b/api/app/controllers/solutions_router.py
@@ -6,9 +6,9 @@ from starlette.responses import FileResponse
from app.database.session import get_db
from app.domain.entities.solution_files import ReadSolutionFile
-from app.domain.entities.solutions import SolutionCreate, SolutionRead, SolutionAfterCreate
+from app.domain.entities.solutions import SolutionCreate, SolutionRead, SolutionAfterCreate, AssessmentCreate
from app.domain.models import User
-from app.infrastructure.dependencies import require_auth_user
+from app.infrastructure.dependencies import require_auth_user, require_teacher
from app.infrastructure.solution_files_service import SolutionFilesService
from app.infrastructure.solutions_service import SolutionsService
@@ -123,3 +123,20 @@ async def upload_file(
):
task_files_service = SolutionFilesService(db)
return await task_files_service.upload_file(task_id, file)
+
+
+@solution_router.post(
+ '/assessment/{solution_id}/',
+ status_code=status.HTTP_204_NO_CONTENT,
+ summary='Set assessment for solution',
+ description='Set assessment for solution',
+)
+async def create_assessment(
+ solution_id: int,
+ assessment_data: AssessmentCreate,
+ db: AsyncSession = Depends(get_db),
+ current_user: User = Depends(require_teacher),
+):
+ solutions_service = SolutionsService(db)
+ await solutions_service.create_assessment(solution_id, assessment_data, current_user)
+ return Response(status_code=status.HTTP_204_NO_CONTENT)
diff --git a/api/app/domain/entities/solutions.py b/api/app/domain/entities/solutions.py
index d11620c..803daa7 100644
--- a/api/app/domain/entities/solutions.py
+++ b/api/app/domain/entities/solutions.py
@@ -34,3 +34,7 @@ class SolutionRead(SolutionAfterCreate):
class Config:
from_attributes = True
+
+
+class AssessmentCreate(BaseModel):
+ assessment: int = Field(...)
diff --git a/api/app/infrastructure/solutions_service.py b/api/app/infrastructure/solutions_service.py
index 3ae9ad8..7a2c9f8 100644
--- a/api/app/infrastructure/solutions_service.py
+++ b/api/app/infrastructure/solutions_service.py
@@ -8,7 +8,7 @@ from app.application.solution_files_repository import SolutionFilesRepository
from app.application.solutions_repository import SolutionsRepository
from app.application.tasks_repository import TasksRepository
from app.application.users_repository import UsersRepository
-from app.domain.entities.solutions import SolutionRead, SolutionCreate, SolutionAfterCreate
+from app.domain.entities.solutions import SolutionRead, SolutionCreate, SolutionAfterCreate, AssessmentCreate
from app.domain.models import User, Solution
from app.settings import Settings
@@ -67,6 +67,20 @@ class SolutionsService:
return response
+ async def create_assessment(self, solution_id: int, assessment: AssessmentCreate, user: User) -> None:
+ solution_model = await self.solutions_repository.get_by_id(solution_id)
+
+ if solution_model is None:
+ raise HTTPException(
+ status_code=status.HTTP_404_NOT_FOUND,
+ detail="Такого решения не найдено"
+ )
+
+ solution_model.assessment = assessment.assessment
+ solution_model.assessment_autor_id = user.id
+
+ await self.solutions_repository.update(solution_model)
+
async def create(self, solution: SolutionCreate, creator: User, task_id: int) -> SolutionAfterCreate:
task_model = await self.tasks_repository.get_by_id(task_id)
diff --git a/web/src/Api/solutionsApi.js b/web/src/Api/solutionsApi.js
index 9dc96b2..9731783 100644
--- a/web/src/Api/solutionsApi.js
+++ b/web/src/Api/solutionsApi.js
@@ -59,6 +59,14 @@ export const solutionsApi = createApi({
},
invalidatesTags: ["task"],
}),
+ createAssessment: builder.mutation({
+ query: ({solutionId, assessment}) => ({
+ url: `/solutions/assessment/${solutionId}/`,
+ method: "POST",
+ body: assessment,
+ }),
+ invalidatesTags: ["lesson"],
+ }),
}),
});
@@ -69,5 +77,6 @@ export const {
useDeleteSolutionMutation,
useGetSolutionFilesListQuery,
useUploadFileMutation,
+ useCreateAssessmentMutation,
} = solutionsApi;
diff --git a/web/src/Components/Pages/CourseDetailPage/Components/ViewTaskModalForm/ViewTaskModal.jsx b/web/src/Components/Pages/CourseDetailPage/Components/ViewTaskModalForm/ViewTaskModal.jsx
index d63d9d5..7979806 100644
--- a/web/src/Components/Pages/CourseDetailPage/Components/ViewTaskModalForm/ViewTaskModal.jsx
+++ b/web/src/Components/Pages/CourseDetailPage/Components/ViewTaskModalForm/ViewTaskModal.jsx
@@ -4,7 +4,7 @@ import {
Col, Collapse,
Divider,
Empty, Flex,
- Form,
+ Form, Input, InputNumber,
Modal,
Popconfirm,
Row,
@@ -47,7 +47,10 @@ const ViewTaskModal = () => {
handleRemoveFile,
handleOk,
draftFiles,
- handleDeleSolution
+ handleDeleSolution,
+ allSolutions,
+ onAssessmentFinish,
+ assessmentForm,
} = useViewTaskModal();
return (
@@ -214,9 +217,9 @@ const ViewTaskModal = () => {
onClick={() => downloadFile(file.id, file.filename)}
loading={downloadingFiles[file.id]}
>
-
- {file.filename} ({(file.file_size / 1024 / 1024).toFixed(2)} МБ)
-
+
+ {file.filename}
+