[ 'name' => '首页管理', 'url' => "/super_manage/index", ], 'users' => [ 'name' => '用户管理', 'url' => "/super_manage/users", ], 'submissions' => [ 'name' => '提交记录', 'url' => "/super_manage/submissions", ], 'custom_test' => [ 'name' => '自定义测试', 'url' => "/super_manage/custom_test", ], 'judger' => [ 'name' => '评测机管理', 'url' => "/super_manage/judger", ], 'image_hosting' => [ 'name' => '图床管理', 'url' => "/super_manage/image_hosting", ], ]; if (!isset($tabs_info[$cur_tab])) { become404Page(); } if ($cur_tab == 'index') { // ========== 公告 ========== if (UOJRequest::post('submit-delete_announcement') === 'delete_announcement') { crsf_defend(); $blog_id = UOJRequest::post('blog_id'); if (!validateUInt($blog_id)) { dieWithAlert('移除失败:博客 ID 无效'); } DB::delete([ "delete from important_blogs", "where", [ "blog_id" => $blog_id, ] ]); dieWithAlert('移除成功!'); } $announcements = DB::selectAll([ "select", DB::fields([ "id" => "blogs.id", "title" => "blogs.title", "poster" => "blogs.poster", "realname" => "user_info.realname", "post_time" => "blogs.post_time", "level" => "important_blogs.level", "is_hidden" => "blogs.is_hidden", ]), "from blogs", "inner join important_blogs on important_blogs.blog_id = blogs.id", "inner join user_info on blogs.poster = user_info.username", "order by level desc, important_blogs.blog_id desc", ]); $add_announcement_form = new UOJBs4Form('add_announcement'); $add_announcement_form->addInput( 'blog_id', 'text', '博客 ID', '', function ($id, &$vdata) { if (!validateUInt($id)) { return '博客 ID 无效'; } if (!queryBlog($id)) { return '博客不存在'; } $vdata['blog_id'] = $id; return ''; }, null ); $add_announcement_form->addInput( 'blog_level', 'text', '置顶级别', '0', function ($x, &$vdata) { if (!validateUInt($x)) { return '数字不合法'; } if ($x > 3) { return '该级别不存在'; } $vdata['level'] = $x; return ''; }, null ); $add_announcement_form->handle = function (&$vdata) { $blog_id = $vdata['blog_id']; $blog_level = $vdata['level']; if (DB::selectExists([ "select * from important_blogs", "where", [ "blog_id" => $blog_id, ] ])) { DB::update([ "update important_blogs", "set", [ "level" => $blog_level, ], "where", [ "blog_id" => $blog_id, ] ]); } else { DB::insert([ "insert into important_blogs", DB::bracketed_fields(["blog_id", "level"]), "values", DB::tuple([$blog_id, $blog_level]), ]); } }; $add_announcement_form->submit_button_config['align'] = 'compressed'; $add_announcement_form->submit_button_config['text'] = '提交'; $add_announcement_form->succ_href = '/super_manage/index#announcements'; $add_announcement_form->runAtServer(); // ========== 倒计时 ========== if (UOJRequest::post('submit-delete_countdown') === 'delete_countdown') { crsf_defend(); $countdown_id = UOJRequest::post('countdown_id'); if (!validateUInt($countdown_id)) { dieWithAlert('删除失败:倒计时 ID 无效'); } DB::delete([ "delete from countdowns", "where", [ "id" => $countdown_id, ] ]); dieWithAlert('删除成功!'); } $countdowns = DB::selectAll([ "select", DB::fields(["id", "title", "end_time"]), "from countdowns", "order by end_time asc", ]); $add_countdown_form = new UOJBs4Form('add_countdown'); $add_countdown_form->addInput( 'countdown_title', 'text', '标题', '', function ($title, &$vdata) { if ($title == '') { return '标题不能为空'; } $vdata['title'] = $title; return ''; }, null ); $add_countdown_form->addInput( 'countdown_end_time', 'text', '结束时间', date("Y-m-d H:i:s"), function ($end_time, &$vdata) { try { $vdata['end_time'] = new DateTime($end_time); } catch (Exception $e) { return '无效时间格式'; } return ''; }, null ); $add_countdown_form->handle = function (&$vdata) { DB::insert([ "insert into countdowns", DB::bracketed_fields(["title", "end_time"]), "values", DB::tuple([$vdata['title'], $vdata['end_time']->format('Y-m-d H:i:s')]), ]); }; $add_countdown_form->submit_button_config['align'] = 'compressed'; $add_countdown_form->submit_button_config['text'] = '添加'; $add_countdown_form->succ_href = '/super_manage/index#countdowns'; $add_countdown_form->runAtServer(); // ========== 常用链接 ========== if (UOJRequest::post('submit-delete_link') === 'delete_link') { crsf_defend(); $link_id = UOJRequest::post('link_id'); if (!validateUInt($link_id)) { dieWithAlert('删除失败:ID 无效'); } DB::delete([ "delete from friend_links", "where", [ "id" => $link_id, ] ]); dieWithAlert('删除成功!'); } $links = DB::selectAll([ "select", DB::fields(["id", "title", "url", "level"]), "from friend_links", "order by level desc, id asc", ]); $add_link_form = new UOJBs4Form('add_link'); $add_link_form->addInput( 'link_title', 'text', '标题', '', function ($title, &$vdata) { if ($title == '') { return '标题不能为空'; } $vdata['title'] = $title; return ''; }, null ); $add_link_form->addInput( 'link_url', 'text', '链接', '', function ($url, &$vdata) { if (!validateURL($url)) { return '链接不合法'; } $vdata['url'] = $url; return ''; }, null ); $add_link_form->addInput( 'link_level', 'text', '权重', '10', function ($level, &$vdata) { if (!validateUInt($level)) { return '数字不合法'; } $vdata['level'] = $level; return ''; }, null ); $add_link_form->handle = function (&$vdata) { DB::insert([ "insert into friend_links", DB::bracketed_fields(["title", "url", "level"]), "values", DB::tuple([$vdata['title'], $vdata['url'], $vdata['level']]), ]); }; $add_link_form->submit_button_config['align'] = 'compressed'; $add_link_form->submit_button_config['text'] = '添加'; $add_link_form->succ_href = '/super_manage/index#links'; $add_link_form->runAtServer(); } elseif ($cur_tab == 'users') { $user_list_cond = []; if (isset($_GET['username']) && $_GET['username'] != "") { $user_list_cond[] = "username like '%" . DB::escape($_GET['username']) . "%'"; } if (isset($_GET['usergroup']) && $_GET['usergroup'] != "") { $user_list_cond[] = "usergroup = '" . DB::escape($_GET['usergroup']) . "'"; } if (isset($_GET['usertype']) && $_GET['usertype'] != "") { $user_list_cond[] = "usertype like '%" . DB::escape($_GET['usertype']) . "%'"; } if ($user_list_cond) { $user_list_cond = implode(' and ', $user_list_cond); } else { $user_list_cond = '1'; } $register_form = new UOJBs4Form('register'); $register_form->addVInput( 'new_username', 'text', '用户名', '', function ($username, &$vdata) { if (!validateUsername($username)) { return '用户名不合法'; } if (queryUser($username)) { return '该用户已存在'; } $vdata['username'] = $username; return ''; }, null ); $register_form->addVInput( 'new_password', 'password', '密码', '', function ($password, &$vdata) { $vdata['password'] = $password; return ''; }, 'validatePassword' ); $register_form->addVInput( 'new_email', 'text', '电子邮件(选填)', '', function ($email, &$vdata) { if ($email && !validateEmail($email)) { return '邮件地址不合法'; } $vdata['email'] = $email; return ''; }, null ); $register_form->addVInput( 'new_realname', 'text', '真实姓名(选填)', '', function ($realname, &$vdata) { $vdata['realname'] = $realname; return ''; }, null ); $register_form->addVInput( 'new_school', 'text', '学校名称(选填)', '', function ($school, &$vdata) { $vdata['school'] = $school; return ''; }, null ); $register_form->handle = function (&$vdata) { $user = [ 'username' => $vdata['username'], 'realname' => $vdata['realname'], 'school' => $vdata['school'], 'email' => $vdata['email'], 'password' => hash_hmac('md5', $vdata['password'], getPasswordClientSalt()), ]; UOJUser::register($user, ['check_email' => false]); dieWithJsonData(['status' => 'success', 'message' => '']); }; $register_form->setAjaxSubmit(<<runAtServer(); $change_password_form = new UOJBs4Form('change_password'); $change_password_form->addVInput( 'p_username', 'text', '用户名', '', function ($username, &$vdata) { if (!validateUsername($username)) { return '用户名不合法'; } if (!queryUser($username)) { return '用户不存在'; } $vdata['username'] = $username; return ''; }, null ); $change_password_form->addVInput( 'p_password', 'password', '密码', '', function ($password, &$vdata) { $vdata['password'] = $password; return ''; }, 'validatePassword' ); $change_password_form->handle = function (&$vdata) { $password = hash_hmac('md5', $vdata['password'], getPasswordClientSalt()); DB::update([ "update user_info", "set", [ "password" => getPasswordToStore($password, $vdata['username']), ], "where", [ "username" => $vdata['username'], ], ]); dieWithJsonData(['status' => 'success', 'message' => '用户 ' . $vdata['username'] . ' 的密码已经被成功重置。']); }; $change_password_form->submit_button_config['class_str'] = 'btn btn-secondary mt-3'; $change_password_form->submit_button_config['text'] = '重置'; $change_password_form->setAjaxSubmit(<<runAtServer(); $change_usergroup_form = new UOJBs4Form('change_usergroup'); $change_usergroup_form->addVInput( 'username', 'text', '用户名', '', function ($username, &$vdata) { if (!validateUsername($username)) { return '用户名不合法'; } if (!queryUser($username)) { return '用户不存在'; } $vdata['username'] = $username; return ''; }, null ); $change_usergroup_form->addVSelect('op_type', [ 'banneduser' => '设为封禁用户', 'normaluser' => '设为普通用户', 'superuser' => '设为超级用户', ], '操作类型', ''); $change_usergroup_form->handle = function ($vdata) { $username = $vdata['username']; $usergroup = ''; switch ($_POST['op_type']) { case 'banneduser': DB::update("update user_info set usergroup = 'B', usertype = 'banned' where username = '{$username}'"); $usergroup = '被封禁的用户'; break; case 'normaluser': DB::update("update user_info set usergroup = 'U', usertype = 'student' where username = '{$username}'"); $usergroup = '普通用户'; break; case 'superuser': DB::update("update user_info set usergroup = 'S', usertype = 'student' where username = '{$username}'"); $usergroup = '超级用户'; break; } dieWithJsonData(['status' => 'success', 'message' => '用户 ' . $username . ' 现在是 ' . $usergroup . '。']); }; $change_usergroup_form->setAjaxSubmit(<<runAtServer(); } elseif ($cur_tab == 'submissions') { } elseif ($cur_tab == 'custom_test') { requireLib('hljs'); $submissions_pag = new Paginator([ 'col_names' => ['*'], 'table_name' => 'custom_test_submissions', 'cond' => '1', 'tail' => 'order by id desc', 'page_len' => 10 ]); $custom_test_deleter = new UOJBs4Form('custom_test_deleter'); $custom_test_deleter->addInput( 'last', 'text', '删除末尾记录', '5', function ($x, &$vdata) { if (!validateUInt($x)) { return '不合法'; } $vdata['last'] = $x; return ''; }, null ); $custom_test_deleter->handle = function (&$vdata) { $all = DB::selectAll("select * from custom_test_submissions order by id asc limit {$vdata['last']}"); foreach ($all as $submission) { $content = json_decode($submission['content'], true); unlink(UOJContext::storagePath() . $content['file_name']); } DB::delete("delete from custom_test_submissions order by id asc limit {$vdata['last']}"); }; $custom_test_deleter->submit_button_config['align'] = 'compressed'; $custom_test_deleter->runAtServer(); } elseif ($cur_tab == 'judger') { $judger_adder = new UOJBs4Form('judger_adder'); $judger_adder->addInput( 'judger_adder_name', 'text', '评测机名称', '', function ($x, &$vdata) { if (!validateUsername($x)) { return '不合法'; } if (DB::selectCount("select count(*) from judger_info where judger_name='$x'") != 0) { return '不合法'; } $vdata['name'] = $x; return ''; }, null ); $judger_adder->handle = function (&$vdata) { $password = uojRandString(32); DB::insert("insert into judger_info (judger_name,password) values('{$vdata['name']}','{$password}')"); }; $judger_adder->submit_button_config['align'] = 'compressed'; $judger_adder->runAtServer(); $judger_deleter = new UOJBs4Form('judger_deleter'); $judger_deleter->addInput( 'judger_deleter_name', 'text', '评测机名称', '', function ($x, &$vdata) { if (!validateUsername($x)) { return '不合法'; } if (DB::selectCount("select count(*) from judger_info where judger_name='$x'") != 1) { return '不合法'; } $vdata['name'] = $x; return ''; }, null ); $judger_deleter->handle = function (&$vdata) { DB::delete("delete from judger_info where judger_name='{$vdata['name']}'"); }; $judger_deleter->submit_button_config['align'] = 'compressed'; $judger_deleter->runAtServer(); } elseif ($cur_tab == 'image_hosting') { if (isset($_POST['submit-delete_image']) && $_POST['submit-delete_image'] == 'delete_image') { crsf_defend(); $image_id = $_POST['image_id']; if (!validateUInt($image_id)) { dieWithAlert('删除失败:图片 ID 无效'); } if (!($image = DB::selectFirst("SELECT * from users_images where id = $image_id"))) { dieWithAlert('删除失败:图片不存在'); } unlink(UOJContext::storagePath() . $result['path']); DB::delete("DELETE FROM users_images WHERE id = $image_id"); dieWithAlert('删除成功!'); } $change_user_image_total_size_limit_form = new UOJBs4Form('change_user_image_total_size_limit'); $change_user_image_total_size_limit_form->submit_button_config['align'] = 'compressed'; $change_user_image_total_size_limit_form->addInput( 'change_user_image_total_size_limit_username', 'text', '用户名', '', function ($x, &$vdata) { if (!validateUsername($x)) { return '用户名不合法'; } if (!queryUser($x)) { return '用户不存在'; } $vdata['username'] = $x; return ''; }, null ); $change_user_image_total_size_limit_form->addInput( 'change_user_image_total_size_limit_limit', 'text', '存储限制(单位:Byte)', '104857600', function ($x, &$vdata) { if (!validateUInt($x, 10)) { return '限制不合法'; } if (intval($x) > 2147483648) { return '限制不能大于 2 GB'; } $vdata['limit'] = $x; return ''; }, null ); $change_user_image_total_size_limit_form->handle = function (&$vdata) { DB::update([ "update user_info", "set", [ 'extra' => DB::json_set( 'extra', '$.image_hosting.total_size_limit', $vdata['limit'], ), ], "where", ["username" => $vdata['username']] ]); }; $change_user_image_total_size_limit_form->runAtServer(); } ?>

添加/修改公告
printHTML(); ?>
添加倒计时
printHTML(); ?>
用户名 学校 用户类别 权限 注册时间 操作 EOD, function ($row) { echo ''; echo '', '', $row['username'], '', ''; echo '', HTML::escape($row['school']), ''; echo ''; switch ($row['usergroup']) { case 'S': echo UOJLocale::get('user::super user'); break; case 'B': echo UOJLocale::get('user::banned user'); break; default: echo UOJLocale::get('user::normal user'); break; } echo ''; echo ''; foreach (explode(',', $row['usertype']) as $idx => $type) { if ($idx) { echo ', '; } echo UOJLocale::get('user::' . str_replace('_', ' ', $type)) ?: HTML::escape($type); } echo ''; echo '', $row['register_time'], ''; echo '', '编辑', ''; echo ''; }, [ 'page_len' => 20, 'div_classes' => ['table-responsive'], 'table_classes' => ['table', 'align-middle'], ], ); ?>
printHTML() ?>
注意事项
  • 用户名推荐格式为年级 + 姓名全拼,如 2022 级的张三同学可以设置为 2022zhangsan。对于外校学生,推荐格式为学校名称缩写 + 姓名拼音首字母,如山大附中的赵锦熙同学可以设置为 sdfzzjx)。
  • 请提醒用户及时修改初始密码,以免账号被盗导致教学资源流出。请勿设置过于简单的初始密码。
  • 我们推荐在创建账号时输入号主的电子邮件地址以便后期发生忘记密码等情况时进行验证。
  • 创建账号后可以在「修改个人信息」页面中的「特权」选项卡为用户分配权限。特别地,如果该用户是外校学生,那么您可能需要将其设置为「仅比赛参加者」以禁止其查看已参与比赛以外的题目。
printHTML() ?>
注意事项
  • 在为用户重置密码前请核对对方身份以免被骗。
  • 请勿设置过于简单的密码。
  • 请提醒用户在登录后及时修改初始密码。
printHTML() ?>
注意事项
  • 用户被封禁后将不能再次登录系统。
  • 将当前用户移除权限后将无法再次访问本页面。
  • 在修改用户类别前请仔细核对用户名以免产生不必要的麻烦。

测评失败的提交记录

'', 'table_config' => [ 'div_classes' => ['card', 'mb-3', 'table-responsive'], 'table_classes' => ['table', 'uoj-table', 'mb-0', 'text-center'] ] ], $myUser ); ?>
get() as $submission) : ?> isEmpty()) : ?>
ID 题目 ID 提交者 提交时间 测评时间
# #
pagination() ?>
删除末尾的 n 条记录
printHTML() ?>

评测机列表

评测机名称 密码 IP EOD, function ($row) { echo << {$row['judger_name']} {$row['password']} {$row['ip']} EOD; }, [ 'page_len' => 10, 'div_classes' => ['card', 'mb-3', 'table-responsive'], 'table_classes' => ['table', 'uoj-table', 'mb-0'], ] ); ?>
添加评测机
printHTML(); ?>
删除评测机
printHTML(); ?>
上传者 预览 文件大小 上传时间 操作 EOD, function ($row) { $user_link = getUserLink($row['uploader']); if ($row['size'] < 1024 * 512) { $size = strval(round($row['size'] * 1.0 / 1024, 1)) . ' KB'; } else { $size = strval(round($row['size'] * 1.0 / 1024 / 1024, 1)) . ' MB'; } $token = crsf_token(); echo << $user_link $size {$row['upload_time']}
EOD; }, [ 'page_len' => 20, 'div_classes' => ['card', 'mb-3', 'table-responsive'], 'table_classes' => ['table', 'uoj-table', 'mb-0'], ] ); ?>
修改用户图床空间上限
printHTML() ?>