CreateExamController.class.php
5.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
<?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;
}
}