@@ -0,0 +1,129 @@
|
||||
from copy import deepcopy
|
||||
|
||||
from django.shortcuts import get_object_or_404
|
||||
from rest_framework import permissions, status
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from progression.services import initialize_math_identity
|
||||
|
||||
from .models import (
|
||||
MathBTIAssessment,
|
||||
MathBTIResult,
|
||||
MathIdentity,
|
||||
Story,
|
||||
StoryRun,
|
||||
)
|
||||
from .services import get_run_payload, make_choice, score_mathbti, start_story
|
||||
|
||||
|
||||
class MathBTIAssessmentView(APIView):
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
def get(self, request):
|
||||
assessment = (
|
||||
MathBTIAssessment.objects.filter(is_published=True).order_by("-published_at").first()
|
||||
)
|
||||
if assessment is None:
|
||||
return Response(
|
||||
{"error": {"code": "not_published", "message": "MathBTI 尚未发布"}},
|
||||
status=status.HTTP_404_NOT_FOUND,
|
||||
)
|
||||
definition = deepcopy(assessment.definition)
|
||||
for question in definition.get("questions", []):
|
||||
for option in question.get("options", []):
|
||||
option.pop("score", None)
|
||||
definition.pop("results", None)
|
||||
return Response({"version": assessment.version, "definition": definition})
|
||||
|
||||
|
||||
class MathBTISubmitView(APIView):
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
def post(self, request):
|
||||
assessment = get_object_or_404(
|
||||
MathBTIAssessment,
|
||||
version=request.data.get("version"),
|
||||
is_published=True,
|
||||
)
|
||||
identity_code, axis_scores = score_mathbti(
|
||||
assessment.definition,
|
||||
request.data.get("answers", []),
|
||||
)
|
||||
identity = get_object_or_404(MathIdentity, code=identity_code)
|
||||
if request.user.is_authenticated:
|
||||
result = MathBTIResult.objects.create(
|
||||
user=request.user,
|
||||
assessment=assessment,
|
||||
identity=identity,
|
||||
answers=request.data.get("answers", []),
|
||||
axis_scores=axis_scores,
|
||||
)
|
||||
initialize_math_identity(request.user, identity)
|
||||
result_id = result.id
|
||||
else:
|
||||
result_id = None
|
||||
return Response(
|
||||
{
|
||||
"id": result_id,
|
||||
"identity": {
|
||||
"code": identity.code,
|
||||
"name": identity.name,
|
||||
"clan": identity.clan,
|
||||
"mathematician": identity.mathematician,
|
||||
"description": identity.description,
|
||||
"portrait": identity.portrait,
|
||||
"initial_abilities": identity.initial_abilities,
|
||||
},
|
||||
"axis_scores": axis_scores,
|
||||
},
|
||||
status=status.HTTP_201_CREATED,
|
||||
)
|
||||
|
||||
|
||||
class StoryListView(APIView):
|
||||
permission_classes = [permissions.AllowAny]
|
||||
|
||||
def get(self, request):
|
||||
stories = Story.objects.filter(is_visible=True).order_by("kind", "title")
|
||||
return Response(
|
||||
[
|
||||
{
|
||||
"slug": story.slug,
|
||||
"title": story.title,
|
||||
"summary": story.summary,
|
||||
"kind": story.kind,
|
||||
"estimated_minutes": story.estimated_minutes,
|
||||
"available": story.versions.filter(is_published=True).exists(),
|
||||
}
|
||||
for story in stories
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class StoryStartView(APIView):
|
||||
def post(self, request, slug):
|
||||
story = get_object_or_404(Story, slug=slug, is_visible=True)
|
||||
return Response(start_story(request.user, story), status=status.HTTP_201_CREATED)
|
||||
|
||||
|
||||
class StoryRunView(APIView):
|
||||
def get(self, request, run_id):
|
||||
run = get_object_or_404(
|
||||
StoryRun.objects.select_related("story_version__story"),
|
||||
id=run_id,
|
||||
user=request.user,
|
||||
)
|
||||
return Response(get_run_payload(run))
|
||||
|
||||
|
||||
class StoryChoiceView(APIView):
|
||||
def post(self, request, run_id):
|
||||
get_object_or_404(StoryRun, id=run_id, user=request.user)
|
||||
payload = make_choice(
|
||||
run_id=run_id,
|
||||
user=request.user,
|
||||
choice_index=request.data.get("choice_index"),
|
||||
idempotency_key=request.headers.get("Idempotency-Key"),
|
||||
)
|
||||
return Response(payload)
|
||||
Reference in New Issue
Block a user