$answer){ //判断答案的题目ID 是不是全在问题列表里 if(!in_array($key,$questionKeys)){ throw new \app\common\exception\Exception('答案数据异常'); } $type = $questionKeyVals[$key]['type']; //判断答案的范围是否正确 switch ($type){ case 'judge': if($answer > 1 || $answer < 0){ throw new \app\common\exception\Exception('判断题答案数据异常'); } break; case 'single': if($answer > (count($questionKeyVals[$key]['option']) - 1) || $answer < 0){ throw new \app\common\exception\Exception('单选题答案数据异常'); } break; case 'multiple': case 'indefinite': if(!is_array($answer)){ throw new \app\common\exception\Exception('多选题答案数据异常'); } foreach ($answer as $option){ if($option > (count($questionKeyVals[$key]['option']) - 1) || $option < 0){ throw new \app\common\exception\Exception('多选题答案数据异常'); } } break; case 'fillblank': if(!is_array($answer)){ throw new \app\common\exception\Exception('填空题答案数据异常'); } break; case 'essay': break; } $temp = [ 'question_id'=>$key, 'createtime'=>time() ]; $isCorrect = false; switch ($type){ case 'single': case 'judge': $temp['right_answer'] = $questionKeyVals[$key]['answer']; $temp['user_answer'] = $answer; $isCorrect = ($temp['right_answer'] == $temp['user_answer']); break; case 'multiple': case 'indefinite': $rightAnswer = $this->normalizeChoiceAnswer($questionKeyVals[$key]['answer']); $answer = $this->normalizeChoiceAnswer($answer); $temp['right_answer'] = implode(",",$rightAnswer); $temp['user_answer'] = implode(",",$answer); $isCorrect = ($rightAnswer == $answer); break; case 'fillblank': $rightAnswer = is_array($questionKeyVals[$key]['answer']) ? $questionKeyVals[$key]['answer'] : json_decode($questionKeyVals[$key]['answer'],true); $temp['right_answer'] = json_encode($rightAnswer,JSON_UNESCAPED_UNICODE); $temp['user_answer'] = json_encode($answer,JSON_UNESCAPED_UNICODE); $isCorrect = $this->checkFillblankAnswer($answer,$rightAnswer); break; case 'essay': $temp['right_answer'] = $questionKeyVals[$key]['answer']; $temp['user_answer'] = (is_array($answer) || is_object($answer)) ? json_encode($answer, JSON_UNESCAPED_UNICODE) : $answer; $isCorrect = false; break; } if($isCorrect){ $trueCount++; $temp['result'] = 1; $temp['error_book_show'] = 0; }else{ $temp['result'] = 0; // 问答题属于主观题,不纳入错题本 $temp['error_book_show'] = ($type == 'essay') ? 2 : 1; if($type != 'essay'){ $errorCount++; } } $result[] = $temp; } return [ 'answer_list'=>$result, 'error_count'=>$errorCount, 'true_count'=>$trueCount, ]; } /** * 校验填空题答案 * @param array $userAnswer 用户答案 * @param array $rightAnswer 正确答案 * @return bool */ protected function checkFillblankAnswer($userAnswer,$rightAnswer){ if(empty($rightAnswer) || empty($userAnswer)){ return false; } if(count($userAnswer) != count($rightAnswer)){ return false; } foreach ($rightAnswer as $index => $acceptedAnswers){ $userBlankAnswer = isset($userAnswer[$index]) ? trim($userAnswer[$index]) : ''; $blankCorrect = false; if(!is_array($acceptedAnswers)){ $acceptedAnswers = [$acceptedAnswers]; } foreach ($acceptedAnswers as $acceptedAnswer){ if(strcasecmp(trim($acceptedAnswer),$userBlankAnswer) === 0){ $blankCorrect = true; break; } } if(!$blankCorrect){ return false; } } return true; } /** * 规范化选择题答案,避免多选/不定项因顺序不同误判。 * @param mixed $answer * @return array */ protected function normalizeChoiceAnswer($answer) { if(!is_array($answer)){ $answer = ($answer === '' || $answer === null) ? [] : explode(",",$answer); } $result = []; foreach ($answer as $item){ if($item === '' || $item === null){ continue; } $result[] = intval($item); } $result = array_values(array_unique($result)); sort($result, SORT_NUMERIC); return $result; } /** * 博阿村答案 * @param $userId * @param $logId * @param $answerList * @return void */ public function saveAnswer($userId,$exercisesId,$logId,$answerList){ foreach ($answerList as &$item){ $item['createtime'] = time(); $item['exercises_log_id'] = $logId; $item['exercises_id'] = $exercisesId; $item['user_id'] = $userId; $item['uniacid'] = UNIACID; } return self::insertAll($answerList); } /** * 获取用户提交的答案 * @param $userId * @param $exercisesId * @param $logId * @return array */ public function getUserAnswer($userId,$exercisesId,$logId = 0){ $where = [ 'user_id'=>$userId ]; if($exercisesId){ $where['exercises_id'] = $exercisesId; } if($logId){ $where['exercises_log_id'] = $logId; } $list = self::with(['warehouse_question'])->where($where)->group('question_id')->order('id','desc')->select(); $data = []; if(!$list){ return $data; } $list = collection($list)->toArray(); foreach ($list as $item){ $type = isset($item['warehouse_question']['type']) ? $item['warehouse_question']['type'] : ''; switch ($type){ case 'multiple': case 'indefinite': $data[$item['question_id']] = []; foreach (explode(",",$item['user_answer']) as $option){ $data[$item['question_id']][] = intval($option); } break; case 'fillblank': $data[$item['question_id']] = json_decode($item['user_answer'],true); break; case 'essay': $decoded = json_decode($item['user_answer'], true); $data[$item['question_id']] = is_array($decoded) ? $decoded : $item['user_answer']; break; default: $data[$item['question_id']] = intval($item['user_answer']); } } return $data; } public function warehouseQuestion() { return $this->belongsTo('app\api\model\app\exam\WarehouseQuestion', 'question_id', 'id', [], 'LEFT')->setEagerlyType(0); } }