<?php /** * 自动创建考卷 * Created by PhpStorm. * User: yingcai * Date: 2017/8/9 * Time: 下午3:12 */ namespace Frontend\Controller\Callback; use Common\Service\AnswerDetailTempService; use Common\Service\AnswerTempService; use Common\Service\PaperService; use VcySDK\Cron; use VcySDK\Service; class CreateExamController extends AbstractController { // 默认生成答卷份数 const DEFAULT_CREATE_PAPERS = 50; // 生成考卷与人数比例 const PERCENT_PAPERS = 0.4; // 默认考卷状态 const DEFAULT_ANSWER_STATUS = 0; // 常规考试 const NOMAL_TYPE = 1; // 非常规类生成考卷份数 const UN_NOMAL_CREATE_PAPERS = 10; // 计划任务最大时间 const CRON_TIME_MAX = 20; // 计划任务最小时间 const CRON_TIME_MIN = 10; /** @var PaperService 试卷信息表 */ protected $paper_s; /** @var AnswerTempService 随机答卷临时表 */ protected $answer_temp; /** @var AnswerDetailTempService 随机答卷详情临时表 */ protected $answer_temp_detail; public function before_action($action = '') { if (!parent::before_action($action)) { return false; } // 实例化试卷表 $this->paper_s = new PaperService(); // 实例化随机答卷临时表 $this->answer_temp = new AnswerTempService(); // 实例化随机答卷详情临时表 $this->answer_temp_detail = new AnswerDetailTempService(); return true; } public function Index() { set_time_limit(0); // 获取需要发送的试卷id $back = $this->callBackData; $ep_id = $back['ep_id']; // 非空判断 if (empty($ep_id)) { return true; } // 获取试卷基本详情 $paper = $this->paper_s->get($ep_id); if (empty($paper)) { return true; } // 是否是随机抽题 if ($paper['ep_type'] != PaperService::TOPIC_RANDOM) { return true; } $cron_serv = new Cron(Service::instance()); // 非常规类生成考卷份数 $papers_count = self::UN_NOMAL_CREATE_PAPERS; // 常规考试 if (self::NOMAL_TYPE == $paper['exam_type']) { // 应生成的考卷总份数(即权限范围总人数) $exam_papers = $paper['unjoin_count'] + $paper['join_count']; // 实际应生成的考卷份数 $papers_count = round($exam_papers * self::PERCENT_PAPERS); } // 获取已生成的考卷数量 $create_exam_papers = $this->answer_temp->count_by_conds(['ep_id' => $ep_id]); // 生成的考卷数量已达到上限 if (($create_exam_papers > $papers_count || ($paper['end_time'] > 0 && $paper['end_time'] <= MILLI_TIME) || PaperService::PAPER_STOP == $paper['exam_status']) && !empty($paper['corn_create_exam']) ) { // 删除计划任务 $cron_serv->delete($paper['corn_create_exam']); // 更新试卷计划任务为空 $this->paper_s->update($ep_id, ['corn_create_exam' => '']); return true; } // 实际应生成的考卷份数:应生成份数-已有份数 $create_papers_count = $papers_count - $create_exam_papers; // 实际应生成考卷分数大于低限设置 if ($create_papers_count > self::DEFAULT_CREATE_PAPERS) { // 按比例应生成的考卷分数(四舍五入取整) $c = round($create_papers_count * self::PERCENT_PAPERS); } else { // 实际应生成考卷份数小于等于低限设置 // 取实际应生成考卷份数 $c = $create_papers_count; } for ($i = 0; $i < $c; $i++) { // 题库信息 $bank_topic_data = unserialize($paper['bank_topic_data']); //题库ID集合 $bank_ids = array_column($bank_topic_data, 'eb_id'); // 选题规则 $rule_data = []; if (!empty($paper['rule'])) { $rule_data = unserialize($paper['rule']); } // 新数据随机抽题 $snapshot = $this->paper_s->random_rule_topic($bank_ids, $paper['ep_id'], $bank_topic_data, $rule_data); // 抽题失败 if (empty($snapshot)) { return true; } // 组装随机答卷临时表数据 $data_temp = [ 'ep_id' => $ep_id, 'answer_status' => self::DEFAULT_ANSWER_STATUS, ]; // 插入随机答卷临时表 $eat_id = $this->answer_temp->insert($data_temp); // 组装随机答卷临时详情表数据 foreach ($snapshot as &$val) { $val['eat_id'] = $eat_id; unset($val['eb_id'], $val['domain'], $val['status'], $val['created'], $val['updated'], $val['deleted']); } // 插入随机答卷临时表 $this->answer_temp_detail->insert_all($snapshot); } // 修改计划任务执行时间 $exam_begin_time = to_second_time($paper['begin_time']); // 计算当前距离考试开始时间还有多久 $m_time = $exam_begin_time - NOW_TIME; $minute = $m_time > 0 ? floor($m_time / 60) : 0; // 距离考试开始大于20分钟 if ($minute > self::CRON_TIME_MAX) { $params = [ 'crId' => $paper['corn_create_exam'], 'crCron' => '0 0/20 * * * ?' ]; $cron_serv->update($params); // 距离考试考试在10到20分钟之间 } elseif ($minute > self::CRON_TIME_MIN && $minute <= self::CRON_TIME_MAX) { $params = [ 'crId' => $paper['corn_create_exam'], 'crCron' => '0 0/10 * * * ?' ]; $cron_serv->update($params); } return true; } }