Simulation.php 14.1 KB
<?php
namespace app\mobile\controller;

use think\Validate;
use think\Db;
use app\common\controller\Api;
use app\mobile\model\Question;
use app\mobile\model\QuestionAnswer;
use app\mobile\model\SimulationResult;
use app\mobile\model\Course;

/**
 * 模拟试题接口
 * @ApiWeigh (97)
 */
class Simulation extends Api
{
	protected $noNeedLogin = ['index','info'];
    protected $noNeedRight = ['*'];
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = model('app\mobile\model\Simulation');
    }

    /**
     * @ApiTitle    (首页)
     * @ApiSummary  (首页)
     * @ApiMethod   (POST)
     *
     * @ApiReturn({
        "code": 1,
        "msg": "成功",
        "time": "1599814710",
        "data": {
            "banner": "", //广告图 
            "list": [{ // 试卷列表
                "id": 2, //试卷ID
                "title": "测试试卷2", //试卷标题
                "do_num": 9 //做过人数
            }]
        }
    })
     */
    public function index()
    {
        $banner = Db::name('mobile_config')->where('id',1)->value('simulation_adver');
        $banner = !empty($banner) ? cdnurl($banner,true) : '';
        $list = $this->model->order('createtime desc')->select();
        foreach ($list as $v) {
            $v->visible(['id','title','do_num']);
        }
        $this->success('成功',compact('banner','list'));
    }

    /**
     * @ApiTitle    (详情)
     * @ApiSummary  (详情)
     * @ApiMethod   (POST)
     *
     * @ApiParams (name="simulation_id", type="int", required=true, description="试卷ID")
     *
     * @ApiReturn({
        "code": 1,
        "msg": "成功",
        "time": "1599046220",
        "data": {
            "id": 1, //试卷ID
            "title": "测试试卷", //试卷标题
            "year": 2015, //年费(单位:年)
            "time": 100, //答题时间(单位:分)
            "pass_score": 80, //合格分数
            "satisfaction": 0, //满意度
            "description": "这个还行", //试卷描述
            "do_num": 10, //回答人数
            "full_score": 100 //试卷分数(单位:分)
        }
    })
     */
    public function info()
    {
        $simulation_id = $this->request->param('simulation_id');
        empty($simulation_id) && $this->error('缺少必要参数');
        $info = $this->model->get($simulation_id);
        empty($info) && $this->error('试卷信息不存在');
        $info['full_score'] = Question::where('target_id',$simulation_id)->sum('score');
        $info = $info->visible(['id','title','year','time','pass_score','satisfaction','description','do_num'])->append(['full_score']);
        $this->success('成功',$info);
    }

    /**
     * @ApiTitle    (考试模式-题目列表)
     * @ApiSummary  (考试模式-题目列表)
     * @ApiMethod   (POST)
     *
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     * @ApiParams (name="simulation_id", type="int", required=true, description="试卷ID")
     * @ApiParams (name="answer_type", type="string", required=false, description="作答类型:0=全部,1=已答题,2=未答题,3=错题")
     *
     * @ApiReturn({
        "code": 1,
        "msg": "成功",
        "time": "1599032660",
        "data": {
            "time": 6000, //倒计时(单位:秒)
            "total": 1, //题目总数
            "list": [{ //题目列表
                "id": 1, //题目ID
                "title": "测定混凝土立方体抗压强度时,标准试件的尺寸是(      )㎜。", //题目
                "option": "[{\"name\":\"A\",\"gender\":\"100\\u00d7100\\u00d7100\"},{\"name\":\"B\",\"gender\":\"150\\u00d7150\\u00d7150\"},{\"name\":\"C\",\"gender\":\"200\\u00d7200\\u00d7200\"},{\"name\":\"D\",\"gender\":\"70.7\\u00d770.7\\u00d770.7\"}]", //题目选项
                "type": "1", //题目类型:1=单选题,2=多选题,3=判断题,4=简答题
                "answer": "A", //答案
                "is_collect": "1" //是否收藏:0=否,1=是
            }]
        }
    })
     */
    public function questionList()
    {
        $user_id = $this->auth->id;
        $simulation_id = $this->request->param('simulation_id');
        $answer_type = $this->request->param('answer_type');
        empty($simulation_id) && $this->error('缺少必要参数');
        $info = $this->model->get($simulation_id);
        empty($info) && $this->error('试卷信息不存在');
        $time = $info['time'] * 60;
        $where['q.target_id'] = $simulation_id;
        $where['q.target_type'] = '2';
        switch ($answer_type) {
            case '1':
                $question_id_arr = QuestionAnswer::where('user_id',$user_id)->column('question_id');
                $where['q.id'] = !empty($question_id_arr) ? ['in',$question_id_arr] : 0;
                break;
            case '2':
                $question_id_arr = QuestionAnswer::where('user_id',$user_id)->column('question_id');
                if(!empty($question_id_arr)){
                    $where['q.id'] = ['notin',$question_id_arr];
                }
                break;
            case '3':
                $question_id_arr = QuestionAnswer::where('user_id',$user_id)->where('is_wrong','1')->column('question_id');
                $where['q.id'] = !empty($question_id_arr) ? ['in',$question_id_arr] : 0;
                break;
        }
        $list = Question::alias('q')
            ->join('mobile_question_collect qc','q.id = qc.question_id and user_id='.$user_id,'left')
            ->where($where)
            ->field('
                q.id,
                q.title,
                q.option,
                q.type,
                q.answer,
                if(qc.id > 0,1,0) is_collect
            ')->order(['type'=>'asc'])
            ->select();
        $total = count($list);
        // 删除原来的做题记录
        QuestionAnswer::where('question_id','in',array_column($list, 'id'))
            ->where('user_id',$user_id)
            ->delete();
        $this->success('成功',compact('time','total','list'));
    }

    /**
     * @ApiTitle    (模考答题卡)
     * @ApiSummary  (模考答题卡)
     * @ApiMethod   (POST)
     * 
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     * @ApiParams (name="simulation_id", type="int", required=true, description="试卷ID")
     *
     * @ApiReturn({
        "code": 1,
        "msg": "成功",
        "time": "1599032660",
        "data": {
            "total": 1, //题目总数
            "list": [{ //题目列表
                "id": 1, //题目ID
                "title": "测定混凝土立方体抗压强度时,标准试件的尺寸是(      )㎜。", //题目
                "option": "[{\"name\":\"A\",\"gender\":\"100\\u00d7100\\u00d7100\"},{\"name\":\"B\",\"gender\":\"150\\u00d7150\\u00d7150\"},{\"name\":\"C\",\"gender\":\"200\\u00d7200\\u00d7200\"},{\"name\":\"D\",\"gender\":\"70.7\\u00d770.7\\u00d770.7\"}]", //题目选项
                "type": "1", //题目类型:1=单选题,2=多选题,3=判断题,4=简答题
                "answer": "A", //答案
                "status": "1" //状态:0=未答,1=答对,2=答错
            }]
        }
    })
     */
    public function answerSheet()
    {
        $user_id = $this->auth->id;
        $simulation_id = $this->request->param('simulation_id');
        empty($simulation_id) && $this->error('缺少必要参数');
        $info = $this->model->get($simulation_id);
        empty($info) && $this->error('试卷信息不存在');
        $list = Question::alias('q')
            ->join('mobile_question_answer qa','q.id = qa.question_id and user_id='.$user_id,'left')
            ->where('q.target_id',$simulation_id)
            ->where('q.target_type','2')
            ->field('
                q.id,
                q.title,
                q.option,
                q.type,
                q.answer,
                if(qa.id > 0,if(qa.is_wrong="0",1,2),0) status
            ')->order(['type'=>'asc'])
            ->select();
        $new_list = [];
        foreach ($list as $v) {
            $new_list[$v['type']][] = $v;
        }
        $this->success('成功',$list);
    }

    /**
     * @ApiTitle    (交卷)
     * @ApiSummary  (交卷)
     * @ApiMethod   (POST)
     *
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     * @ApiParams (name="simulation_id", type="int", required=true, description="试卷ID")
     *
     * @ApiReturn({
        "code": 1,
        "msg": "交卷成功",
        "time": "1599116222",
        "data": {
            "simulation_result_id": "10" //考试结果ID
        }
    })
     */
    public function submit()
    {
        $user_id = $this->auth->id;
        $simulation_id = $this->request->param('simulation_id');
        empty($simulation_id) && $this->error('缺少必要参数');
        $info = $this->model->get($simulation_id);
        empty($info) && $this->error('试卷信息不存在');
        $list = Question::alias('q')
            ->join('mobile_question_answer qa','q.id = qa.question_id and user_id='.$user_id,'left')
            ->where('q.target_id',$simulation_id)
            ->where('q.target_type','2')
            ->field('q.id,q.title,q.option,q.type,q.answer,q.score,qa.get_score,qa.is_wrong')
            ->select();
        // 考试得分
        $myscore = array_sum(array_column($list, 'get_score'));
        // 正确率
        $right_count = Question::alias('q')
            ->join('mobile_question_answer qa','q.id = qa.question_id and user_id='.$user_id,'left')
            ->where('q.target_id',$simulation_id)
            ->where('q.target_type','2')
            ->where('qa.is_wrong','0')
            ->count('q.id');
        $right_rate = !empty($right_count) ? bcdiv($right_count,count($list),4) * 100 : 0;
        // 记录结果
        $result = SimulationResult::create([
            'user_id' => $user_id,
            'simulation_id' => $simulation_id,
            'full_score' => array_sum(array_column($list, 'score')),
            'get_score' => $myscore,
            'right_rate' => $right_rate
        ]);
        /*击败考生率和平均分*/
        $result_list = SimulationResult::where('simulation_id',$simulation_id)->select();
        // 击败考生
        $lt_count = SimulationResult::where('simulation_id',$simulation_id)
            ->where('get_score','<',$myscore)
            ->count();
        $win_rate = !empty($lt_count) ? bcdiv($lt_count,count($result_list),4) * 100 : 0;
        // 平均分
        $average_score = ceil(array_sum(array_column($result_list, 'get_score')) / count($result_list));
        // 记录下来击败考证率和平均分
        $result->save([
            'win_rate' => $win_rate,
            'average_score' => $average_score
        ]);
        $this->success('交卷成功',['simulation_result_id'=>$result['id']]);
    }

    /**
     * @ApiTitle    (测试结果页)
     * @ApiSummary  (测试结果页)
     * @ApiMethod   (POST)
     *
     * @ApiParams (name="simulation_result_id", type="int", required=true, description="考试结果ID")
     *
     * @ApiReturn({
        "code": 1,
        "msg": "成功",
        "time": "1599116915",
        "data": {
            "info": { //考试结果
                "id": 10, //考试结果ID
                "user_id": 9, //用户ID
                "simulation_id": 1, //试卷ID
                "full_score": 6, //试卷满分
                "get_score": 3, //考试得分
                "right_rate": 50, //正确率
                "win_rate": 100, //击败考生率
                "average_score": 3, //全站平均得分
                "createtime": 1599116222,
                "updatetime": 1599116222
            },
            "list": [{ //答题卡
                "id": 1, //题目ID
                "title": "测定混凝土立方体抗压强度时,标准试件的尺寸是(      )㎜。", //题目
                "option": "[{\"name\":\"A\",\"gender\":\"100\\u00d7100\\u00d7100\"},{\"name\":\"B\",\"gender\":\"150\\u00d7150\\u00d7150\"},{\"name\":\"C\",\"gender\":\"200\\u00d7200\\u00d7200\"},{\"name\":\"D\",\"gender\":\"70.7\\u00d770.7\\u00d770.7\"}]", //题目选项
                "type": "1", //题目类型:1=单选题,2=多选题,3=判断题,4=简答题
                "answer": "A", //题目答案
                "status": 2, //状态:0=未答,1=答对,2=答错
                "my_answer": A //我的答案
            }],
            "course": { //推荐课程
                "id": 1, //课程ID
                "title": "测试课程", //课程名称
                "current_price": "50.00", //现价
                "original_price": "100.00", //原价
                "select_rate": 64 //选择率
            }
        }
    })
     */
    public function examResult()
    {
        $user_id = $this->auth->id;
        $simulation_result_id = $this->request->param('simulation_result_id');
        empty($simulation_result_id) && $this->error('缺少必要参数');
        $info = SimulationResult::get($simulation_result_id);
        empty($info) && $this->error('考试结果信息不存在');
        $list = Question::alias('q')
            ->join('mobile_question_answer qa','q.id = qa.question_id and user_id='.$user_id,'left')
            ->where('q.target_id',$info['simulation_id'])
            ->where('q.target_type','2')
            ->field('
                q.id,
                q.title,
                q.option,
                q.type,
                q.answer,
                if(qa.id > 0,if(qa.is_wrong="0",1,2),0) status,
                qa.content my_answer
            ')->order(['type'=>'asc'])
            ->select();
        $new_list = [];
        foreach ($list as $v) {
            $new_list[$v['type']][] = $v;
        }
        // 推荐课程
        $course_id = $this->model->where('id',$info['simulation_id'])->value('course_id');
        $course = Course::where('id',$course_id)->field('id,title,current_price,original_price')->find();
        if($course){
            $course->select_rate = mt_rand(40,70);
        }else{
            $course = [];
        }
        $this->success('成功',compact('info','list','course'));
    }
}