当前路径:app/common/model/exam/Question.php <?php declare(strict_types=1); namespace app\common\model\exam; use app\common\model\Base; use app\common\model\core\Excel; use app\control\model\User; use app\test\QuestionTest; use Error; use Exception; use mb\helper\Collection; use think\db\exception\DataNotFoundException; use think\db\exception\DbException; use think\db\exception\ModelNotFoundException; use think\facade\Db; use think\facade\Log; use think\Model; /** * Class Question * @package app\common\model\exam\test */ class Question { /** * 题型 */ public const TYPE = [ 'judge' => '判断题', 'choice' => '单选题', 'choices' => '多选题', 'composition' => '作文题', //作文 'fillIn' => '填空题', //填空 'answer' => '问答题', //问答 'typing' => '打字题', //打字 'handel' => '操作题', //操作 ]; public const MARKTYPE = [ 'composition', 'fillIn', 'answer', 'handel', ]; /** * 选择序号 */ public const CHOICES = [ '1' => 'A', '2' => 'B', '3' => 'C', '4' => 'D', '5' => 'E', '6' => 'F', '7' => 'G', '8' => 'H', '9' => 'I', '10' => 'J', '11' => 'K', ]; /** * 难度 */ public const DIFFICULTY_LEVEL = [ 'easy' => '易', 'moreEasily' => '较易', 'medium' => '中等', 'moreDifficult' => '较难', 'difficult' => '难', ]; public const EXPORT_FIELDS = [ '' => '', 'type' => '题型', 'name' => '基本内容', 'answer' => '正确答案', 'percent' => '得分率', 'A' => '选A', 'B' => '选B', 'C' => '选C', 'D' => '选D', 'E' => '选E', 'F' => '选F', ]; public const EXPORT_TYPE_FIELDS = [ '' => '', 'type' => '题型', 'questionNum' => '试题数量', 'score' => '试题分数', 'avg' => '平均分', 'percent' => '得分率', ]; /** * @param $questionInfo * @return bool|int|string */ public static function add($questionInfo) { $newRow = Collection::keyStyle($questionInfo, Collection::NAME_STYLE_C); $newRow = Collection::elements( [ 'name', 'options', 'answer', 'type', 'score', 'founder', 'difficulty_level', 'knowledge', 'subject', 'analysis', ], $newRow ); $newRow['created_time'] = time(); $newRow['score'] = 0; try { return Db::table('exam_questions') ->insertGetId($newRow); } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return false; } /** * @param $filters * @return array|Model|null */ public static function fetch($filters) { $where = self::parseFilters($filters); try { $questionInfo = Db::table('exam_questions') ->where($where) ->find(); if (!empty($questionInfo)) { $questionInfo['options'] = @unserialize($questionInfo['options']); $questionInfo['answer'] = @unserialize($questionInfo['answer']); return $questionInfo; } } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return []; } /** * @param $filters * @param $newState * @return bool */ public static function update($filters, array $newState) { $where = self::parseFilters($filters); $newState = Collection::keyStyle($newState, Collection::NAME_STYLE_C); try { $offect = Db::table('exam_questions') ->where($where) ->update($newState); if ($offect === 1) { return true; } return false; } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return false; } /** * @param $filters * @return bool */ public static function remove($filters) { $where = self::parseFilters($filters); try { $offect = Db::table('exam_questions') ->where($where) ->delete(); if (!empty($offect)) { return true; } return false; } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return false; } /** * @param $filters * @return array */ public static function parseFilters($filters) { $newFilters = []; if (is_array($filters)) { if (!empty($filters['id'])) { $newFilters[] = ['id', '=', $filters['id']]; } if (!empty($filters['ids'])) { $newFilters[] = ['id', 'in', $filters['ids']]; } if (!empty($filters['name'])) { $newFilters[] = ['name', '=', $filters['name']]; } if (empty($newFilters)) { throw error(-19, '缺少必填参数ID'); } if (!empty($filters['knowledge'])) { $newFilters[] = ['knowledge', '=', $filters['knowledge']]; } if (!empty($filters['founder'])) { $newFilters[] = ['founder', '=', $filters['founder']]; } } else { $newFilters[] = ['id', '=', intval($filters)]; } return $newFilters; } /** * filters.type * filters.knowledge * filters.subjects * filters.difficultyLevel * filters.name * filters.founder * array filters.order 排序列子 ['id' => 'desc'] * @param $filters * @param int $pIndex * @param int $pSize * @param int $total * @return array */ public static function search($filters, $pIndex = 1, $pSize = 10, &$total = 0) { $where = []; if (!empty($filters['type'])) { $where[] = ['type', '=', $filters['type']]; } if (!empty($filters['package'])) { $where[] = ['package', '=', $filters['package']]; } if (!empty($filters['knowledge'])) { $where[] = ['knowledge', '=', $filters['knowledge']]; } if (!empty($filters['subjects'])) { $where[] = ['subject', '=', $filters['subjects']]; } if (!empty($filters['subject'])) { $where[] = ['subject', '=', $filters['subject']]; } if (!empty($filters['difficultyLevel'])) { $where[] = ['difficulty_level', '=', $filters['difficultyLevel']]; } if (!empty($filters['name'])) { $where[] = ['name', 'like', "%{$filters['name']}%"]; } if (!empty($filters['founder'])) { $where[] = ['founder', '=', $filters['founder']]; } if (!empty($filters['ids'])) { $where[] = ['id', 'in', $filters['ids']]; } try { $total = Db::table('exam_questions') ->where($where) ->count(); $query = Db::table('exam_questions') ->where($where); if (!empty($pIndex)) { $query->page($pIndex, $pSize); } if (!empty($filters['order'])) { $query->order($filters['order']); } $dataSet = $query->select()->toArray(); if (!empty($dataSet)) { return array_map( function ($row) { $row['answer'] = unserialize($row['answer']); $row['options'] = unserialize($row['options']); $row['analysis'] = unserialize($row['analysis']); return Collection::keyStyle($row, Collection::NAME_STYLE_JAVA); }, $dataSet ); } } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return []; } /** * 导入excel * @param $excelUrl * @return array|Error */ public static function questionImport($excelUrl) { $error = []; $types = Base::exchangeKey(self::TYPE); $difficultys = Base::exchangeKey(self::DIFFICULTY_LEVEL); try { $subjects = Db::table('exam_subjects')->select()->toArray(); $subjects = Base::headelId('title', $subjects); } catch (Exception $e) { return error(-20, '科目查询失败'); } try { $knowledges = Db::table('exam_knowledge')->select()->toArray(); $knowledges = Base::headelId('title', $knowledges); } catch (Exception $e) { return error(-20, '科目查询失败'); } $currentUser = User::fetchCurrent(); $questionInfo = Excel::read( $excelUrl, [ ['field' => 'subject', 'column' => 'A'], ['field' => 'knowledge', 'column' => 'B'], ['field' => 'typeTitle', 'column' => 'C'], ['field' => 'difficultyLevel', 'column' => 'D'], // ['field' => 'score', 'column' => 'E'], ['field' => 'name', 'column' => 'E'], ['field' => 'options', 'column' => 'F'], ['field' => 'answer', 'column' => 'G'], ['field' => 'analysis', 'column' => 'H'], ] ); if (empty($questionInfo) || is_error($questionInfo)) { return error(-24, '文件错误,未读取到数据'); } $line = 1; foreach ($questionInfo as $k => $v) { $line++; if (is_object($v)) { $error[$line] = ['line' => $line, 'msg' => '模板格式有误']; continue; } $obj = false; foreach ($v as $item) { if (is_object($item)) { $obj = true; } } if ($obj) { $error[$line] = ['line' => $line, 'msg' => '内容存在格式错误']; continue; } $params = []; $params['founder'] = $currentUser['id']; if (empty($types[$v['typeTitle']])) { $error[$line] = ['line' => $line, 'msg' => '分类错误']; continue; } if (empty($difficultys[$v['difficultyLevel']])) { $error[$line] = ['line' => $line, 'msg' => '等级错误']; continue; } if (empty($subjects[$v['subject']])) { $error[$line] = ['line' => $line, 'msg' => '没有此科目:' . $v['subject']]; continue; } else { $params['subject'] = $subjects[$v['subject']]['id']; } if (empty($knowledges[$v['knowledge']])) { $error[$line] = ['line' => $line, 'msg' => '没有此知识点:' . $v['knowledge']]; continue; } else { $params['knowledge'] = $knowledges[$v['knowledge']]['id']; } // if (empty($v['score'])) { // $error[$line] = ['line' => $line, 'msg' => '该题没有分数']; // continue; // } if (empty($v['name'])) { $error[$line] = ['line' => $line, 'msg' => '该题题目不能为空']; continue; } if (empty($v['answer'])) { $error[$line] = ['line' => $line, 'msg' => '该题标准答案不能为空']; continue; } $params['type'] = $types[$v['typeTitle']]; $params['difficultyLevel'] = $difficultys[$v['difficultyLevel']]; // $params['score'] = $v['score']; $params['name'] = $v['name']; switch ($types[$v['typeTitle']]) { case 'fillIn': case 'answer': case 'composition': $params['answer'] = serialize($v['answer']); break; case 'handel': $params['answer'] = serialize(['url' => $v['answer']]); break; case 'judge': $params['answer'] = ($v['answer'] == '正确') ? 1 : 0; $params['answer'] = serialize($params['answer']); break; case 'choice': case 'choices': if (is_object($v['options'])) { $error[$line] = ['line' => $line, 'msg' => '选项模板格式有误']; break; } if (empty($v['options'])) { $error[$line] = ['line' => $line, 'msg' => '该题没有选项']; break; } $v['options'] = explode('|', $v['options']); $options = []; foreach ($v['options'] as $k1 => $v1) { $options[self::CHOICES[$k1 + 1]] = $v1; } $params['options'] = serialize($options); if ($types[$v['typeTitle']] == 'choice') { $params['answer'] = serialize($v['answer']); } else { $params['answer'] = serialize(str_split($v['answer'])); } break; case 'typing': $typingInfo = explode(',', $v['answer']); if (count($typingInfo) != 2) { $error[$line] = ['line' => $line, 'msg' => '参数错误']; } $params['answer'] = serialize(['time' => $typingInfo[0], 'number' => $typingInfo[1]]); break; default: $error[$line] = ['line' => $line, 'msg' => '题型错误']; break; } $filters = [ 'name' => $params['name'], 'knowledge' => $params['knowledge'] ]; $exists = Question::fetch($filters); if (!empty($exists)) { $error[$line] = ['line' => $line, 'msg' => '已存在此题']; } if (empty($error[$line])) { $params['analysis'] = serialize($v['analysis']); $result = Question::add($params); if (!$result) { $error[$line] = ['line' => $line, 'msg' => '添加失败']; } } } return $error; } /** * 统计题型分类 * 统计难度分类 * 统计知识点分类 * @param $subjectId * @return array|Error */ public static function statistics($subjectId) { $where = []; $where[] = ['subject', '=', $subjectId]; $count = [ 'questionCount' => 0, 'knowledgeCount' => 0, ]; try { $typeCount = Db::table('exam_questions') ->field('type,count(*) count') ->where($where) ->group('type') ->select()->toArray(); foreach ($typeCount as $v) { $count['questionCount'] += $v['count']; } $knowledgeCount = Db::table('exam_questions') ->field('knowledge type,count(*) count') ->where($where) ->group('knowledge') ->select()->toArray(); foreach ($typeCount as $v) { $count['knowledgeCount'] += $v['count']; } $difficultyCount = Db::table('exam_questions') ->field('difficulty_level type,count(*) count') ->where($where) ->group('difficulty_level') ->select()->toArray(); return [ 'typeCount' => $typeCount, 'knowledgeCount' => $knowledgeCount, 'difficultyCount' => $difficultyCount, 'count' => $count ]; } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return error(-20, '统计失败'); } /** * 根据科目统计试题 * @param $subjectId * @return int */ public static function questionCount($subjectId) { $where = []; $where[] = ['subject', '=', $subjectId]; try { return Db::table('exam_questions') ->where($where) ->count(); } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return 0; } /** * 判断答案是否正确 * @param $questionId * @param $content * @return bool|Error * @see QuestionTest::testQuestionVerify() */ public static function verify($questionId, $content) { $questionInfo = self::fetch(intval($questionId)); if (empty($questionInfo)) { return error(-20, '该题不存在'); } $type = $questionInfo['type']; if (!in_array($type, ['judge', 'choice', 'choices', 'fillIn'])) { return error(-21, '此题参考答案不能作为分数判断依据'); } if ($type == 'choices') { if (!is_array($content) || (count($questionInfo['answer']) != count($content))) { return false; } foreach ($questionInfo['answer'] as $answer) { if (!in_array($answer, $content)) { return false; } } } elseif ($content !== $questionInfo['answer']) { return false; } return true; } /** * 按照题库包分组聚合类型知识点科目 * @param $package * @param $group * @return array|array[]|\array[][] */ public static function group($package, $group) { $where = []; $where[] = ['package', '=', $package]; try { return Db::table('exam_questions')->where($where)->group($group)->field($group)->select()->toArray(); } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return error(-20, '统计失败'); } }
相关源码
- 可旋转的彩色立方体C#源代码2021-10-29
- 在线考试系统2021-10-15
- EduSoho开源网校系统源码2019-06-27
- 仿拼多多小程序商城源码2019-06-06
- PHP5网站运行监测系统源码2017-04-14
关于我们 | 顾问团队 | 发展历程 | 联系我们 | 源码上传
联系电话(Tel):4008-010-151(免长途)
地址:北京市海淀区大恒科技大厦五层 邮编:100080
Floor 5th,Daheng Building,Zhongguancun,Beijing,China,100080
51Aspx.com 版权所有 CopyRight © 2006-2022. 京ICP备09089570号 | 京公网安备11010702000869号
联系电话(Tel):4008-010-151(免长途)
地址:北京市海淀区大恒科技大厦五层 邮编:100080
Floor 5th,Daheng Building,Zhongguancun,Beijing,China,100080
51Aspx.com 版权所有 CopyRight © 2006-2022. 京ICP备09089570号 | 京公网安备11010702000869号