$fallbackKpCodes * @return array */ public function fromArray(array $question, array $fallbackKpCodes = []): array { $type = $this->normalizeQuestionType( (string) ($question['question_type'] ?? $question['type'] ?? '') ) ?? $this->guessType($question); $kpCode = (string) ($question['kp_code'] ?? $question['kp'] ?? $question['knowledge_point'] ?? $question['knowledge_point_code'] ?? ($fallbackKpCodes[0] ?? '')); $id = $question['id'] ?? $question['question_id'] ?? $question['question_bank_id'] ?? null; return [ 'id' => $id, 'question_id' => $question['question_id'] ?? $id, 'question_type' => $type, 'stem' => $question['stem'] ?? $question['content'] ?? ($question['question_text'] ?? ''), 'content' => $question['content'] ?? $question['stem'] ?? '', 'options' => $question['options'] ?? ($question['choices'] ?? []), 'answer' => $question['answer'] ?? $question['correct_answer'] ?? '', 'solution' => $question['solution'] ?? '', 'difficulty' => $this->normalizeDifficulty($question['difficulty'] ?? null), 'score' => $question['score'] ?? $this->defaultScore($type), 'estimated_time' => $question['estimated_time'] ?? 300, 'kp' => $kpCode, 'kp_code' => $kpCode, ]; } /** * @return array */ public function fromModel(Question $question): array { return $this->fromArray([ 'id' => $question->id, 'question_id' => $question->id, 'question_type' => $question->question_type, 'stem' => $question->stem, 'content' => $question->stem, 'options' => $question->options ?? [], 'answer' => $question->answer, 'solution' => $question->solution, 'difficulty' => $question->difficulty, 'kp_code' => $question->kp_code, ]); } public function normalizeQuestionType(?string $type): ?string { $type = strtolower(trim((string) $type)); if (in_array($type, ['choice', 'single_choice', 'multiple_choice', '选择题', '单选', '多选'], true)) { return 'choice'; } if (in_array($type, ['fill', 'fill_in_the_blank', 'blank', '填空题', '填空'], true)) { return 'fill'; } if (in_array($type, ['answer', 'calculation', 'word_problem', 'proof', '解答题', '计算题'], true)) { return 'answer'; } return null; } public function normalizeDifficulty(mixed $difficulty): float { if ($difficulty === null || $difficulty === '') { return 0.5; } $value = (float) $difficulty; if ($value > 1) { $value = $value / 5; } return max(0.0, min(1.0, $value)); } private function guessType(array $question): string { if (! empty($question['options']) && is_array($question['options'])) { return 'choice'; } $content = $question['stem'] ?? $question['content'] ?? ''; if (is_string($content) && (str_contains($content, '____') || str_contains($content, '()'))) { return 'fill'; } return 'answer'; } private function defaultScore(string $type): int { return match ($type) { 'choice', 'fill' => 5, default => 10, }; } }