# 功能介绍

# 🏠 首页

首页可以显示公告列表、提交记录曲线、本周和上周的top10用户。 本周top10是指自本周一0点起至此时此刻,解决问题数量最多的10位用户。 上周top10是指上周一0点至上周日24点,解决问题数量最多的10位用户。

# 🖍 评测(提交记录)

以列表的形式展示所有的提交记录。注意,普通用户只能看到题库中的题目的提交记录,而无法看到竞赛中的提交记录;而管理员用户可以看到全量的提交记录。 该页面可以自动刷新最新的评测结果,用户无需手动刷新网页。

# 📜 题库

包含所有题目。普通用户只能看到非隐藏题目。管理员添加题目时可选择公开或隐藏题目(默认隐藏)。 题目唯一编号(题号)默认起始于1000,管理员添加题目自动生成(自增),无法修改,无法自定义。 对于每道题目,出题人应当设置以下属性:

  • 标题(必需)
  • 题目描述(必需)
  • 输入描述、输出描述、提示、题目来源(均为可选项)
  • 时间限制(必需,默认1000MS),对于C/C++之外的语言,判题服务自动放宽至2倍
  • 空间限制(必需,默认64MB),对于C/C++之外的语言,判题服务自动放宽至2倍
  • 样例(可选项),向选手提供若干组示例以帮助选手准确的理解题目
  • 特判(可选项),参考特判说明

# 测试数据

对于每道题目,出题人必需上传测试数据。测试数据必需成对出现,以后缀来区分输入和输出。

  • data.in,data.out 这是一组合法的测试数据
  • 1.in,1.ans 这也是一组合法的测试数据

# 问题标签

对于每道题目,若当前用户已通过,将被邀请填写题目标签,来标记这道题目所涉及的知识点。

# 其它功能

  1. 重判;管理员可以重判某些提交记录,可根据提交编号、题目编号、竞赛编号、时间区间这些选项来筛选提交记录并重判;
  2. 导入与导出;管理员可以以xml文件的方式导入或导出若干个题目;注意,不宜一次性导出大量题目,因为文件太大而无法生成。

# 🏆 竞赛

也可称为“作业”,包含所有竞赛。普通用户只能看到公开,且所在类别也公开的竞赛。 竞赛唯一编号默认起始于1000,管理员添加竞赛时自动生成(自增),无法修改,无法自定义。 对于每个竞赛,管理员可以设置以下属性:

  • 竞赛类别(必需,默认不分类且前台无法看到)
  • 标题(必需)
  • 描述信息(可选)
  • 附件(可选,创建者可以上传一些必要的文件)
  • 比赛时间(必需)
  • 封榜比例(必需,默认0),规定比赛结尾不刷新榜单的时间;例如封榜比例为 0.2 则表示比赛时间进行到80%时将冻结榜单,不再向选手展示最新的排名情况,但管理员仍可查看最新榜单
  • 参赛方式
    • public 所有能在看台看到该竞赛的人,皆可参与
    • password 选择此模式,必需设置密码;任何人进入竞赛,必需正确输入参赛密码
    • private 选择此模式,只有指定的用户可以进入竞赛
  • 竞赛题目
    • 题目列表;必需使用题目唯一编号(题号)来指定
    • 编程语言;参赛选手只能使用创建者指定的语言来提交代码
    • 榜单类型;ACMOI
    • 公开榜单;创建者可以设定是否将榜单公开在网络上

其它功能:在后台竞赛列表中,当管理员切换到某个具体的类别时,可以改变排列顺序。

# 竞赛类别

每个竞赛都拥有一个唯一的类别(若没设置则默认不分类)。前台查看竞赛时,已设为公开的类别将展示在导航菜单中,并展示该类别下的所有非隐藏竞赛。

  • 名称
  • 父类别(默认一级类别)
  • 类别简介

其它功能:在类别列表中,当管理员切换到某个具体的类别时,可以改变排列顺序。

# 👨‍👨‍👦 群组

类似于“班级”、“课程”等概念。

在实际教学、ACM集训中,某一门课程可能包含若干课时(例如32课时),每一课时都有对应的作业(竞赛),那么这些作业非常适合收集起来,提供给一批用户使用。 对于每个团队,创建者可以设定以下属性:

  • 标题(必需),可填写课程名
  • 课程简介(可选)
  • 作业列表(竞赛编号列表)

此外,管理员可以对团队成员进行管理。

# 🧑‍✈️ 权限管理

采用laravel第三方拓展包spatie/laravel-permission作为权限管理支持。该拓展包含以下数据表;

  • permissions —— 权限表;
  • roles —— 角色表;
  • role_has_permissions —— 角色-权限关联表,某角色所拥有的角色,一个角色能拥有多个权限;
  • model_has_permissions —— 模型-权限关联表,某用户所拥有的权限,一个用户能拥有多个权限;
  • model_has_roles —— 模型-角色关联表,某用户所拥有的角色,一个用户能拥有多个角色; 可以看出,该拓展允许用户跳过角色,直接拥有权限。用户-角色-权限之间的关系是多对多对多,即一个用户可拥有多个角色,一个角色包含若干条权限;反之,一个权限可包含于多个角色,一个角色可以应用于多个用户。

# 权限命名原则(permissions表的权限)

基于spatie/laravel-permission (opens new window)支持通配符匹配(详情),我们以.符号对权限进行分层,基本权限命名的基本格式为admin.{resource}.{action}.{target}。 对于通配符*,需要特别注意:

The * means "ALL". It does not mean "ANY".
Thus can('post.*') will only pass if the user has been assigned post.* explicitly.

意思是说,查询权限*时匹配的是“所有”(全部满足),而不是存在“任意一个”就够了。因此,当调用can('post.*')查询权限时,用户必须拥有权限post.*才能返回true。而当调用can('post.a')查询权限时,存在权限post.apost.*则返回true

以“公告”为例(其他权限只需将notice改为对应的单词),其增删改查权限是固有的:

  • admin.notice.create创建公告;
  • admin.notice.delete删除公告;
  • admin.notice.update修改公告;
  • admin.notice.view查看公告(仅针对隐藏的公告);
  • admin.notice等价于admin.notice.*,即匹配以上所有权限;
  • admin等价于admin.*,即超级管理员;

# 开发约定

为了提高系统安全性、易用性,我们做以下约定:

  • 用户必须通过“角色”获得相关权限,而不能直接获得权限。也就是说,此时model_has_permissions表是不使用的。例如用户admin想要成为超级管理员,应当拥有角色administrator,而角色administrator收录所有权限;
  • 普通用户默认视为学生,无需分配任何角色;

# 对公告、题库、竞赛等模块的影响

以“公告”为例(题库、竞赛等同理),权限判断遵循以下原则:

  • 创建公告;管理员的角色中,存在权限admin.notice.create或更高;
  • 删除/修改公告;角色中存在权限admin.notice.delete/admin.notice.update或更高,或者自己是创建者
  • 查看公告;
    • 对于隐藏的条目,角色中存在权限admin.notice.view或更高,或者自己是创建者
    • 对于前台公开的条目,不检查权限,即任意用户可获取;

# 角色配置技巧

如果希望某角色,能够创建公告,能够浏览所有公告,但只允许修改/删除自己创建的公告,则只需给该角色分配以下权限:

  • admin.view;使用户能够进入后台管理页面;
  • admin.notice.view
  • admin.notice.create
上次更新: 4/4/2024, 8:40:36 AM