exam add recurring

This commit is contained in:
xiaomlove
2024-04-13 13:55:32 +08:00
parent cb4f91bee5
commit b55a014c59
5 changed files with 147 additions and 29 deletions

View File

@@ -101,14 +101,29 @@ class ExamRepository extends BaseRepository
private function checkBeginEnd(array $params): bool
{
if (!empty($params['begin']) && !empty($params['end']) && empty($params['duration'])) {
if (
!empty($params['begin']) && !empty($params['end'])
&& empty($params['duration'])
&& empty($params['recurring'])
) {
return true;
}
if (empty($params['begin']) && empty($params['end']) && isset($params['duration']) && ctype_digit((string)$params['duration']) && $params['duration'] > 0) {
if (
empty($params['begin']) && empty($params['end'])
&& isset($params['duration']) && ctype_digit((string)$params['duration']) && $params['duration'] > 0
&& empty($params['recurring'])
) {
return true;
}
if (
empty($params['begin']) && empty($params['end'])
&& empty($params['duration'])
&& !empty($params['recurring'])
) {
return true;
}
throw new \InvalidArgumentException("Require begin and end or only duration.");
throw new \InvalidArgumentException(nexus_trans("exam.time_condition_invalid"));
}
private function checkFilters(array $params)
@@ -231,7 +246,7 @@ class ExamRepository extends BaseRepository
$now = Carbon::now();
$query = Exam::query()
->where('status', Exam::STATUS_ENABLED)
->whereRaw("if(begin is not null and end is not null, begin <= '$now' and end >= '$now', duration > 0)")
->whereRaw("if(begin is not null and end is not null, begin <= '$now' and end >= '$now', duration > 0 or recurring is not null)")
;
if (!is_null($excludeId)) {
@@ -330,6 +345,7 @@ class ExamRepository extends BaseRepository
public function assignToUser(int $uid, int $examId, $begin = null, $end = null)
{
$logPrefix = "uid: $uid, examId: $examId, begin: $begin, end: $end";
/** @var Exam $exam */
$exam = Exam::query()->find($examId);
$user = User::query()->findOrFail($uid);
if (Auth::user()->class <= $user->class) {
@@ -349,12 +365,12 @@ class ExamRepository extends BaseRepository
'exam_id' => $exam->id,
];
if (empty($begin)) {
$begin = $exam->begin_for_user;
$begin = $exam->getBeginForUser();
} else {
$begin = Carbon::parse($begin);
}
if (empty($end)) {
$end = $exam->end_for_user;
$end = $exam->getEndForUser();
} else {
$end = Carbon::parse($end);
}
@@ -1003,8 +1019,8 @@ class ExamRepository extends BaseRepository
$size = 1000;
$minId = 0;
$result = 0;
$begin = $exam->begin_for_user;
$end = $exam->end_for_user;
$begin = $exam->getBeginForUser();
$end = $exam->getEndForUser();
while (true) {
$logPrefix = sprintf('[%s], exam: %s, size: %s', __FUNCTION__, $exam->id , $size);
$users = (clone $baseQuery)->where("$userTable.id", ">", $minId)->limit($size)->get();
@@ -1069,10 +1085,12 @@ class ExamRepository extends BaseRepository
$result += $examUsers->count();
$now = Carbon::now()->toDateTimeString();
$examUserIdArr = $uidToDisable = $messageToSend = $userBanLog = $userModcommentUpdate = [];
$examUserToInsert = [];
foreach ($examUsers as $examUser) {
$minId = $examUser->id;
$examUserIdArr[] = $examUser->id;
$uid = $examUser->uid;
/** @var Exam $exam */
$exam = $examUser->exam;
$currentLogPrefix = sprintf("$logPrefix, user: %s, exam: %s, examUser: %s", $uid, $examUser->exam_id, $examUser->id);
if (!$examUser->user) {
@@ -1124,8 +1142,18 @@ class ExamRepository extends BaseRepository
'subject' => $subject,
'msg' => $msg
];
if (!empty($exam->recurring) && $this->isExamMatchUser($exam, $examUser->user)) {
$examUserToInsert[] = [
'uid' => $examUser->user->id,
'exam_id' => $exam->id,
'begin' => $exam->getBeginForUser(),
'end' => $exam->getEndForUser(),
'created_at' => $now,
'updated_at' => $now,
];
}
}
DB::transaction(function () use ($uidToDisable, $messageToSend, $examUserIdArr, $userBanLog, $userModcommentUpdate, $userTable, $logPrefix) {
DB::transaction(function () use ($uidToDisable, $messageToSend, $examUserIdArr, $examUserToInsert, $userBanLog, $userModcommentUpdate, $userTable, $logPrefix) {
ExamUser::query()->whereIn('id', $examUserIdArr)->update(['status' => ExamUser::STATUS_FINISHED]);
do {
$deleted = ExamProgress::query()->whereIn('exam_user_id', $examUserIdArr)->limit(10000)->delete();
@@ -1144,6 +1172,9 @@ class ExamRepository extends BaseRepository
if (!empty($userBanLog)) {
UserBanLog::query()->insert($userBanLog);
}
if (!empty($examUserToInsert)) {
ExamUser::query()->insert($examUserToInsert);
}
});
}
return $result;