Files
OJ2/apps/web/src/routes.ts
T
2026-10-26 13:52:24 +08:00

356 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { RouteRecordRaw } from 'vue-router'
export const ojs: RouteRecordRaw = {
path: '/',
component: () => import('shared/layout/default.vue'),
children: [
// 登录后是个人首页,没登录还是题目列表(见 oj/home/index.vue)
{ path: '', component: () => import('oj/home/index.vue'), name: 'home' },
{ path: 'problem', component: () => import('oj/problem/list.vue'), name: 'problems' },
{
path: 'problem/:problemID',
component: () => import('oj/problem/detail.vue'),
props: true,
name: 'problem',
},
{
path: 'submission',
component: () => import('oj/submission/list.vue'),
name: 'submissions',
},
{
path: 'submission/:submissionID',
component: () => import('oj/submission/detail.vue'),
props: true,
meta: { requiresAuth: true },
},
{
path: 'contest',
component: () => import('oj/contest/list.vue'),
name: 'contests',
},
{
path: 'contest/:contestID',
component: () => import('oj/contest/detail.vue'),
props: true,
meta: { requiresAuth: true },
children: [
{
path: '',
component: () => import('oj/contest/pages/problems.vue'),
props: true,
meta: { requiresAuth: true },
name: 'contest problems',
},
{
path: 'submission',
component: () => import('oj/submission/list.vue'),
meta: { requiresAuth: true },
name: 'contest submissions',
},
{
path: 'rank',
component: () => import('oj/contest/pages/rank.vue'),
props: true,
meta: { requiresAuth: true },
name: 'contest rank',
},
// 老师的「全班情况」,考完是「成绩」(代替原来后台的「审核」页)
{
path: 'class',
component: () => import('oj/contest/pages/class.vue'),
props: true,
meta: { requiresAuth: true },
name: 'contest class',
},
],
},
{
path: 'contest/:contestID/problem/:problemID',
component: () => import('oj/problem/detail.vue'),
props: true,
name: 'contest problem',
meta: { requiresAuth: true },
},
{
path: 'rank',
name: 'rank',
component: () => import('oj/rank/list.vue'),
},
{
path: 'classroom',
name: 'classroom board',
component: () => import('oj/classroom/board.vue'),
meta: { requiresAuth: true, requiresTeacherAdmin: true },
},
{
path: 'statistics',
name: 'statistics',
component: () => import('oj/statistics/index.vue'),
meta: { requiresAuth: true, requiresTeacherAdmin: true },
},
{
path: 'class',
name: 'class',
component: () => import('oj/class/pk.vue'),
meta: { requiresAuth: true },
},
{
path: 'announcement',
name: 'announcements',
component: () => import('oj/announcement/list.vue'),
},
{
path: 'user',
component: () => import('oj/user/index.vue'),
meta: { requiresAuth: true },
},
{
path: 'achievement',
name: 'achievement',
component: () => import('oj/achievement/index.vue'),
meta: { requiresAuth: true },
},
{
path: 'learn',
name: 'learn home',
component: () => import('oj/learn/home.vue'),
},
{
path: 'learn/:type/:step',
name: 'learn',
component: () => import('oj/learn/index.vue'),
props: true,
},
{
path: 'ai-analysis',
name: 'ai',
component: () => import('oj/ai/analysis.vue'),
meta: { requiresAuth: true },
},
{
path: 'problemset',
component: () => import('oj/problemset/list.vue'),
name: 'problemsets',
},
{
path: 'problemset/:problemSetId',
component: () => import('oj/problemset/detail.vue'),
props: true,
name: 'problemset',
},
{
path: 'problemset/:problemSetId/problem/:problemID',
component: () => import('oj/problem/detail.vue'),
props: true,
name: 'problemset problem',
meta: { requiresAuth: true },
},
// 兜底:没有它,打错地址是一整页空白,连顶栏都没有。vue-router 按路径具体程度排序,
// 不按注册顺序,所以它吃不掉别的路由;/admin 下打错的也落到这里
{
path: ':pathMatch(.*)*',
name: 'not found',
component: () => import('shared/components/NotFound.vue'),
props: { title: '这个页面不存在', hint: '可能是地址打错了,或者这个页面已经下线' },
},
],
}
export const admins: RouteRecordRaw = {
path: '/admin',
component: () => import('shared/layout/admin.vue'),
children: [
{
path: '',
name: 'admin home',
component: () => import('admin/setting/home.vue'),
meta: { requiresSuperAdmin: true },
},
{
path: 'config',
name: 'admin config',
component: () => import('admin/setting/config.vue'),
meta: { requiresSuperAdmin: true },
},
{
path: 'user/list',
name: 'admin user list',
component: () => import('admin/user/list.vue'),
meta: { requiresSuperAdmin: true },
},
{
path: 'user/generate',
name: 'admin user generate',
component: () => import('admin/user/generate.vue'),
meta: { requiresSuperAdmin: true },
},
// admin和super_admin都可以访问的路由 (需要题目权限)
{
path: 'problem/list',
name: 'admin problem list',
component: () => import('admin/problem/list.vue'),
meta: { requiresProblemPermission: true },
},
{
path: 'problem/tags',
name: 'admin tag list',
component: () => import('admin/problem/tags.vue'),
meta: { requiresProblemPermission: true },
},
{
path: 'problem/create',
name: 'admin problem create',
component: () => import('admin/problem/editor.vue'),
meta: { requiresProblemPermission: true },
},
{
path: 'problem/edit/:problemID',
name: 'admin problem edit',
component: () => import('admin/problem/editor.vue'),
props: true,
meta: { requiresProblemPermission: true },
},
{
path: 'contest/list',
name: 'admin contest list',
component: () => import('admin/contest/list.vue'),
meta: { requiresTeacherAdmin: true },
},
{
path: 'contest/create',
name: 'admin contest create',
component: () => import('admin/contest/detail.vue'),
meta: { requiresTeacherAdmin: true },
},
{
path: 'contest/edit/:contestID',
name: 'admin contest edit',
component: () => import('admin/contest/detail.vue'),
props: true,
meta: { requiresTeacherAdmin: true },
},
{
path: 'contest/:contestID/problem/list',
name: 'admin contest problem list',
component: () => import('admin/problem/list.vue'),
props: true,
meta: { requiresTeacherAdmin: true },
},
{
path: 'contest/:contestID/problem/create',
name: 'admin contest problem create',
component: () => import('admin/problem/editor.vue'),
props: true,
meta: { requiresTeacherAdmin: true },
},
{
path: 'contest/:contestID/problem/edit/:problemID',
name: 'admin contest problem edit',
component: () => import('admin/problem/editor.vue'),
props: true,
meta: { requiresTeacherAdmin: true },
},
// 只有super_admin可以访问的路由
{
path: 'announcement/list',
name: 'admin announcement list',
component: () => import('admin/announcement/list.vue'),
meta: { requiresSuperAdmin: true },
},
{
path: 'announcement/create',
name: 'admin announcement create',
component: () => import('admin/announcement/detail.vue'),
meta: { requiresSuperAdmin: true },
},
{
path: 'announcement/edit/:announcementID',
name: 'admin announcement edit',
component: () => import('admin/announcement/detail.vue'),
props: true,
meta: { requiresSuperAdmin: true },
},
{
path: 'tutorial/list',
name: 'admin tutorial list',
component: () => import('admin/tutorial/list.vue'),
meta: { requiresSuperAdmin: true },
},
{
path: 'tutorial/create',
name: 'admin tutorial create',
component: () => import('admin/tutorial/detail.vue'),
meta: { requiresSuperAdmin: true },
},
{
path: 'tutorial/edit/:tutorialID',
name: 'admin tutorial edit',
component: () => import('admin/tutorial/detail.vue'),
props: true,
meta: { requiresSuperAdmin: true },
},
{
path: 'problem/stuck',
name: 'admin stuck problems',
component: () => import('admin/problem/Stuck.vue'),
meta: { requiresTeacherAdmin: true },
},
{
path: 'problem/trend',
name: 'admin grade trend',
component: () => import('admin/problem/Trend.vue'),
meta: { requiresTeacherAdmin: true },
},
// 题单管理路由
{
path: 'problemset/list',
name: 'admin problemset list',
component: () => import('admin/problemset/list.vue'),
meta: { requiresTeacherAdmin: true },
},
{
path: 'achievement/list',
name: 'admin achievement list',
// 后端 admin 接口是 super_admin_required,这里必须跟着用
// requiresSuperAdmin,否则教师能进页面但每个请求都 403
component: () => import('admin/achievement/list.vue'),
meta: { requiresSuperAdmin: true },
},
{
path: 'problemset/create',
name: 'admin problemset create',
component: () => import('admin/problemset/edit.vue'),
meta: { requiresTeacherAdmin: true },
},
{
path: 'problemset/edit/:problemSetId',
name: 'admin problemset edit',
component: () => import('admin/problemset/edit.vue'),
props: true,
meta: { requiresTeacherAdmin: true },
},
// 原来的「详情」页(题目 / 奖章 / 进度三个页签)并进了一屏编辑,老链接转过去
{
path: 'problemset/:problemSetId',
name: 'admin problemset detail',
redirect: (to) => ({
name: 'admin problemset edit',
params: { problemSetId: to.params.problemSetId },
}),
},
{
path: 'ai/reports',
name: 'admin ai reports',
component: () => import('admin/ai/list.vue'),
meta: { requiresTeacherAdmin: true },
},
{
path: 'learn',
name: 'admin learn analytics',
component: () => import('admin/learn/index.vue'),
meta: { requiresTeacherAdmin: true },
},
],
}