当前路径:app/control/controller/exam/Paper.php <?php declare(strict_types=1); namespace app\control\controller\exam; use app\BaseController; use app\common\model\account\Department; use app\common\model\account\User as UserModel; use app\common\model\exam\Knowledge; use app\common\model\exam\paper\Record; use app\common\model\exam\Subject; use app\control\model\User; use app\Request; use mb\helper\Collection; use think\response\Json; use app\common\model\exam\Paper as ModelPaper; use app\common\model\exam\Question; /** * Class Paper * @package app\control\controller\exam */ class Paper extends BaseController { /** * @param Request $request * @return Json * @api {post} /exam/paper/search 试卷列表 * @apiGroup Exam-paper * @apiName sort1 * @apiVersion 1.0.0 * * @apiDescription 试卷列表 * * @apiParam {String} type 考试类型<br>competition -- 竞赛级别<br>promote -- 提升级<br>beginner -- 入门级<br>simulate -- 模拟考 * @apiParam {Number} [current] 页码 * @apiParam {Number} [pageSize] 页数 * @apiParam {String} [title] 试卷名称 * @apiParam {String} [timeStart] 显示起始时间 * @apiParam {String} [timeEnd] 显示结束时间 * @apiParam {String} [mode] 组卷方式 hand -- 手工组卷 random -- 随机组卷 * * @apiSuccess {Number} code 状态码,0:请求成功 * @apiSuccess {String} message 提示信息 * @apiSuccess {Object} dataSet 返回数据 * * @apiSuccessExample {json} Success-Response: * {"code":0,"message":"","dataSet":[], "total" : 0} * * @apiErrorExample {json} Error-Response: * {"code":5001,"message":"接口异常"} */ public function search(Request $request) { $input = $request->post(); $pageIndex = empty($input['current']) ? 1 : intval($input['current']); $pageSize = empty($input['pageSize']) ? 10 : intval($input['pageSize']); $total = 0; $filters = []; // $type = empty($input['type']) ? 'competition' : $input['type']; // $filters['type'] = $type; if (!empty($input['title'])) { $filters['title'] = $input['title']; } if (!empty($input['timeStart'])) { $filters['timeStart'] = $input['timeStart']; } if (!empty($input['timeEnd'])) { $filters['timeEnd'] = $input['timeEnd']; } if (!empty($input['mode'])) { $filters['mode'] = $input['mode']; } $dataSet = ModelPaper::search($filters, $pageIndex, $pageSize, $total); $dataSet = array_map( function ($val) { $val['questionType'] = unserialize($val['questionType']); $totalNum = 0; foreach ($val['questionType'] as $item) { $totalNum += $item['questionNum']; } unset($val['questionType']); $val['totalQuestionNum'] = $totalNum; return $val; }, $dataSet ); return payload(['dataSet' => $dataSet, 'total' => $total]); } /** * @param Request $request * @return Json * @throws \think\Exception * @api {post} /exam/paper/add 试卷新增/修改 * @apiGroup Exam-paper * @apiName sort2 * @apiVersion 1.0.0 * * @apiDescription 试卷新增/修改 * * @apiParam {Number} [id] 试卷id * @apiParam {String} type 考试类型<br>competition -- 竞赛级别<br>promote -- 提升级<br>beginner -- 入门级<br>simulate -- 模拟考 * @apiParam {String} title 试卷名称 * @apiParam {String} mode 组卷方式 random -- 随机组卷 <br> hand -- 手工组卷 * @apiParam {String} way 出题方式 fixed -- 题序固定 <br> random -- 题序随机 <br> question -- 试题随机 * @apiParam {Number} display 显示模式 1 -- 整卷 2 -- 逐题 * @apiParam {Number} time 考试时间 * @apiParam {Number} totalPoints 试卷总分 * @apiParam {Number} throughPoints 通过分数 * @apiParam {String} timeStart 答题起始时间 * @apiParam {String} timeEnd 答题结束时间 * @apiParam {String[]} strategies 策略 <br>随机组卷时传['type' => 'judge','knowledge' => 2,'subject' => 3,'strategy' => [ * ['level' => 'easy', 'num' => 0], ['level' => 'moreEasily', 'num' => 1], * ['level' => 'medium', 'num' => 0], ['level' => 'moreDifficult', 'num' => 0], ['level' => 'difficult', 'num' => 0] * ]],<br> 手工组卷时传['type' => 'judge', 'knowledge' => 2, 'subject' => 3, 'strategy' => [1, 2, 3]], * @apiParam {String[]} questionType 题型设置 type -- 类型 point -- 分值 questionNum 题量 order -- 顺序 <br> * ['type' => 'judge','point' => 1,'questionNum' => 2,'order' => 1], * @apiParam {Number} definition 分数定义 1 -- 使用试卷定义分值 2 -- 使用题库定义分值 默认是1 * @apiParam {Number} multiple 允许多次考试 0 -- 不允许 1 -- 允许 * @apiParam {Number} result 允许查看结果 0 -- 不允许 1 -- 允许 * @apiParam {Number} completion 允许填空类自动判卷 0 -- 不允许 1 -- 允许 * @apiParam {Number} save 自动保存答卷时长 * @apiParam {String[]} watch 查看人员 * @apiParam {String[]} mark 批卷人 * * @apiSuccess {Number} code 状态码,0:请求成功 * @apiSuccess {String} message 提示信息 * @apiSuccess {Object} dataSet 返回数据 * * @apiSuccessExample {json} Success-Response: * {"code":0,"message":"","dataSet":[], "total" : 0} * * @apiErrorExample {json} Error-Response: * {"code":5001,"message":"接口异常"} */ public function add(Request $request) { $currentUser = User::fetchCurrent(); $input = $request->post(); $data = Collection::elements( [ 'title', 'type', 'mode', 'way', 'display', 'time', 'totalPoints', 'throughPoints', 'strategies', 'questionType', 'timeStart', 'timeEnd' ], $input ); foreach ($data as $v) { if (empty($v)) { return payload(error(-1, '参数不完整')); } } if ( !in_array($data['mode'], ModelPaper::MODE) || !in_array($data['type'], ModelPaper::TYPE) || !in_array($data['way'], ModelPaper::WAY) || !is_array($data['strategies']) || !is_array($data['questionType']) || !in_array($data['display'], [1, 2]) ) { return payload(error(-2, '参数错误')); } if (($data['mode'] == 'hand') && ($data['way'] == 'question')) { return payload(error(-9, '手工组卷不支持试题随机')); } $id = empty($input['id']) ? 0 : intval($input['id']); if (!empty($id)) { $record = Record::recordNum(['paper' => intval($id)]); if (!empty($record)) { return payload(error(-1, '该考卷已被使用,请先删除答卷再进行修改')); } } if (!empty($id) && !ModelPaper::check($id)) { return payload(error(-11, '您暂无操作权限')); } $data['definition'] = !empty($input['definition']) ? intval($input['definition']) : 1; $data['multiple'] = !empty($input['multiple']) ? intval($input['multiple']) : 0; $data['result'] = !empty($input['result']) ? intval($input['result']) : 0; $data['completion'] = !empty($input['completion']) ? intval($input['completion']) : 0; $data['save'] = !empty($input['save']) ? intval($input['save']) : 0; $data['question_type'] = Collection::key($data['questionType'], 'type'); $questionType = []; //判断题目数量是否正确 foreach ($data['strategies'] as &$str) { if (!isset($questionType[$str['type']])) { $questionType[$str['type']] = [ 'type' => $str['type'], 'num' => 0 ]; } $questionNum = 0; if ($data['mode'] == 'hand') { $questionNum += count($str['strategy']); } else { foreach ($str['strategy'] as $v) { $questionNum += $v; } } $questionType[$str['type']]['num'] += $questionNum; } $totalPoint = 0; foreach ($questionType as $que) { if ($data['question_type'][$que['type']]['questionNum'] != $que['num']) { return payload(error(-20, '题型数量有误')); } $totalPoint += $data['question_type'][$que['type']]['point'] * $que['num']; } if ($totalPoint != $data['totalPoints']) { return payload(error(-88, '总分不一致')); } $data['founder'] = $currentUser['id']; $data['watch'] = $input['watch']; $data['mark'] = $input['mark']; $data['timeStart'] = strtotime($data['timeStart']); $data['timeEnd'] = strtotime($data['timeEnd']); $id = ModelPaper::modify($data, $id); if (is_error($id)) { return payload(error(-10, '题库策略发生变更,请修改试题策略')); } if (!$id) { return payload(error(-99, '新增失败')); } return payload(['id' => $id]); } /** * @param Request $request * @return Json * @api {post} /exam/paper/strategy 生成策略 * @apiGroup Exam-paper * @apiName sort3 * @apiVersion 1.0.0 * * @apiDescription 生成策略 * * @apiParam {String} mode 组卷方式 random -- 随机组卷 hand -- 手工组卷 * @apiParam {Number} [subjectId] 科目id * @apiParam {String[]} [knowledgeId] 知识点id 传数组[1] * @apiParam {String} [type] 题型名称 judge choice * * @apiSuccess {Number} code 状态码,0:请求成功 * @apiSuccess {String} message 提示信息 * @apiSuccess {Object} dataSet 手工组卷返回数据 * @apiSuccess {Number} dataSet.id 试题id 手工组卷时返回 * @apiSuccess {String} dataSet.subjectTitle 科目名称 公共部分 * @apiSuccess {String} dataSet.knowledgeTitle 知识点名称 公共部分 * @apiSuccess {String} dataSet.type 题型名称 公共部分 * @apiSuccess {String} dataSet.name 试题内容 手工组卷时返回 * @apiSuccess {Number} dataSet.createdTime 试题创建时间 手工组卷时返回 * @apiSuccess {String} dataSet.score 试题分数 手工组卷时返回 * @apiSuccess {String} dataSet.difficultyLevel 试题难度 手工组卷时返回 * @apiSuccess {String} dataSet.founderTitle 创建人 手工组卷时返回 * @apiSuccess {Number} dataSet.knowledge 知识点id 随机组卷时返回 * @apiSuccess {Number} dataSet.subject 科目id 随机组卷时返回 * @apiSuccess {String[]} dataSet.strategy 策略 随机组卷时返回 * @apiSuccess {String} dataSet.strategy.level 难度 随机组卷时返回 * @apiSuccess {Number} dataSet.strategy.questionNum 题目数量 随机组卷时返回 * * @apiSuccessExample {json} 手工组卷结果: * {"errCode": 0,"errMsg": "ok","dataSet": [ * {"id": 13,"name": "测试判断题","options": "a:0:{}","answer": "b:1;","type": "judge","score": "2.00", * "founder": 1,"difficultyLevel": "medium","knowledge": 3,"subject": 3,"analysis": "判断题解析","createdTime": 0, * "subjectTitle": "","knowledgeTitle": "","founderTitle": "root" }]} * * @apiSuccessExample {json} 随机组卷结果: * {"errCode": 0,"errMsg": "ok","dataSet": [{ * "type": "judge","knowledge": 2,"subject": 3,"strategy": {"easy": 1,"moreEasily": 0,"medium": 0, * "moreDifficult": 0,"difficult": 0},"subjectTitle": "","knowledgeTitle": "测试知识点1"}]} * * @apiErrorExample {json} Error-Response: * {"code":5001,"message":"接口异常"} */ public function strategy(Request $request) { $input = $request->post(); if (empty($input['mode'])) { return payload(error(-1, '参数不完整')); } $filter = []; if (!empty($input['type'])) { $filter['type'] = $input['type']; } if (!empty($input['subject']) && !empty($input['knowledge'])) { if (!is_array($input['knowledge'])) { return payload(error(-2, '参数类型有误')); } $filter['subject'] = $input['subject']; } if (empty($filter)) { return payload(['dataSet' => []]); } $result = []; if (!empty($input['subject']) && !empty($input['knowledge'])) { foreach ($input['knowledge'] as $val) { $filter['knowledge'] = $val; $result[] = ModelPaper::strategy($filter, $input['mode']); } } else { $result[] = ModelPaper::strategy($filter, $input['mode']); } $dataSet = []; foreach ($result as $res) { $dataSet = array_merge($dataSet, $res); } $returnSet = array_map( function ($row) { $subjectInfo = Subject::fetch(intval($row['subject'])); $row['subjectTitle'] = empty($subjectInfo['title']) ? '' : $subjectInfo['title']; $knowledgeInfo = Knowledge::fetch(intval($row['knowledge'])); $row['knowledgeTitle'] = empty($knowledgeInfo['title']) ? '' : $knowledgeInfo['title']; if (isset($row['founder'])) { $user = UserModel::fetch(intval($row['founder'])); $row['founderTitle'] = empty($user) ? '' : $user['uid']; } return $row; }, $dataSet ); return payload(['dataSet' => $returnSet]); } /** * @param Request $request * @return Json * @throws \think\Exception * @api {post} /exam/paper/detail 试卷详情 * @apiGroup Exam-paper * @apiName sort4 * @apiVersion 1.0.0 * * @apiDescription 试卷详情 * * @apiParam {Number} id 试卷id * * @apiSuccess {Number} code 状态码,0:请求成功 * @apiSuccess {String} message 提示信息 * @apiSuccess {Object} dataSet 返回数据 * * @apiSuccessExample {json} Success-Response: * {"errCode": 0,"errMsg": "ok","dataSet": {"id": 1,"title": "测试卷1","type": "competition","mode": "hand", * "way": "fixed","display": 1,"time": 40,"totalPoints": "6.00","throughPoints": "2.00","definition": 1, * "multiple": 0,"result": 0,"completion": 0,"save": 0,"strategies": [{"type": "judge","knowledge": 2,"subject": 3, * "strategy": [1,2,3]},{"type": "choice","knowledge": 2,"subject": 3,"strategy": [4]},{"type": "judge", * "knowledge": 3,"subject": 16,"strategy": [5]}],"questionType": {"judge": {"type": "judge","point": 1, * "questionNum": 4,"order": 1},"choice": {"type": "choice","point": 2,"questionNum": 1,"order": 2}}, * "timeCreated": 1591597450,"timeStart": 1591372800,"timeEnd": 1593532800,"founder": 1, * "watch": "","mark": "","founderTitle": "root"}} * * @apiErrorExample {json} Error-Response: * {"code":5001,"message":"接口异常"} */ public function detail(Request $request) { $input = $request->post(); if (empty($input['id'])) { return payload(error(-1, '参数不完整')); } $detail = ModelPaper::detail(intval($input['id'])); $detail['questionType'] = array_values($detail['questionType']); unset($detail['question']); if (!empty($detail['watch']['user'])) { $detail['watch']['user'] = array_map( function ($v) { $user = UserModel::fetch(intval($v)); if (!empty($user)) { $department = Department::fetch($user['department']); $user = [ 'id' => $user['id'], 'uid' => $user['uid'], 'name' => $user['name'], 'department' => $department['id'], 'departmentTitle' => $department['title'], ]; } return $user; }, $detail['watch']['user'] ); } if (!empty($detail['mark']['user'])) { $detail['mark']['user'] = array_map( function ($v) { $user = UserModel::fetch(intval($v)); if (!empty($user)) { $department = Department::fetch($user['department']); $user = [ 'id' => $user['id'], 'uid' => $user['uid'], 'name' => $user['name'], 'department' => $department['id'], 'departmentTitle' => $department['title'], ]; } return $user; }, $detail['mark']['user'] ); } if (empty($detail['watch']['user']) && empty($detail['watch']['department'])) { $detail['watch'] = ""; } if (empty($detail['mark']['user']) && empty($detail['mark']['department'])) { $detail['mark'] = ""; } $userInfo = UserModel::fetch($detail['founder']); $detail['founderTitle'] = isset($userInfo['uid']) ? $userInfo['uid'] : ''; return payload(['dataSet' => $detail]); } /** * @param Request $request * @return Json * @api {post} /exam/paper/delete 试卷删除 * @apiGroup Exam-paper * @apiName sort5 * @apiVersion 1.0.0 * * @apiDescription 试卷详情 * * @apiParam {Number} ids 试卷id * @apiParam {String} type single 单删 batch 多删 * * @apiSuccess {Number} code 状态码,0:请求成功 * @apiSuccess {String} message 提示信息 * @apiSuccess {Object} dataSet 返回数据 * * @apiSuccessExample {json} Success-Response: * {"code":0,"message":"","dataSet":[], "total" : 0} * * @apiErrorExample {json} Error-Response: * {"code":5001,"message":"接口异常"} */ public function delete(Request $request) { $input = $request->post(); if (empty($input['ids']) || empty($input['type'])) { return payload(error(-1, '参数不完整')); } if ($input['type'] == 'batch') { $ids = implode(',', $input['ids']); } else { $ids = (string)$input['ids']; } $record = ModelPaper::paperUsed(explode(',', $ids)); if (!$record) { return payload(error(-1, '试卷已被使用,请先删除答题记录')); } $res = ModelPaper::delete($input['type'], $ids); if (!$res) { return payload(error(-1, '删除失败')); } return payload([]); } /** * @param Request $request * @return Json * @throws \think\Exception * @api {post} /exam/paper/preview 试卷预览 * @apiGroup Exam-paper * @apiName sort6 * @apiVersion 1.0.0 * * @apiDescription 试卷预览 * * @apiParam {Number} id 试卷id * * @apiSuccess {Number} code 状态码,0:请求成功 * @apiSuccess {String} message 提示信息 * @apiSuccess {Object} dataSet 返回数据 * * @apiSuccessExample {json} Success-Response: * {"code":0,"message":"","dataSet":[], "total" : 0} * * @apiErrorExample {json} Error-Response: * {"code":5001,"message":"接口异常"} */ public function preview(Request $request) { $input = $request->post(); if (empty($input['id'])) { return payload(error(-1, '参数不完整')); } $dataSet = ModelPaper::preview(intval($input['id'])); if (is_error($dataSet)) { return payload(error(-11, $dataSet->getMessage())); } $question = []; foreach ($dataSet['question'] as $v) { $question = array_merge($question, $v); } $questionArr = Question::search(['ids' => $question], 0); $questionArr = Collection::key($questionArr, 'id'); foreach ($dataSet['question'] as $k => &$val) { foreach ($val as &$v) { if (isset($questionArr[$v])) { $v = $questionArr[$v]; // $v['analysis'] = unserialize($v['analysis']); $v = Collection::elements(['id', 'name', 'options', 'answer', 'analysis'], $v); } else { continue; } } } return payload(['dataSet' => $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号