From 1ecf4e54b1952a7725b7d4bcc9fd0b44e2308d59 Mon Sep 17 00:00:00 2001 From: Baoshuo Date: Tue, 20 Sep 2022 08:28:38 +0800 Subject: [PATCH] feat: assignments --- db/app_uoj233.sql | 16 +++ web/app/controllers/assignment.php | 97 +++++++++++++++++++ web/app/controllers/contest_inside.php | 2 +- web/app/controllers/group.php | 129 ++++++++++++++++++++++++- web/app/libs/uoj-query-lib.php | 10 ++ web/app/locale/basic/en.php | 1 + web/app/locale/basic/zh-cn.php | 1 + web/app/route.php | 2 + web/css/uoj-theme.css | 7 ++ 9 files changed, 262 insertions(+), 3 deletions(-) create mode 100644 web/app/controllers/assignment.php diff --git a/db/app_uoj233.sql b/db/app_uoj233.sql index 5b3e275..cf13048 100644 --- a/db/app_uoj233.sql +++ b/db/app_uoj233.sql @@ -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` -- diff --git a/web/app/controllers/assignment.php b/web/app/controllers/assignment.php new file mode 100644 index 0000000..2c348a0 --- /dev/null +++ b/web/app/controllers/assignment.php @@ -0,0 +1,97 @@ + + + + +

作业详细信息

+ +
+
+
作业信息
+
    +
  • 小组
  • +
  • 题单
  • +
  • 创建时间
  • +
  • 截止时间
  • +
+
+
+ +
+
+
完成状况
+ +'; + $header_row .= ''.UOJLocale::get('username').''; + foreach ($problem_ids as $problem_id) { + $header_row .= '' . "#{$problem_id}" . ''; + } + $header_row .= ''; + + $print_row = function($row) use ($problem_ids, $finished) { + $username = $row['username']; + + echo ''; + echo '' . getUserLink($username) . ''; + foreach ($problem_ids as $problem_id) { + if (!isset($finished[$username]) || !isset($finished[$username][$problem_id])) { + echo ''; + } else { + echo ''; + } + } + echo ''; + }; + + $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); + ?> + +
+
+ + diff --git a/web/app/controllers/contest_inside.php b/web/app/controllers/contest_inside.php index f97afff..5c14d47 100644 --- a/web/app/controllers/contest_inside.php +++ b/web/app/controllers/contest_inside.php @@ -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')"); } diff --git a/web/app/controllers/group.php b/web/app/controllers/group.php index aabaebb..358b140 100644 --- a/web/app/controllers/group.php +++ b/web/app/controllers/group.php @@ -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 ''; echo ''; } - if (!$current_ac) { - echo '(无)'; + if (count($current_ac) == 0) { + echo '暂无最新动态'; + } + ?> + + + + +
+
+
+
    + getTimestamp() - $ddl->getTimestamp() > 604800) { + continue; + } // 7d + + echo '
  • '; + echo "{$ass['title']} (题单 #{$ass['list_id']})"; + + if ($ddl < $now) { + echo ' overdue'; + } elseif ($ddl->getTimestamp() - $now->getTimestamp() < 86400) { // 1d + echo ' soon'; + } elseif ($now->getTimestamp() - $create_time->getTimestamp() < 86400) { // 1d + echo ' new'; + } + + $ddl_str = $ddl->format('Y-m-d H:i'); + echo " (截止时间: {$ddl_str},查看完成情况)"; + echo '
  • '; + } + + if (count($assignments) == 0) { + echo '

    暂无作业

    '; } ?>
@@ -144,6 +263,12 @@
从小组中删除用户
printHTML(); ?> + +
为小组添加作业
+printHTML(); ?> + +
删除小组的作业
+printHTML(); ?> diff --git a/web/app/libs/uoj-query-lib.php b/web/app/libs/uoj-query-lib.php index 429c7d7..362329c 100644 --- a/web/app/libs/uoj-query-lib.php +++ b/web/app/libs/uoj-query-lib.php @@ -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) { diff --git a/web/app/locale/basic/en.php b/web/app/locale/basic/en.php index 7c17bd5..15105c8 100644 --- a/web/app/locale/basic/en.php +++ b/web/app/locale/basic/en.php @@ -28,6 +28,7 @@ return [ 'help' => 'Help', 'search' => 'Search', 'news' => 'News', + 'assignments' => 'Assignments', 'username' => 'Username', 'password' => 'Password', 'new password' => 'New password', diff --git a/web/app/locale/basic/zh-cn.php b/web/app/locale/basic/zh-cn.php index abc9a40..78435b1 100644 --- a/web/app/locale/basic/zh-cn.php +++ b/web/app/locale/basic/zh-cn.php @@ -28,6 +28,7 @@ return [ 'help' => '帮助', 'search' => '搜索', 'news' => '最新动态', + 'assignments' => '作业', 'username' => '用户名', 'password' => '密码', 'new password' => '新密码', diff --git a/web/app/route.php b/web/app/route.php index 613ec2b..f2efc20 100644 --- a/web/app/route.php +++ b/web/app/route.php @@ -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) { diff --git a/web/css/uoj-theme.css b/web/css/uoj-theme.css index 26b3691..58fa95a 100644 --- a/web/css/uoj-theme.css +++ b/web/css/uoj-theme.css @@ -447,3 +447,10 @@ form.uoj-form-compressed button { position: relative; top: -6px; } + +td.success { + background-color: #99FF99; +} +td.failed { + background-color: #FF9999; +}