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

<?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;
}
}
}