Room.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <?php
  2. namespace addons\exam\controller;
  3. use addons\exam\enum\CommonStatus;
  4. use addons\exam\enum\RoomMode;
  5. use addons\exam\enum\RoomSignupStatus;
  6. use addons\exam\library\ValidateService;
  7. use addons\exam\model\BaseModel;
  8. use addons\exam\model\RoomGradeModel;
  9. use addons\exam\model\RoomModel;
  10. use addons\exam\model\RoomSignupModel;
  11. use app\admin\model\exam\CateModel;
  12. /**
  13. * 考场接口
  14. */
  15. class Room extends Base
  16. {
  17. protected $noNeedLogin = ['index'];
  18. protected $noNeedRight = ['*'];
  19. protected $user;
  20. /**
  21. * 查询出分类下的考场
  22. */
  23. public function index()
  24. {
  25. $cate_id = input('cate_id', '0');
  26. $sort = input('sort/s', '');
  27. $query = RoomModel::with(
  28. [
  29. 'cates' => BaseModel::withSimpleCate(),
  30. 'paper' => function ($query) {
  31. $query->field('id, cate_id, title, mode, quantity, total_score, pass_score, limit_time');
  32. },
  33. ]
  34. )->where('status', CommonStatus::NORMAL);
  35. // 分类
  36. if ($cate_id && is_numeric($cate_id)) {
  37. $child_cate_ids = CateModel::getChildId($cate_id);
  38. array_push($child_cate_ids, $cate_id);
  39. $query->whereIn('cate_id', $child_cate_ids);
  40. }
  41. // 排序
  42. if ($sort && $sort != 'null') {
  43. $sort = explode('|', $sort);
  44. $field = $sort[0];
  45. $order_by = $sort[1];
  46. $field = in_array($field, ['signup_count', 'grade_count', 'pass_count']) ? $field : 'signup_count';
  47. $order_by = $order_by == 'desc' ? 'desc' : 'asc';
  48. $query->order("{$field} $order_by");
  49. }
  50. $list = $query->order('weigh desc')->paginate();
  51. $this->success('', ['list' => $list]);
  52. }
  53. /**
  54. * 考场详情
  55. */
  56. public function detail()
  57. {
  58. if (!$room_id = input('room_id/d', '0')) {
  59. $this->error('缺少考场ID');
  60. }
  61. if (!$room = RoomModel::with(
  62. [
  63. 'cates' => BaseModel::withSimpleCate(),
  64. 'paper'
  65. ])
  66. ->where('id', $room_id)->find()
  67. ) {
  68. $this->error('考场信息不存在');
  69. }
  70. if ($room['status'] != CommonStatus::NORMAL) {
  71. $this->error('考场已关闭');
  72. }
  73. // 报名记录
  74. $signup_log = RoomSignupModel::where('room_id', $room_id)
  75. ->where('user_id', $this->auth->id)
  76. ->order('id desc')
  77. ->find();
  78. // 考试记录
  79. $room_grade_logs = $signup_log ? RoomGradeModel::where('room_id', $room_id)
  80. ->where('user_id', $this->auth->id)
  81. ->order('id desc')
  82. ->select() : [];
  83. // 符合开始考试条件(0:不允许,1:开始开始,2:开始补考)
  84. if ($signup_log) {
  85. // 已报名成功、在考试时间内
  86. $can_start = ($signup_log['status'] == RoomSignupStatus::ACCEPT && ($room['start_time'] < time() && $room['end_time'] > time())) ? 1 : 0;
  87. if ($can_start) {
  88. // 允许补考
  89. if ($room['is_makeup'] == 1) {
  90. // 未超出补考次数限制
  91. $room_grade_log_count = count($room_grade_logs);
  92. if ($room_grade_log_count > 0) {
  93. $can_start = $room_grade_log_count - 1 < $room['makeup_count'] ? 2 : 0;
  94. }
  95. } else {
  96. // 非补考模式只能考一次
  97. $can_start = count($room_grade_logs) == 0;
  98. }
  99. }
  100. $signup_log['can_start'] = $can_start;
  101. }
  102. $this->success('', [
  103. 'room' => $room,
  104. 'signup_log' => $signup_log,
  105. 'exam_logs' => $room_grade_logs,
  106. ]);
  107. }
  108. /**
  109. * 考场报名
  110. */
  111. public function signup()
  112. {
  113. switch (true) {
  114. case !$room_id = input('room_id/d', '0'):
  115. $this->error('缺少考场ID');
  116. case !$real_name = input('real_name/s', ''):
  117. $this->error('请填写您的姓名');
  118. case !$phone = input('phone/s', ''):
  119. $this->error('请填写手机号码');
  120. case !ValidateService::phone($phone):
  121. $this->error('手机号码格式不正确');
  122. case !$room = RoomModel::get($room_id):
  123. $this->error('考场信息不存在');
  124. case $room['signup_mode'] == RoomMode::PASSWORD && $room['password'] != input('password/s', ''):
  125. $this->error('考场密码不正确');
  126. case $room['status'] != CommonStatus::NORMAL:
  127. $this->error('考场状态异常');
  128. case $room['start_time'] > time() || $room['end_time'] < time():
  129. $this->error('考场未开始或已过期');
  130. // case $room['signup_count'] >= $room['people_count']:
  131. // $this->error('考场人数已满,无法报名参加考试');
  132. }
  133. // 已报名、被拒绝
  134. if ($signupLog = RoomSignupModel::where('room_id', $room_id)->where('user_id', $this->auth->id)->find()) {
  135. if ($signupLog->status != RoomSignupStatus::REJECT) {
  136. $this->error('该考场您已报过名了,请勿重复报名');
  137. }
  138. $signupLog->real_name = $real_name;
  139. $signupLog->phone = $phone;
  140. $signupLog->status = RoomSignupStatus::WAIT;
  141. if ($signupLog->save()) {
  142. $this->success('重新提交报名成功');
  143. }
  144. } else {
  145. // 非审核模式
  146. if ($room['signup_mode'] != RoomMode::AUDIT) {
  147. if ($room['people_count'] != 0 && $room['signup_count'] >= $room['people_count']) {
  148. $this->error('考场人数已满,无法报名参加考试');
  149. }
  150. }
  151. // 创建报名记录
  152. if (RoomSignupModel::create([
  153. 'user_id' => $this->auth->id,
  154. 'room_id' => $room_id,
  155. 'real_name' => $real_name,
  156. 'phone' => $phone,
  157. 'status' => $room['signup_mode'] == RoomMode::AUDIT ? RoomSignupStatus::WAIT : RoomSignupStatus::ACCEPT,
  158. ])) {
  159. // 非审核模式
  160. if ($room['signup_mode'] != RoomMode::AUDIT) {
  161. // 递增报名成功人数
  162. $room->setInc('signup_count');
  163. }
  164. $this->success($room['signup_mode'] == RoomMode::AUDIT ? '报名成功,请等待审核' : '报名成功');
  165. }
  166. }
  167. $this->error('报名失败,请重试');
  168. }
  169. }