Paper.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <?php
  2. namespace addons\exam\controller;
  3. use addons\exam\enum\CommonStatus;
  4. use addons\exam\enum\ExamMode;
  5. use addons\exam\library\ExamService;
  6. use addons\exam\model\PaperModel;
  7. use addons\exam\model\QuestionModel;
  8. use addons\exam\model\UserModel;
  9. use app\admin\model\exam\CateModel;
  10. use app\admin\model\exam\GradeModel;
  11. use think\Request;
  12. use think\Db;
  13. /**
  14. * 试卷接口
  15. */
  16. class Paper extends Base
  17. {
  18. protected $noNeedLogin = ['index'];
  19. protected $noNeedRight = ['*'];
  20. protected $user;
  21. /**
  22. * 查询出分类下的试卷
  23. */
  24. public function index()
  25. {
  26. $cate_id = input('cate_id/d', '0');
  27. $sort = input('sort/s', '');
  28. $now = time();
  29. $query = PaperModel::with([
  30. 'cates' => function ($query) {
  31. $query->withField('id, name');
  32. }
  33. ])
  34. ->where('status', CommonStatus::NORMAL)
  35. ->where('is_only_room', 0)// 过滤仅考场使用的试卷
  36. ->whereRaw("((start_time = 0 and end_time = 0) or (start_time < {$now} and end_time > {$now}))");
  37. // 分类
  38. if ($cate_id) {
  39. $child_cate_ids = CateModel::getChildId($cate_id);
  40. array_push($child_cate_ids, $cate_id);
  41. $query->whereIn('cate_id', $child_cate_ids);
  42. }
  43. // 排序
  44. if ($sort && $sort != 'null') {
  45. $sort = explode('|', $sort);
  46. $field = $sort[0];
  47. $order_by = $sort[1];
  48. $field = in_array($field, ['join_count']) ? $field : 'join_count';
  49. $order_by = $order_by == 'desc' ? 'desc' : 'asc';
  50. $query->order("{$field} $order_by");
  51. }
  52. $list = $query->paginate();
  53. $this->success('', ['list' => $list]);
  54. }
  55. public function lists()
  56. {
  57. $list = Db::name('exam_paper')->field('id,image,title,updatetime')->where('status','normal')
  58. ->order('weigh desc, id desc')->autopage()->select();
  59. $list = list_domain_image($list,['image']);
  60. $this->success('', $list);
  61. }
  62. public function detail(){
  63. $id = input('id');
  64. $info = Db::name('exam_paper')->field('id,image,title,content,updatetime,quantity')->where('status','normal')
  65. ->find($id);
  66. $info = info_domain_image($info,['image']);
  67. $this->success('', $info);
  68. }
  69. /**
  70. * 试卷取题接口
  71. */
  72. public function getExamQuestion()
  73. {
  74. $paper_id = input('paper_id/d', 0);
  75. $room_id = input('room_id/d', 0);
  76. // 验证是否需要绑定手机号
  77. // UserModel::isMustBindMobile($this->auth->getUser());
  78. // 预创建考场考试记录
  79. // $room_grade_id = ExamService::preRoomGrade($room_id, $this->auth->id);
  80. // 获取试卷题目
  81. $question_data = ExamService::getExamQuestion($paper_id, $room_id);
  82. // $this->success('', array_merge($question_data, ['room_grade_id' => $room_grade_id]));
  83. $this->success('', $question_data);
  84. }
  85. //开始考试接口
  86. public function startpaper(){
  87. $paper_id = input('paper_id/d', 0);
  88. $user_id = $this->auth->id;
  89. //检查考试状态
  90. $check = Db::name('exam_grade')->where('user_id', $user_id)->where('status',1)->find();
  91. if($check){
  92. //$this->success('您有其他考试正在进行中,即将继续考试',0);//直接给成功,数据返回0,前端跳转
  93. }
  94. //检查试卷
  95. $paper = PaperModel::get($paper_id);
  96. switch (true) {
  97. case !$paper:
  98. $this->error('科普答题信息不存在');
  99. case $paper->status != 'NORMAL':
  100. $this->error('科普答题信息不存在');
  101. case $paper->mode == 'RANDOM' && !$paper->configs:
  102. $this->error('科普答题信息未配置');
  103. }
  104. //时间限制
  105. if ($paper['start_time'] > 0 && $paper['start_time'] > time()) {
  106. $this->error('该试卷未开始,不能参与考试');
  107. }
  108. if ($paper['end_time'] > 0 && $paper['end_time'] < time()) {
  109. $this->error('该试卷已结束,不能参与考试');
  110. }
  111. //考试资格
  112. if(!in_array($user_id,explode(',',$paper['user_ids']))){
  113. $this->error('您不能参加该考试');
  114. }
  115. //次数限制
  116. if ($paper['limit_count'] > 0){
  117. $my_count = Db::name('exam_grade')->where('user_id', $user_id)->where('paper_id', $paper_id)->count();
  118. if($my_count >= $paper['limit_count']) {
  119. $this->error('该试卷您的考试次数已达上限');
  120. }
  121. }
  122. //记录为已开始,计划任务倒计时之后 自动结束
  123. $data = [
  124. 'cate_id' => $paper['cate_id'],
  125. 'user_id' => $this->auth->id,
  126. 'paper_id' => $paper_id,
  127. 'mode' => $paper['mode'],
  128. 'total_score' => $paper['total_score'],
  129. 'total_count' => $paper['quantity'],
  130. 'start_time' => time(),
  131. 'createtime' => time(),
  132. 'status' => 1,
  133. 'limit_time' => $paper['limit_time'], //限时N秒
  134. 'last_time' => $paper['limit_time'] > 0 ? (time() + $paper['limit_time']) : 0, //最后限制交卷时间,时间戳
  135. ];
  136. $grade_id = Db::name('exam_grade')->insertGetId($data);
  137. $this->success('',$grade_id);
  138. }
  139. //进行中考试
  140. public function half_examing(){
  141. $user_id = $this->auth->id;
  142. $check = Db::name('exam_grade')->where('user_id', $user_id)->where('status',1)->find();
  143. if(empty($check)){
  144. $this->error('您没有进行中的考试');
  145. }
  146. $paper_id = $check['paper_id'];
  147. // 获取试卷题目
  148. $question_data = ExamService::getExamQuestion($paper_id, 0);
  149. $question_data['paper']['limit_time'] = $check['last_time'] - time();//倒计时秒数
  150. $this->success('', $question_data);
  151. }
  152. /**
  153. * 交卷
  154. */
  155. public function submit()
  156. {
  157. $request = Request::instance();
  158. $user_id = $this->auth->id;
  159. $paper_id = $request->post('paper_id/d', 0);
  160. $questions = $request->post('questions/a', []);
  161. $start_time = $request->post('start_time/d', time());
  162. $room_id = 0;
  163. $room_grade_id = $request->post('room_grade_id/d', 0);
  164. if (!$user_id || !$paper_id || !$questions) {
  165. $this->error('提交数据有误');
  166. }
  167. $check = Db::name('exam_grade')->where('status',1)->where('user_id',$user_id)->where('paper_id',$paper_id)->find();
  168. if(!$check){
  169. $this->error('交卷有误,或者您已交卷');
  170. }
  171. $grade_id = $check['id'];
  172. $start_time = $check['start_time'];
  173. // 考场考试
  174. if ($room_id) {
  175. if (!$room_grade_id) {
  176. $this->error('提交数据不合法');
  177. }
  178. // 考场考试
  179. $result = ExamService::roomExam($user_id, $room_id, $room_grade_id, $questions, $start_time, $paper, $room, $is_makeup, $room_grade_log);
  180. // 记录考场考试成绩
  181. $room_grade_log->allowField(true)->save(
  182. array_merge(
  183. $result,
  184. [
  185. // 'cate_id' => $paper['cate_id'],
  186. 'user_id' => $user_id,
  187. 'paper_id' => $paper_id,
  188. 'is_makeup' => $is_makeup,
  189. 'is_pre' => 0, // 提交成绩后不再为预创建标记
  190. ],
  191. [
  192. 'exam_mode' => ExamMode::ROOM,
  193. ]
  194. )
  195. );
  196. } else {
  197. $result = ExamService::paperExam($user_id, $paper_id, $questions, $start_time, $paper);
  198. // 记录考试成绩
  199. /*GradeModel::create(array_merge(
  200. $result,
  201. [
  202. 'cate_id' => $paper['cate_id'],
  203. 'user_id' => $user_id,
  204. 'paper_id' => $paper_id,
  205. ],
  206. [
  207. // 'exam_mode' => ExamMode::PAPER,
  208. 'date' => date('Y-m-d'),
  209. ]), true);*/
  210. $update = array_merge(
  211. $result,
  212. [
  213. 'cate_id' => $paper['cate_id'],
  214. 'updatetime' => time(),
  215. 'date' => date('Y-m-d'),
  216. 'status' => 2,
  217. 'finish_time' => time(),
  218. ]);
  219. unset($update['pass_score']);
  220. unset($update['start_time']);
  221. $rs = Db::name('exam_grade')->where('id',$grade_id)->update($update);
  222. if($rs === false){
  223. $this->error('交卷失败');
  224. }
  225. }
  226. $result['nickname'] = $this->auth->nickname;
  227. //删除本试卷分数最低的试卷
  228. $old_grade = Db::name('exam_grade')->where('user_id',$user_id)->where('paper_id',$paper_id)->where('id','NEQ',$grade_id)->find();
  229. if(!empty($old_grade)){
  230. if($old_grade['score'] <= $update['score']){
  231. $delete_id = $old_grade['id'];
  232. }else{
  233. $delete_id = $grade_id;
  234. }
  235. Db::name('exam_grade')->where('id',$delete_id)->delete();
  236. }
  237. //删除本试卷分数最低的试卷
  238. $this->success('',$result);
  239. // return json($result);
  240. }
  241. /*
  242. * 查看错题
  243. * Robin
  244. * @param $ids
  245. * */
  246. public function error_ids($ids)
  247. {
  248. $questions = QuestionModel::whereIn('id', ($ids))->select();
  249. $this->success('', $questions);
  250. }
  251. }