当前路径:app/common/model/exam/paper/Record.php <?php declare(strict_types=1); namespace app\common\model\exam\paper; use app\common\model\account\Department; use app\common\model\account\User as UserModel; use app\common\model\Base; use app\common\model\exam\Paper; use app\common\model\exam\Question; use app\control\model\User; use Exception; use mb\helper\Collection; use think\facade\Db; use think\facade\Log; /** * Class Record * @package app\common\model\exam\paper */ class Record { public const EXPORT_FIELDS = [ '' => '', 'id' => '序号', 'uid' => '账号', 'name' => '姓名', 'gender' => '性别', 'score' => '成绩', 'pass' => '结果', 'department' => '部门', 'duty' => '职务', 'company' => '单位', 'birthday' => '出生年月日', 'phone' => '电话', 'cardType' => '证件类型', 'cardNum' => '证件号码', ]; /** * @param $filter * @param $pIndex * @param $pSize * @param $total * @return array */ public static function search(array $filter, int $pIndex = 1, int $pSize = 10, &$total = 0) { $where = []; if (!empty($filter['paperId'])) { $where[] = ['rec.paper_id', '=', $filter['paperId']]; } if (!empty($filter['departmentId'])) { $where[] = ['dep.id', '=', $filter['departmentId']]; } if (!empty($filter['dutyId'])) { $where[] = ['user.duty', '=', $filter['dutyId']]; } if (!empty($filter['userId'])) { //查某人的卷子 $where[] = ['rec.user_id', '=', $filter['userId']]; } if (!empty($filter['uid'])) { //按用户uid查询 $where[] = ['user.uid', 'like', "%{$filter['uid']}%"]; } if (!empty($filter['name'])) { $where[] = ['user.name', 'like', "%{$filter['name']}%"]; } if (!empty($filter['status'])) { $where[] = ['rec.status', '=', $filter['status']]; } if (!empty($filter['markStatus'])) { $where[] = ['rec.mark_status', '=', $filter['markStatus']]; } if (!empty($filter['symbol'])) { $where[] = ['rec.score', $filter['symbol'], $filter['score']]; } if (!empty($filter['timeStart'])) { $where[] = ['rec.time_end', '>=', strtotime($filter['timeStart'])]; } if (!empty($filter['timeEnd'])) { $where[] = ['rec.time_end', '<=', strtotime($filter['timeEnd'])]; } if (!empty($filter['type'])) { $where[] = ['paper.type', '=', $filter['type']]; } if (!empty($filter['personal'])) { $where[] = ['paper.time_end', '<=', time()]; } try { $total = Db::table('exam_paper_records')->alias('rec')->join('exam_papers paper', 'rec.paper_id = paper.id') ->leftJoin('account_users user', 'rec.user_id = user.id') ->leftJoin('account_departments dep', 'user.department = dep.id')->where($where)->count(); $query = Db::table('exam_paper_records')->alias('rec')->join('exam_papers paper', 'rec.paper_id = paper.id') ->leftJoin('account_users user', 'rec.user_id = user.id') ->leftJoin('account_departments dep', 'user.department = dep.id')->where($where) ->field( 'rec.*,user.uid,user.name,user.gender,user.department,user.duty, user.company,user.phone,user.birthday,user.card_type,user.card_num,paper.title,paper.through_points' ); if (!empty($pIndex)) { $query->page($pIndex, $pSize); } $dataSet = $query->select()->toArray(); return array_map( function ($val) { return Collection::keyStyle($val, Collection::NAME_STYLE_JAVA); }, $dataSet ); } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return []; } /** * @param array $data * @return int|string */ public static function add(array $data) { $newData = Collection::keyStyle($data, Collection::NAME_STYLE_C); try { return Db::table('exam_paper_records')->insertGetId($newData); } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return 0; } /** * @param $filter * @param array $data * @return bool * @throws \think\Exception */ public static function update($filter, array $data) { $filter = self::parseFilters($filter); $newData = Collection::keyStyle($data, Collection::NAME_STYLE_C); try { $res = Db::table('exam_paper_records')->where($filter)->update($newData); if ($res === 1) { return true; } return false; } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return false; } /** * @param $filter * @return float|int|string * @throws \think\Exception */ public static function recordNum($filter) { $filter = self::parseFilters($filter); try { $num = Db::table('exam_paper_records')->where($filter)->group('user_id')->count(); return $num; } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return 0; } /** * @param $filter * @return array|int * @throws \think\Exception */ public static function joinUser($filter) { $filter = self::parseFilters($filter); try { $user = Db::table('exam_paper_records')->where($filter)->group('user_id')->field('user_id')->select(); if (empty($user)) { return []; } return Base::neaten($user, 'user_id'); } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return 0; } /** * @param $filters * @return array * @throws \think\Exception */ public static function parseFilters($filters) { $newFilters = []; if (is_array($filters)) { if (!empty($filters['id'])) { $newFilters[] = ['id', '=', $filters['id']]; } if (empty($filters)) { throw error(-19, '缺少必填参数ID'); } if (!empty($filters['paper'])) { $newFilters[] = ['paper_id', '=', $filters['paper']]; } if (!empty($filters['user'])) { $newFilters[] = ['user_id', '=', $filters['user']]; } } else { $newFilters[] = ['id', '=', intval($filters)]; } return $newFilters; } /** * @param string $type * @param string $ids * @return bool */ public static function delete(string $type, string $ids) { if ($type == 'single') { $where[] = ['id', '=', $ids]; } else { $where[] = ['id', 'in', "{$ids}"]; } try { $offect = Db::table('exam_paper_records') ->where($where) ->delete(); if ($offect) { return true; } return false; } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return false; } /** * 通过试卷id删除记录 * @param string $id * @return bool */ public static function deleteRecord(string $id) { $where[] = ['paper_id', '=', $id]; try { $offect = Db::table('exam_paper_records') ->where($where) ->delete(); if ($offect) { return true; } return false; } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return false; } /** * @param $filter * @return array * @throws \think\Exception */ public static function fetch($filter) { $filter = self::parseFilters($filter); try { return Db::table('exam_paper_records')->where($filter)->find(); } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return []; } /** * @param $filter * @return array * @throws \think\Exception */ public static function fetchRec($filter) { $filter = self::parseFilters($filter); try { return Db::table('exam_paper_records')->where($filter)->order('id', 'desc')->find(); } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return []; } /** * @param $filter * @param $type * @return float|int|mixed|string * @throws \think\Exception */ public static function score($filter, $type) { if (!empty($filter['paper'])) { $where[] = ['paper_id', '=', $filter['paper']]; } if (!empty($filter['department'])) { $where[] = ['department', '=', $filter['department']]; } $query = Db::table('exam_paper_records')->alias('rec')->join('account_users user', 'rec.user_id = user.id', 'LEFT')->where($where); $score = 0; try { switch ($type) { case 'avg': $score = $query->avg('score'); break; case 'max': $score = $query->max('score'); break; case 'min': $score = $query->min('score'); break; default: return 0; } return sprintf("%.1f", $score); } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return $score; } public static function examPass($filter) { try { $where = "paper.`id` = {$filter['paper']} and rec.status = 'end' and rec.score > paper.through_points and paper.time_end <= " . time(); if (!empty($filter['department'])) { $where .= " and user.department = {$filter['department']}"; } $query = Db::table('exam_paper_records')->alias('rec')->join('exam_papers paper', 'rec.paper_id = paper.id')->join('account_users user', 'rec.user_id = user.id', 'left') ->where($where)->field( 'rec.*,paper.title,paper.through_points' ); return $query->count(); } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return 0; } /** * @param string $type * @return float|int|string */ public static function passNum($type = '') { $user = User::fetchCurrent(); try { $where = "user_id = {$user['id']} and rec.status = 'end' and rec.score > paper.through_points and paper.time_end <= " . time(); if (!empty($type)) { $where .= " and paper.`type` = '{$type}'"; } $query = Db::table('exam_paper_records')->alias('rec')->join('exam_papers paper', 'rec.paper_id = paper.id') ->where($where)->field( 'rec.*,paper.title,paper.through_points' ); return $query->count(); } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return 0; } /** * 获取用户考试排名 * @param int $paperId * @param int $recordId * @return int */ public static function serial(int $paperId, int $recordId) { // $query = "SELECT t4.* FROM ( // select t1.*,(@num := @num+1) as rank // from exam_paper_records as t1,(select (@num := 0)) as t3 where score = ( // select max(score) from exam_paper_records as t2 where t2.user_id = t1.user_id) // AND t1.paper_id = 22 ORDER BY score desc) as t4 where user_id = 1"; //相同成绩按照id排 /*$query = "select *, ( select count(DISTINCT score) from ( select t1.* from exam_paper_records as t1 where score = ( select max(score) from exam_paper_records as t2 where t2.user_id = t1.user_id ) AND t1.paper_id = 22) AS b WHERE a.score<b.score)+1 AS rank from ( select t1.* from exam_paper_records as t1 where score = ( select max(score) from exam_paper_records as t2 where t2.user_id = t1.user_id ) AND t1.paper_id = 22) AS a ORDER BY rank";*/ try { /*$query = "select * from ( select *, ( select count(DISTINCT score) from ( select t1.* from exam_paper_records as t1 where score = ( select max(score) from exam_paper_records as t2 where t2.user_id = t1.user_id ) AND t1.paper_id = $paperId ) AS b WHERE a.score<b.score)+1 AS rank from ( select t1.* from exam_paper_records as t1 where score = ( select max(score) from exam_paper_records as t2 where t2.user_id = t1.user_id ) AND t1.paper_id = $paperId ) AS a ORDER BY rank ) as t5 where t5.user_id = $userId";*/ /*$query = "select *, ( select count(DISTINCT score) from ( select t1.* from exam_paper_records as t1 where score = ( select max(score) from exam_paper_records as t2 where t2.user_id = t1.user_id ) AND t1.paper_id = $paperId ) AS b WHERE a.score<b.score)+1 AS rank from ( select t1.* from exam_paper_records as t1 where t1.paper_id = $paperId ) AS a where id = $recordId ORDER BY rank"; $res = Db::query($query);*/ $res = Db::table('exam_paper_records') ->where(['paper_id' => $paperId, 'status' => 'end']) ->order('score', 'desc')->field('id')->select()->toArray(); $ids = Base::neaten($res, 'id'); $rank = array_search($recordId, $ids); return $rank + 1; } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return 0; } /** * 更新成绩和结果 * @param $filter * @param $result * @return bool * @throws \think\Exception */ public static function updateResult($filter, $result) { $record = self::fetch($filter); $paper = Paper::fetch($record['paper_id']); $questionType = unserialize($paper['question_type']); $questionType = array_map( function ($val) { $val = $val['point']; return $val; }, $questionType ); $fillIn = $paper['completion'] ? true : false; $res = self::grade($result, $questionType, $fillIn); $res['result'] = serialize($res['result']); $user = User::fetchCurrent(); $res['mark_id'] = $user['id']; $res['mark_status'] = 'end'; try { $filter = self::parseFilters($filter); $offect = Db::table('exam_paper_records')->where($filter)->update($res); if ($offect === 1) { return true; } } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return false; } /** * 计算并返回成绩和结果 * @param array $result 试题结果 * @param array $questionType 题型和对应分值 * @param bool $fillIn 填空题是否自动评 * @return array */ public static function grade(array $result, array $questionType, $fillIn = false) { $array = ['judge', 'choice', 'choices']; if ($fillIn) { array_push($array, 'fillIn'); } $score = 0; foreach ($result as $key => &$item) { foreach ($item as &$val) { if (in_array($key, $array)) { $res = Question::verify($val['id'], $val['answer']); if ($res) { $val['score'] = $questionType[$key]; } } $score += $val['score']; } } return ['score' => $score, 'result' => $result]; } /** * 检测是否有评卷权限 * @param $filter * @return bool * @throws \think\Exception */ public static function markRole($filter) { $user = User::fetchCurrent(); if (!in_array($user['role'], ['root', 'manager'])) { return false; } $record = self::fetch($filter); if (empty($record)) { return false; } if ($user['role'] != 'root') { $where = "`paper_id` = {$record['paper_id']}"; $department = Department::fetch($user['department']); if (!empty($department)) { $where .= " and (`type` = '' or (`type` = 'user' and `binding_id` = {$user['id']}) or (`type` = 'department' and `binding_id` = {$department['first']}) or (`type` = 'department' and `binding_id` = {$user['department']}))"; } else { $where .= " and (`type` = '' or (`type` = 'user' and `binding_id` = {$user['id']}) or (`type` = 'department' and `binding_id` = {$user['department']}))"; } try { $res = Db::table('exam_paper_mark')->where($where)->find(); if (empty($res)) { return false; } return true; } catch (Exception $e) { Log::channel('myError')->write($e->getMessage(), \think\Log::ERROR); } return false; } return true; } /** * 试卷预览 * @param int $recordId 考试记录id * @param string $type 类型 all -- 全部展示 wrong -- 错题展示 * @return array * @throws \think\Exception */ public static function preview(int $recordId, string $type) { $record = self::fetch($recordId); $record['result'] = unserialize($record['result']); $paper = Paper::fetch(intval($record['paper_id'])); $show = Paper::sort(unserialize($paper['question_type']), $record['result'], $paper['way']); $question = []; $questionNum = 0; foreach ($record['result'] as $val) { $question = array_merge($question, $val); array_map( function ($i) use (&$questionNum) { $questionNum++; }, $val ); } $questionIds = Base::neaten($question, 'id'); $questionArr = Question::search(['ids' => $questionIds], 0); $questionArr = Collection::key($questionArr, 'id'); $show = array_filter( array_map( function ($item) use ($questionArr, $type) { $item = array_map( function ($value) use ($questionArr, $type) { if ((($type == 'wrong') && empty($value['score'])) || ($type != 'wrong')) { if (!isset($questionArr[$value['id']])) { return []; } $value = [ 'id' => $value['id'], 'name' => $questionArr[$value['id']]['name'], 'options' => $questionArr[$value['id']]['options'], 'questionAnswer' => $questionArr[$value['id']]['answer'], 'studentAnswer' => $value['answer'], 'analysis' => $questionArr[$value['id']]['analysis'], 'score' => $value['score'], ]; } else { $value = []; } return $value; }, $item ); $item = array_values(array_filter(array_values($item))); return $item; }, $show ) ); $user = UserModel::fetch($record['user_id']); $dataSet = [ 'title' => $paper['title'], 'userId' => $user['uid'], 'userName' => $user['name'], 'questionNum' => $questionNum, 'totalPoints' => $paper['total_points'], 'throughPoints' => $paper['through_points'], 'score' => $record['score'], 'timeEnd' => $record['time_end'], 'markId' => $record['mark_id'], 'show' => $show, 'questionType' => unserialize($paper['question_type']) ]; if ($dataSet['markId']) { $userInfo = UserModel::fetch($dataSet['markId']); $dataSet['markTitle'] = isset($userInfo['uid']) ? $userInfo['uid'] : ''; } else { $dataSet['markTitle'] = ''; } return $dataSet; } }
相关源码
- 可旋转的彩色立方体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号