feat: assignments

This commit is contained in:
Baoshuo Ren 2022-09-20 08:28:38 +08:00
parent 945bd35776
commit 1ecf4e54b1
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A
9 changed files with 262 additions and 3 deletions

View File

@ -436,6 +436,22 @@ CREATE TABLE `groups_users` (
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `assignments`
--
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8mb4 */;
CREATE TABLE `assignments` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`list_id` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
`create_time` datetime NOT NULL,
`deadline` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `hacks`
--

View File

@ -0,0 +1,97 @@
<?php
if (!Auth::check()) {
become403Page(UOJLocale::get('need login'));
}
if (!isNormalUser($myUser)) {
become403Page();
}
requirePHPLib('form');
$assignment_id = $_GET['id'];
$assignment = queryAssignment($assignment_id);
if (!$assignment) {
become404Page();
}
$group = queryGroup($assignment['group_id']);
$list = queryProblemList($assignment['list_id']);
?>
<?php echoUOJPageHeader(UOJLocale::get('assignments')) ?>
<h2 style="margin-top: 24px">作业详细信息</h2>
<div class="row">
<div class="col-sm-12 mt-4">
<h5>作业信息</h5>
<ul>
<li><b>小组</b><a href="/group/<?= $group['id'] ?>"><?= $group['title'] ?></a></li>
<li><b>题单</b><a href="/problem_list/<?= $list['id'] ?>"><?= $list['title'] ?></a></li>
<li><b>创建时间</b><?= $assignment['create_time'] ?></li>
<li><b>截止时间</b><?= $assignment['deadline'] ?></li>
</ul>
</div>
</div>
<div class="row">
<div class="col-sm-12 mt-4">
<h5>完成状况</h5>
<?php
$query = DB::query("select problem_id from lists_problems where list_id = {$list['id']}");
$problem_ids = [];
while ($row = DB::fetch($query)) {
$problem_ids[] = $row['problem_id'];
}
$query = DB::query("select a.username as username, c.problem_id as problem_id from user_info a inner join groups_users b on a.username = b.username and b.group_id = {$group['id']} inner join best_ac_submissions c on a.username = c.submitter inner join lists_problems d on c.problem_id = d.problem_id and d.list_id = {$list['id']}");
$finished = [];
while ($row = DB::fetch($query)) {
$username = $row['username'];
$problem_id = $row['problem_id'];
if (!isset($finished[$username])) {
$finished[$username] = [];
}
$finished[$username][$problem_id] = 1;
}
$header_row = '';
$header_row .= '<tr>';
$header_row .= '<th style="width: 14em;">'.UOJLocale::get('username').'</th>';
foreach ($problem_ids as $problem_id) {
$header_row .= '<th style="width: 2em;">' . "<a href=\"/problem/{$problem_id}\">#{$problem_id}</a>" . '</th>';
}
$header_row .= '</tr>';
$print_row = function($row) use ($problem_ids, $finished) {
$username = $row['username'];
echo '<tr>';
echo '<td>' . getUserLink($username) . '</td>';
foreach ($problem_ids as $problem_id) {
if (!isset($finished[$username]) || !isset($finished[$username][$problem_id])) {
echo '<td class="failed"><i class="fa fa-times"></i></td>';
} else {
echo '<td class="success"><i class="fa fa-check"></i></td>';
}
}
echo '</tr>';
};
$from = "user_info a inner join groups_users b on (b.group_id = {$group['id']} and a.username = b.username)";
$col_names = array('a.username as username');
$cond = "1";
$tail = "order by a.username asc";
$config = array('page_len' => 100);
echoLongTable($col_names, $from, $cond, $tail, $header_row, $print_row, $config);
?>
</div>
</div>
<?php echoUOJPageFooter() ?>

View File

@ -325,7 +325,7 @@
}
}
if (isset($_POST['self_review_update__overall'])){
if (isset($_POST['self_review_update__overall'])) {
$esc_content = DB::escape($_POST['self_review_update__overall']);
DB::query("replace into contests_reviews (contest_id, problem_id, poster, content) values ({$contest['id']}, -1, '{$myUser['username']}', '$esc_content')");
}

View File

@ -96,6 +96,86 @@
DB::query("delete from groups_users where username='{$username}' and group_id={$group_id}");
};
$delete_user_form->runAtServer();
$add_new_assignment_form = new UOJForm('add_new_assignment');
$add_new_assignment_form->addInput('new_assignment_list_id', 'text', '题单 ID', '',
function ($x) {
global $group_id;
if (!validateUInt($x)) {
return '题单 ID 不合法';
}
$list = queryProblemList($x);
if (!$list) {
return '题单不存在';
}
if ($list['is_hidden'] != 0) {
return '题单是隐藏的';
}
if (queryAssignmentByGroupListID($group_id, $x)) {
return '该题单已经在作业中';
}
return '';
},
null
);
$default_ddl = new DateTime();
$default_ddl->setTime(17, 0, 0);
$default_ddl->add(new DateInterval("P7D"));
$add_new_assignment_form->addInput('new_assignment_deadline', 'text', '截止时间', $default_ddl->format('Y-m-d H:i'),
function ($x) {
$ddl = DateTime::createFromFormat('Y-m-d H:i', $x);
if (!$ddl) {
return '截止时间格式不正确,请以类似 "2020-10-1 17:00" 的格式输入';
}
return '';
},
null
);
$add_new_assignment_form->submit_button_config['align'] = 'compressed';
$add_new_assignment_form->submit_button_config['text'] = '添加作业';
$add_new_assignment_form->handle = function() {
global $group_id, $myUser;
$list_id = $_POST['new_assignment_list_id'];
$ddl = DateTime::createFromFormat('Y-m-d H:i', $_POST['new_assignment_deadline']);
$ddl_str = $ddl->format('Y-m-d H:i:s');
DB::insert("insert into assignments (group_id, list_id, create_time, deadline) values ({$group_id}, '{$list_id}', now(), '{$ddl_str}')");
};
$add_new_assignment_form->runAtServer();
$remove_assignment_form = new UOJForm('remove_assignment');
$remove_assignment_form->addInput('remove_assignment_list_id', 'text', '题单 ID', '',
function ($x) {
global $group_id;
if (!validateUInt($x)) {
return '题单 ID 不合法';
}
if (!queryAssignmentByGroupListID($group_id, $x)) {
return '该题单不在作业中';
}
return '';
},
null
);
$remove_assignment_form->submit_button_config['align'] = 'compressed';
$remove_assignment_form->submit_button_config['text'] = '删除作业';
$remove_assignment_form->handle = function() {
global $group_id, $myUser;
$list_id = $_POST['remove_assignment_list_id'];
DB::query("delete from assignments where list_id='{$list_id}' and group_id={$group_id}");
};
$remove_assignment_form->runAtServer();
}
?>
@ -118,8 +198,47 @@
echo '<time class="time">(', $ac['submit_time'], ')</time>';
echo '</li>';
}
if (!$current_ac) {
echo '(无)';
if (count($current_ac) == 0) {
echo '暂无最新动态';
}
?>
</ul>
</div>
</div>
<div class="row">
<div class="col-sm-12 mt-4">
<h5><?= UOJLocale::get('assignments') ?></h5>
<ul>
<?php
$assignments = queryGroupActiveAssignments($group['id']);
foreach ($assignments as $ass) {
$ddl = DateTime::createFromFormat('Y-m-d H:i:s', $ass['deadline']);
$create_time = DateTime::createFromFormat('Y-m-d H:i:s', $ass['create_time']);
$now = new DateTime();
if ($now->getTimestamp() - $ddl->getTimestamp() > 604800) {
continue;
} // 7d
echo '<li>';
echo "<a href=\"/problem_list/{$ass['list_id']}\">{$ass['title']} (题单 #{$ass['list_id']})</a>";
if ($ddl < $now) {
echo '<sup style="color:red">&nbsp;overdue</sup>';
} elseif ($ddl->getTimestamp() - $now->getTimestamp() < 86400) { // 1d
echo '<sup style="color:red">&nbsp;soon</sup>';
} elseif ($now->getTimestamp() - $create_time->getTimestamp() < 86400) { // 1d
echo '<sup style="color:red">&nbsp;new</sup>';
}
$ddl_str = $ddl->format('Y-m-d H:i');
echo " (截止时间: {$ddl_str}<a href=\"/assignment/{$ass['id']}\">查看完成情况</a>)";
echo '</li>';
}
if (count($assignments) == 0) {
echo '<p>暂无作业</p>';
}
?>
</ul>
@ -144,6 +263,12 @@
<h5>从小组中删除用户</h5>
<?php $delete_user_form->printHTML(); ?>
<h5>为小组添加作业</h5>
<?php $add_new_assignment_form->printHTML(); ?>
<h5>删除小组的作业</h5>
<?php $remove_assignment_form->printHTML(); ?>
<?php endif ?>
<?php echoUOJPageFooter() ?>

View File

@ -121,6 +121,16 @@ function queryGroupmateCurrentAC($username) {
function queryGroupCurrentAC($group_id) {
return DB::selectAll("select a.problem_id as problem_id, a.submitter as submitter, a.submission_id as submission_id, b.submit_time as submit_time, d.title as problem_title, b.submit_time as submit_time, e.realname as realname from best_ac_submissions a inner join submissions b on (a.submission_id = b.id) inner join groups_users c on (a.submitter = c.username and c.group_id = $group_id) inner join problems d on (a.problem_id = d.id and d.is_hidden = 0) inner join user_info e on (a.submitter = e.username) where b.submit_time > addtime(now(), '-360:00:00') order by b.submit_time desc limit 10", MYSQLI_ASSOC);
}
function queryGroupActiveAssignments($group_id) {
return DB::selectAll("select a.id as id, a.list_id as list_id, a.create_time as create_time, a.deadline as deadline, b.title from assignments a left join lists b on a.list_id = b.id where a.group_id = $group_id and a.deadline > addtime(now(), '-360:00:00') order by a.deadline asc", MYSQLI_ASSOC);
}
function queryAssignment($id) {
return DB::selectFirst("select * from assignments where id = $id", MYSQLI_ASSOC);
}
function queryAssignmentByGroupListID($group_id, $list_id) {
return DB::selectFirst("select * from assignments where list_id='$list_id' and group_id='$group_id'", MYSQLI_ASSOC);
}
function queryZanVal($id, $type, $user) {
if ($user == null) {

View File

@ -28,6 +28,7 @@ return [
'help' => 'Help',
'search' => 'Search',
'news' => 'News',
'assignments' => 'Assignments',
'username' => 'Username',
'password' => 'Password',
'new password' => 'New password',

View File

@ -28,6 +28,7 @@ return [
'help' => '帮助',
'search' => '搜索',
'news' => '最新动态',
'assignments' => '作业',
'username' => '用户名',
'password' => '密码',
'new password' => '新密码',

View File

@ -45,6 +45,8 @@ Route::group([
Route::any('/groups', '/groups.php');
Route::any('/group/{id}', '/group.php');
Route::any('/assignment/{id}', '/assignment.php');
Route::any('/blogs', '/blogs.php');
if (UOJConfig::$data['switch']['blog-domain-mode'] != 3) {

View File

@ -447,3 +447,10 @@ form.uoj-form-compressed button {
position: relative;
top: -6px;
}
td.success {
background-color: #99FF99;
}
td.failed {
background-color: #FF9999;
}