You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
5.4 KiB
144 lines
5.4 KiB
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Question;
|
|
use App\Models\QuestionBlank;
|
|
use App\Models\QuestionChoice;
|
|
use App\Models\QuestionGroup;
|
|
use App\Models\QuestionType;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class QuestionService
|
|
{
|
|
|
|
public function __construct(
|
|
QuestionGroupService $questionGroupService
|
|
)
|
|
{
|
|
$this->questionGroupService = $questionGroupService;
|
|
}
|
|
|
|
public function createQuestion($data, $exerciseId)
|
|
{
|
|
$now = now();
|
|
$groupData = [];
|
|
$dataQuestion = [];
|
|
$dataQuestionChoices = [];
|
|
$dataQuestionBlank = [];
|
|
$questionMap = [];
|
|
|
|
DB::beginTransaction();
|
|
try {
|
|
// 1. Chuẩn bị groupData
|
|
foreach ($data as $groupKey => $value) {
|
|
$groupData[] = [
|
|
'content' => $value->title,
|
|
'exercise_id' => $exerciseId,
|
|
'is_question_order_fixed' => $value->is_question_order_fixed,
|
|
'is_option_order_fixed' => $value->is_option_order_fixed,
|
|
'position' => $groupKey + 1,
|
|
'paragraph' => $value->paragraph,
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
];
|
|
}
|
|
|
|
// 2. Insert group & lấy lại id
|
|
QuestionGroup::insert($groupData);
|
|
$groupIds = QuestionGroup::where('exercise_id', $exerciseId)
|
|
->orderByDesc('id')
|
|
->take(count($groupData))
|
|
->get()
|
|
->reverse()
|
|
->pluck('id')
|
|
->values()
|
|
->toArray();
|
|
|
|
// 3. Chuẩn bị question
|
|
$questionIndex = 0;
|
|
foreach ($data as $groupKey => $value) {
|
|
$groupId = $groupIds[$groupKey];
|
|
foreach ($value->questions as $qIndex => $question) {
|
|
$questionType = QuestionType::where('code', $question->type)->first();
|
|
$questionTypeId = $questionType ? $questionType->id : 1;
|
|
$dataQuestion[] = [
|
|
'exercise_id' => $exerciseId,
|
|
'content' => $question->content,
|
|
'description' => $question->description ?? null,
|
|
'group_id' => $groupId,
|
|
'question_type_id' => $questionTypeId,
|
|
'level' => 2,
|
|
'score' => $question->score ?? null,
|
|
'explanation' => $question->explanation ?? null,
|
|
'hint' => $question->hint ?? null,
|
|
'created_at' => $now,
|
|
'updated_at' => $now
|
|
];
|
|
$questionMap["{$groupKey}_{$qIndex}"] = [
|
|
'type' => $question->type,
|
|
'options' => $question->options ?? [],
|
|
'answers' => $question->answers ?? [],
|
|
];
|
|
$questionIndex++;
|
|
}
|
|
}
|
|
|
|
// 4. Insert question & lấy lại theo custom_key
|
|
Question::insert($dataQuestion);
|
|
|
|
$questions = Question::where('exercise_id', $exerciseId)->get();
|
|
// $questionsByKey = $questions->keyBy(function ($item) {
|
|
// return "{$item->group_id}_{$item->position}"; // hoặc dùng custom_key nếu có
|
|
// });
|
|
|
|
// 5. Mapping lại options/answers
|
|
$qIndex = 0;
|
|
foreach ($questionMap as $key => $meta) {
|
|
$questionId = $questions[$qIndex]->id ?? null;
|
|
if (!$questionId) continue;
|
|
|
|
if ($meta['type'] == 'multiple_choice') {
|
|
foreach ($meta['options'] as $optKey => $option) {
|
|
$dataQuestionChoices[] = [
|
|
'question_id' => $questionId,
|
|
'label' => $option->label,
|
|
'content' => $option->content,
|
|
'is_correct' => $option->is_correct,
|
|
'position' => $optKey + 1,
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
];
|
|
}
|
|
} else {
|
|
foreach ($meta['answers'] as $ansKey => $answer) {
|
|
$dataQuestionBlank[] = [
|
|
'question_id' => $questionId,
|
|
'correct_answer' => $answer->answer_true,
|
|
'other_answers' => json_encode($answer->other_answers),
|
|
'position' => $ansKey + 1,
|
|
'created_at' => $now,
|
|
'updated_at' => $now,
|
|
];
|
|
}
|
|
}
|
|
|
|
$qIndex++;
|
|
}
|
|
|
|
if (!empty($dataQuestionChoices)) {
|
|
QuestionChoice::insert($dataQuestionChoices);
|
|
}
|
|
|
|
if (!empty($dataQuestionBlank)) {
|
|
QuestionBlank::insert($dataQuestionBlank);
|
|
}
|
|
|
|
DB::commit();
|
|
} catch (\Throwable $e) {
|
|
DB::rollBack();
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
}
|
|
|