初始化项目:添加后端代码、ThinkPHP框架、前端资源
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller\app\exam;
|
||||
|
||||
use app\common\controller\Api;
|
||||
|
||||
/**
|
||||
* 练习
|
||||
*/
|
||||
class Exercises extends Api
|
||||
{
|
||||
|
||||
protected $noNeedLogin = ["detail","getCourseBindExam"];
|
||||
// 无需鉴权的接口,*表示全部
|
||||
protected $noNeedRight = ['*'];
|
||||
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->model = new \app\api\model\app\exam\Exercises();
|
||||
$this->logModel = new \app\api\model\app\exam\ExercisesLog;
|
||||
$this->exercisesSubscribeModel = new \app\api\model\app\exam\ExercisesSubscribe;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取练习详情
|
||||
* @return void
|
||||
*/
|
||||
public function detail()
|
||||
{
|
||||
$id = input('id');
|
||||
$data = $this->model->with(['course'])->where([
|
||||
'exercises.id'=>$id
|
||||
])->where([
|
||||
'exercises.status'=>1
|
||||
])->find();
|
||||
|
||||
if(!$data){
|
||||
$this->error('获取练习详情信息错误,请重试');
|
||||
}
|
||||
|
||||
if($data->course && $data->course->id){
|
||||
//判断是否已经订阅
|
||||
$data->course->is_subscription = \app\common\model\user\Subscription::getSubscriptionAuth($this->auth->id,$data->course->id);
|
||||
$data->course->visible(['is_subscription','id','name','cover','pay_price','price','pay_type']);
|
||||
|
||||
$courseData = $data->course->toArray();
|
||||
$courseType = $courseData['type'] ?? '';
|
||||
$isVirtualPay = \app\common\library\pay\VirtualPayService::isUseVirtualPay($courseType);
|
||||
$courseData['is_virtual_pay'] = $isVirtualPay ? 1 : 0;
|
||||
if ($isVirtualPay) {
|
||||
$courseData = \app\common\library\pay\VirtualPayService::convertPriceFields($courseData, ['price', 'pay_price']);
|
||||
}
|
||||
$data['course'] = $courseData;
|
||||
} else {
|
||||
$data['course'] = null;
|
||||
}
|
||||
|
||||
|
||||
$data->is_auth = \app\common\model\app\exam\ExercisesSubscribe::checkAuth($this->auth->id,$id);
|
||||
|
||||
$data->is_subscribe = \app\common\model\app\exam\ExercisesSubscribe::checkSubscribe($this->auth->id,$id);
|
||||
|
||||
$this->model->where(['id'=>$id])->setInc('views');
|
||||
|
||||
if(!$data['question_total_count']){
|
||||
$data['question_total_count'] = $this->model->getExercisesQuestionCount($id);
|
||||
}
|
||||
|
||||
|
||||
$data['detail'] = \addons\alivod\library\Alivod::parseContentAliovdTag($data['detail']);
|
||||
|
||||
$data['is_virtual_pay'] = \app\common\library\pay\VirtualPayService::isUseVirtualPay('exercises');
|
||||
if ($data['is_virtual_pay'] && isset($data['pay_price'])) {
|
||||
$data['pay_price'] = \app\common\library\pay\VirtualPayService::convertPrice($data['pay_price']);
|
||||
}
|
||||
|
||||
$this->success("获取成功",$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取课程关联的题库练习
|
||||
* @return void
|
||||
*/
|
||||
public function getCourseBindExam(){
|
||||
$courseId = $this->request->post('course_id');
|
||||
$examIds = $this->model
|
||||
->where([
|
||||
'bind_course'=>$courseId,
|
||||
'status'=>1
|
||||
])
|
||||
->column('id');
|
||||
|
||||
$query = \app\common\model\goods\Handle::getGoodsQuery();
|
||||
|
||||
$list = [];
|
||||
|
||||
if($examIds) {
|
||||
$list = $query->where([
|
||||
'id'=>['in',$examIds],
|
||||
'type'=>'exercises'
|
||||
])->select();
|
||||
|
||||
if($list){
|
||||
foreach ($list as &$item){
|
||||
$priceInfo = \app\common\model\goods\Handle::parseGoodsExtendInfo($item['id'],$item['type']);
|
||||
$item = array_merge($item,$priceInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->success("获取成功",$list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 加入练习
|
||||
* @return void
|
||||
*/
|
||||
public function subscribe(){
|
||||
$id = input('id');
|
||||
|
||||
$data = $this->model->with(['course'])->where([
|
||||
'exercises.id'=>$id
|
||||
])->where([
|
||||
'exercises.status'=>1
|
||||
])->find();
|
||||
|
||||
if(!$data){
|
||||
$this->error('该课程暂不可用,请重试');
|
||||
}
|
||||
|
||||
$isAuth = \app\common\model\app\exam\ExercisesSubscribe::checkAuth($this->auth->id,$id);
|
||||
if(!$isAuth){
|
||||
$this->error('暂无使用该练习权限,请重试');
|
||||
}
|
||||
|
||||
$isSubscribe = \app\common\model\app\exam\ExercisesSubscribe::checkSubscribe($this->auth->id,$id);
|
||||
if($isSubscribe){
|
||||
$this->error('已经订阅过了');
|
||||
}
|
||||
|
||||
$type = $data['sales_type'] == 1 ? 'free' : 'bind_course';
|
||||
\app\common\model\app\exam\ExercisesSubscribe::subscribe($this->auth->id,$id,$type);
|
||||
|
||||
$this->success("操作成功");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取订阅列表
|
||||
* @return void
|
||||
*/
|
||||
public function getSubscribeList(){
|
||||
|
||||
$limit = input('limit',10);
|
||||
$page = input('page',1);
|
||||
$search = input('search');
|
||||
$sort = input('sort','desc') == 'desc' ? 'desc' : 'asc';
|
||||
$order = input('order');
|
||||
|
||||
$where = [
|
||||
'user_id'=>$this->auth->id,
|
||||
'exercises.status'=>1
|
||||
];
|
||||
|
||||
$orderField = 'exercises_subscribe.createtime';
|
||||
|
||||
if(!empty($search)){
|
||||
// $where['course.name'] = ['like',"%{$search}%"];
|
||||
}
|
||||
|
||||
$rows = $this->exercisesSubscribeModel->with(['exercises']);
|
||||
$list = $rows
|
||||
->where($where)
|
||||
->limit($limit)->page($page)
|
||||
->order($orderField,$sort)
|
||||
->select();
|
||||
|
||||
|
||||
if(!empty($list)){
|
||||
foreach ($list as $item){
|
||||
|
||||
//获取练习包含题目数量
|
||||
$item->question_count = $this->model->getExercisesQuestionCount($item->exercises_id);
|
||||
//获取已做的题目数量
|
||||
$item->complete_question_count = $this->logModel->getCompleteQuestionCount($item->exercises_id);
|
||||
//判断百分比
|
||||
$item->complete_prop = !$item->complete_question_count ? 0 : ceil($item->question_count/$item->complete_question_count) * 100;
|
||||
|
||||
$item->exercises->visible(['type','sales_type','id','name','cover','pay_price','price','pay_type']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->success('获取成功', $list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取练习商品列表
|
||||
* @return void
|
||||
*/
|
||||
public function getGoodsList(){
|
||||
|
||||
$limit = input('limit',10);
|
||||
$page = input('page',1);
|
||||
$search = input('search');
|
||||
$groupId = input('group_id');
|
||||
$sort = input('sort','desc') == 'desc' ? 'desc' : 'asc';
|
||||
$order = input('order');
|
||||
|
||||
$sort = 'desc';
|
||||
|
||||
$where = [
|
||||
'status'=>1,
|
||||
'hide'=>0,
|
||||
];
|
||||
|
||||
$orderField = 'createtime';
|
||||
|
||||
if(!empty($groupId)){
|
||||
$where['group_id'] = $groupId;
|
||||
}
|
||||
|
||||
|
||||
$rows = $this->model;
|
||||
$list = $rows
|
||||
->where($where)
|
||||
->limit($limit)->page($page)
|
||||
->order($orderField,$sort)
|
||||
->select();
|
||||
|
||||
|
||||
if(!empty($list)){
|
||||
foreach ($list as &$item){
|
||||
|
||||
|
||||
$item->type = 'exercises';
|
||||
switch ($item->sales_type){
|
||||
case 1:
|
||||
$item->pay_type = 'free';
|
||||
break;
|
||||
case 2:
|
||||
$item->price = $item->pay_price;
|
||||
$item->pay_type = 'pay';
|
||||
break;
|
||||
case 3:
|
||||
$item->pay_type = 'bind_course';
|
||||
break;
|
||||
}
|
||||
|
||||
$item->visible(['type','sales_type','id','name','cover','pay_price','price','pay_type']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->success('获取成功', $list);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取课程分组列表
|
||||
* @return void
|
||||
*/
|
||||
public function group(){
|
||||
$list = (new \app\api\model\app\exam\ExercisesGroup)->getList();
|
||||
|
||||
$this->success('返回成功', $list);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller\app\exam;
|
||||
|
||||
use app\common\controller\Api;
|
||||
|
||||
/**
|
||||
* 练习记录
|
||||
*/
|
||||
class ExercisesLog extends Api
|
||||
{
|
||||
|
||||
protected $noNeedLogin = [];
|
||||
// 无需鉴权的接口,*表示全部
|
||||
protected $noNeedRight = ['*'];
|
||||
|
||||
|
||||
public function _initialize()
|
||||
{
|
||||
parent::_initialize();
|
||||
$this->exercisesModel = new \app\api\model\app\exam\Exercises();
|
||||
$this->logModel = new \app\api\model\app\exam\ExercisesLog;
|
||||
$this->exercisesLogAnswer = new \app\api\model\app\exam\ExercisesLogAnswer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 新建练习
|
||||
* @return void
|
||||
*/
|
||||
public function buildLog(){
|
||||
$exercisesId = input('id');
|
||||
|
||||
//获取出题配置
|
||||
$exercisesInfo = $this->exercisesModel->where([
|
||||
'id'=>$exercisesId,
|
||||
'status'=>1
|
||||
])->find();
|
||||
|
||||
if(!$exercisesInfo){
|
||||
$this->error('获取练习详情信息错误,请重试');
|
||||
}
|
||||
|
||||
if(!\app\common\model\app\exam\ExercisesSubscribe::checkAuth($this->auth->id,$exercisesId)){
|
||||
$this->error('暂无该练习使用权限');
|
||||
}
|
||||
|
||||
$logId = $this->logModel->buildLog($this->auth->id,$exercisesId);
|
||||
|
||||
if(!$logId){
|
||||
$this->error('新建练习失败,请重试');
|
||||
}
|
||||
|
||||
$this->success("获取成功",$logId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取做题记录详情
|
||||
* @return void
|
||||
*/
|
||||
public function getLogDetail(){
|
||||
|
||||
$logId = input('id');
|
||||
|
||||
$logData = $this->logModel->where([
|
||||
'id'=>$logId,
|
||||
'user_id'=>$this->auth->id
|
||||
])->find();
|
||||
|
||||
if(!$logData){
|
||||
$this->error('获取练习详情错误,请重试');
|
||||
}
|
||||
|
||||
$questionList = $this->logModel->getQuestionList($logId);
|
||||
|
||||
if(!$questionList){
|
||||
$this->error('获取练习题目错误,请重试');
|
||||
}
|
||||
|
||||
$logData->question_list = $this->logModel->getQuestionList($logId);
|
||||
|
||||
if($logData['status'] == 1){
|
||||
//需要获取用户的答案
|
||||
$logData->user_answer = $this->exercisesLogAnswer->getUserAnswer($this->auth->id,0,$logId);
|
||||
}
|
||||
|
||||
if($logData->question_list){
|
||||
foreach ($logData->question_list as $option){
|
||||
if($logData['status'] == 0){
|
||||
// 未交卷:隐藏参考答案与解析,但保留填空题答案结构用于确定填空数量
|
||||
$option->visible(['question','type','id','option','answer']);
|
||||
// 填空题答案保留结构但清空具体内容
|
||||
if($option['type'] == 'fillblank' && is_array($option['answer'])){
|
||||
$option['answer'] = array_map(function(){ return []; }, $option['answer']);
|
||||
}
|
||||
}else{
|
||||
// 已交卷:返回参考答案、解析等供结果页展示
|
||||
$option->visible(['id','type','degree','question','option','answer','analysis']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//计算做题时间
|
||||
$logData->usetime = time() - $logData->createtime;
|
||||
|
||||
$this->success("获取成功",$logData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 提交练习
|
||||
* @return void
|
||||
*/
|
||||
public function submit(){
|
||||
$logId = input('id');
|
||||
$answerList = input('answer/a');
|
||||
|
||||
|
||||
if(!$answerList){
|
||||
$this->error('请至少填写一个问题的答案再提交');
|
||||
}
|
||||
|
||||
|
||||
$logData = $this->logModel->where([
|
||||
'id'=>$logId,
|
||||
'user_id'=>$this->auth->id
|
||||
])->find();
|
||||
|
||||
if(!$logData){
|
||||
$this->error('获取练习详情错误,请重试');
|
||||
}
|
||||
|
||||
if($logData['status'] != 0){
|
||||
$this->error('已经提交过了');
|
||||
}
|
||||
|
||||
//需要效验答案
|
||||
|
||||
$questionList = $this->logModel->getQuestionList($logId);
|
||||
|
||||
|
||||
$result = $this->exercisesLogAnswer->checkAnswer($questionList,$answerList);
|
||||
|
||||
if(!$result['answer_list']){
|
||||
$this->error('请至少填写一个问题的答案再提交');
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(!$this->exercisesLogAnswer->saveAnswer($this->auth->id,$logData['exercises_id'],$logId,$result['answer_list'])){
|
||||
$this->error('答案提交错误,请重试');
|
||||
}
|
||||
$this->logModel->where([
|
||||
'id'=>$logId
|
||||
])->update([
|
||||
'status'=>1,
|
||||
'result_error_count'=>$result['error_count'],
|
||||
'result_true_count'=>$result['true_count'],
|
||||
'updatetime'=>time()
|
||||
]);
|
||||
|
||||
$this->success('交卷成功');
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取考试结果
|
||||
* @return void
|
||||
*/
|
||||
public function getResult(){
|
||||
$logId = input('id');
|
||||
|
||||
$logData = $this->logModel->where([
|
||||
'id'=>$logId,
|
||||
'user_id'=>$this->auth->id
|
||||
])->find();
|
||||
|
||||
if(!$logData){
|
||||
$this->error('获取练习详情错误,请重试');
|
||||
}
|
||||
|
||||
$logData->prop = ceil($logData->result_true_count/$logData->question_count * 100);
|
||||
|
||||
$this->success('获取成功',$logData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取练习记录
|
||||
* @return void
|
||||
*/
|
||||
public function getLogList(){
|
||||
|
||||
$limit = input('limit',10);
|
||||
$page = input('page',1);
|
||||
$exercisesId = input('id',1);
|
||||
$sort = input('sort','desc') == 'desc' ? 'desc' : 'asc';
|
||||
|
||||
$where = [
|
||||
'user_id'=>$this->auth->id,
|
||||
'exercises_id'=>$exercisesId
|
||||
];
|
||||
|
||||
|
||||
$rows = $this->logModel;
|
||||
$list = $rows
|
||||
->where($where)
|
||||
->limit($limit)->page($page)
|
||||
->order('createtime',$sort)
|
||||
->select();
|
||||
|
||||
|
||||
if(!empty($list)){
|
||||
foreach ($list as &$item){
|
||||
$item->prop = ceil($item->result_true_count / $item->question_count * 100);
|
||||
|
||||
$item->visible(['prop','createtime','exercises_id','question_count','result_error_count','result_true_count','updatetime','id']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->success('获取成功', $list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取错误本
|
||||
* @return void
|
||||
*/
|
||||
public function getErrorQuestion(){
|
||||
$exercisesId = input('id',1);
|
||||
$where = [
|
||||
'user_id'=>$this->auth->id,
|
||||
'exercises_id'=>$exercisesId,
|
||||
'error_book_show'=>1,
|
||||
'result'=>0
|
||||
];
|
||||
|
||||
$errorQuestionIds = $this->exercisesLogAnswer->where($where)->order('createtime','desc')->field('question_id')->group('question_id')->column('question_id');
|
||||
|
||||
$logData = [
|
||||
'status' => 1
|
||||
];
|
||||
|
||||
$logData['question_list'] = $this->logModel->idsGetQestion($errorQuestionIds);
|
||||
|
||||
$logData['user_answer'] = $this->exercisesLogAnswer->getUserAnswer($this->auth->id,$exercisesId);
|
||||
|
||||
$this->success('获取成功', $logData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除错题
|
||||
* @return void
|
||||
*/
|
||||
public function delErrorQuestion(){
|
||||
$exercisesId = input('id',1);
|
||||
$questionId = input('question_id',1);
|
||||
|
||||
$where = [
|
||||
'user_id'=>$this->auth->id,
|
||||
'exercises_id'=>$exercisesId,
|
||||
'question_id'=>$questionId,
|
||||
'error_book_show'=>1,
|
||||
'result'=>0
|
||||
];
|
||||
|
||||
$answerData = $this->exercisesLogAnswer->where($where)->find();
|
||||
|
||||
if(!$answerData){
|
||||
$this->error('该问题暂时无法变更,请重试');
|
||||
}
|
||||
$this->exercisesLogAnswer->where($where)->update([
|
||||
'error_book_show'=>2
|
||||
]);
|
||||
$this->success('移除成功');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user