123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- <?php
- namespace app\api\controller;
- use app\common\controller\Api;
- use think\Db;
- use app\utils\RedisKeyEnum;
- use app\utils\RedisUtil;
- /**
- * 答题
- */
- class Question extends Api
- {
- protected $noNeedLogin = [];
- protected $noNeedRight = ['*'];
- //取题之前弹机构
- public function get_question_before(){
- $jigou = Db::name('vote_jigou')->where('id',$this->auth->bind_jigou_id)->value('title');
- $times = config('site.bind_jigou_times') - $this->auth->bind_jigou_times;
- $rs = [
- 'bind_jigou_id' => $this->auth->bind_jigou_id,
- 'jigou_title' => $jigou,
- 'times' => $times,
- ];
- $this->success(1,$rs);
- }
- //获取10个题
- public function get_question(){
- //上次绑定选手的时间不是今天
- if(empty($this->auth->bind_jigou_id)){
- $this->error('先绑定机构再答题',null,2);
- }
- //今天,总答题次数
- $gift_question = config('site.exam_times_user_eday');
- //今天,已答题次数
- $submit_question = RedisUtil::getInstance(RedisKeyEnum::EAXM_TIMES.date('Y-m-d').':'.$this->auth->id)->get();
- //今日剩余答题次数
- $today_my_question = $gift_question - $submit_question;
- if($today_my_question < 0){
- $today_my_question = 0;
- }
- if($today_my_question == 0){
- $this->error('今日答题次数用完了,明天再来吧');
- }
- //获取10个随机题目
- $lists = Db::name('exam_question')
- ->field('id,kind,title,options_json')
- ->where('is_material_child', 0)// 材料题子题不显示
- ->where('status', 'NORMAL')// 正常
- ->where('deletetime', NULL)
- ->orderRaw('rand()')->limit($today_my_question)->select();
- foreach($lists as $key => $val){
- $val['options_json'] = $this->getOptionsJsonAttr($val['options_json']);
- $lists[$key] = $val;
- }
- $this->success(1,$lists);
- }
- private function getOptionsJsonAttr($value)
- {
- if ($value = json_decode($value, true)) {
- $data = [];
- foreach ($value as $key => $row) {
- $arr['key'] = $key;
- $arr['value'] = $row;
- array_push($data, $arr);
- }
- return $data;
- }
- return [];
- }
- /**
- * 答题
- */
- public function submit()
- {
- $this->error('接口作废');
- if(!$this->apiLimit('操作太快了,休息一下吧'));
- //上次绑定选手的时间不是今天
- if(empty($this->auth->bind_jigou_id)){
- $this->error('先绑定机构再答题',null,2);
- }
- //检查今日答题次数
- $exam_times_user_eday = config('site.exam_times_user_eday');
- $count = RedisUtil::getInstance(RedisKeyEnum::EAXM_TIMES.date('Y-m-d').':'.$this->auth->id)->get();
- if($count >= $exam_times_user_eday){
- $this->error('今日答题次数用完了,明天再来吧');
- }
- //答题
- $user_questions = input('questions','','htmlspecialchars_decode');
- $user_questions = json_decode($user_questions,true);
- if (!$user_questions) {
- $this->error('提交数据有误');
- }
- //避免超次数
- if(count($user_questions) + $count > $exam_times_user_eday){
- $this->error('今日答题次数用完了,明天再来吧!');
- }
- $questions_ids = array_column($user_questions, 'id'); // 答题id
- $answers = array_column($user_questions, 'answer'); // 用户答案
- $is_right_number = 0;
- $log_data = [];
- $questions = Db::name('exam_question')->field('id,kind,answer')->where('id','IN', $questions_ids)->orderRaw('field(id,'. implode(',', $questions_ids) .')')->select();
- foreach($questions as $key => $question){
- $is_right = $this->paperExam($question,$answers[$key]);
- if($is_right){
- $is_right_number ++;
- }
- $log_data[] = [
- 'user_id' => $this->auth->id,
- 'question_id' => $question['id'],
- 'is_right' => $is_right ? 1 : 0,
- 'jigou_id' => $this->auth->bind_jigou_id,
- 'createtime' => time(),
- 'createdate' => strtotime(date('Y-m-d')),
- ];
- }
- Db::startTrans();
- //答题日志
- $log_id = Db::name('user_question_log')->insertAll($log_data);
- if(!$log_id){
- Db::rollback();
- $this->error('答题失败');
- }
- if($is_right_number > 0){
- //给机构加分
- $rs = Db::name('vote_jigou')->where('id',$this->auth->bind_jigou_id)->setInc('score',$is_right_number);
- if($rs === false){
- Db::rollback();
- $this->error('答题失败');
- }
- }
- Db::commit();
- //今日答题次数,自增一次
- $count = RedisUtil::getInstance(RedisKeyEnum::EAXM_TIMES.date('Y-m-d').':'.$this->auth->id)->incrby_expire(count($user_questions),86400);
- if($is_right_number > 0){
- //今日答对次数,自增一次
- RedisUtil::getInstance(RedisKeyEnum::EAXM_RIGHT.date('Y-m-d').':'.$this->auth->id)->incrby_expire($is_right_number,86400);
- }
- //返回正确了几道题,剩余答题次数
- $result = [
- 'remark' => '答题完成,获得'.$is_right_number.'次投票次数,答题最多可获得'.$exam_times_user_eday.'次投票机会',
- 'submit_number'=> count($user_questions),
- 'right_number' => $is_right_number,
- 'remain' => $exam_times_user_eday - $count,
- ];
- $this->success('答题完毕',$result);
- }
- /**
- * 试题
- * @param $question_id
- * @param $answer
- * @return bool
- */
- private function paperExam($question,$answer)
- {
- $is_right = false;
- if(empty($question)){
- return false;
- }
- switch ($question['kind']) {
- case 'JUDGE': // 判断题
- case 'SINGLE': // 单选题
- case 'MULTI': // 多选题
- // 答题正确
- if (strtoupper($answer) == $question['answer']) {
- $is_right = true;
- } else {
- $is_right = false;
- }
- break;
- case 'SHORT': // 简答题
- // 答案得分配置
- $answer_config = is_string($question['answer']) ? json_decode($question['answer'], true) : $question['answer'];
- $user_answers = $answer;
- foreach ($answer_config['config'] as $answer_item) {
- // 匹配答案关键词
- if (strpos($user_answers, $answer_item['answer']) !== false) {
- $is_right = true;
- break;
- }
- }
- break;
- }
- return $is_right;
- }
- }
|