feat: update frontend for four-tier role system
Add Student Admin and Teacher Admin roles to constants, types, store, permissions, routes, and admin UI. Teacher Admin sees contests and problemsets in sidebar; Student Admin sees only problems. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -133,7 +133,8 @@ export const CONTEST_TYPE = {
|
||||
|
||||
export const USER_TYPE = {
|
||||
REGULAR_USER: "Regular User",
|
||||
ADMIN: "Admin",
|
||||
STUDENT_ADMIN: "Student Admin",
|
||||
TEACHER_ADMIN: "Teacher Admin",
|
||||
SUPER_ADMIN: "Super Admin",
|
||||
}
|
||||
|
||||
|
||||
@@ -133,15 +133,22 @@ export function debounce<T extends (...args: any[]) => any>(
|
||||
}
|
||||
|
||||
export function getUserRole(role: User["admin_type"]): {
|
||||
type: "default" | "info" | "error"
|
||||
label: "普通" | "管理员" | "超管"
|
||||
type: "default" | "info" | "warning" | "error"
|
||||
label: "普通" | "学生管理员" | "教师管理员" | "超管"
|
||||
} {
|
||||
const roleMap = {
|
||||
[USER_TYPE.REGULAR_USER]: {
|
||||
type: "default" as const,
|
||||
label: "普通" as const,
|
||||
},
|
||||
[USER_TYPE.ADMIN]: { type: "info" as const, label: "管理员" as const },
|
||||
[USER_TYPE.STUDENT_ADMIN]: {
|
||||
type: "info" as const,
|
||||
label: "学生管理员" as const,
|
||||
},
|
||||
[USER_TYPE.TEACHER_ADMIN]: {
|
||||
type: "warning" as const,
|
||||
label: "教师管理员" as const,
|
||||
},
|
||||
[USER_TYPE.SUPER_ADMIN]: {
|
||||
type: "error" as const,
|
||||
label: "超管" as const,
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
import { useUserStore } from "shared/store/user"
|
||||
|
||||
/**
|
||||
* 权限检查工具函数
|
||||
*/
|
||||
export function usePermissions() {
|
||||
const userStore = useUserStore()
|
||||
|
||||
return {
|
||||
// 基本权限检查
|
||||
isAuthenticated: computed(() => userStore.isAuthed),
|
||||
isAdminRole: computed(() => userStore.isAdminRole),
|
||||
isTeacherOrAbove: computed(() => userStore.isTeacherOrAbove),
|
||||
isSuperAdmin: computed(() => userStore.isSuperAdmin),
|
||||
hasProblemPermission: computed(() => userStore.hasProblemPermission),
|
||||
|
||||
// 功能权限检查
|
||||
canManageUsers: computed(() => userStore.isSuperAdmin),
|
||||
canManageAnnouncements: computed(() => userStore.isSuperAdmin),
|
||||
canManageComments: computed(() => userStore.isSuperAdmin),
|
||||
@@ -22,9 +18,10 @@ export function usePermissions() {
|
||||
canSendMessages: computed(() => userStore.isSuperAdmin),
|
||||
|
||||
canManageProblems: computed(() => userStore.hasProblemPermission),
|
||||
canManageContests: computed(() => userStore.isSuperAdmin),
|
||||
canManageContests: computed(() => userStore.isTeacherOrAbove),
|
||||
canManageProblemsets: computed(() => userStore.isTeacherOrAbove),
|
||||
canViewClassroomData: computed(() => userStore.isTeacherOrAbove),
|
||||
|
||||
// 题目权限细分检查
|
||||
canManageAllProblems: computed(
|
||||
() =>
|
||||
userStore.user?.problem_permission === "All" || userStore.isSuperAdmin,
|
||||
@@ -34,17 +31,15 @@ export function usePermissions() {
|
||||
userStore.user?.problem_permission === "Own" && !userStore.isSuperAdmin,
|
||||
),
|
||||
|
||||
// 获取用户权限级别描述
|
||||
getUserPermissionLevel: computed(() => {
|
||||
if (userStore.isSuperAdmin) return "超级管理员"
|
||||
if (userStore.isAdminRole) return "管理员"
|
||||
if (userStore.isTeacherAdmin) return "教师管理员"
|
||||
if (userStore.isStudentAdmin) return "学生管理员"
|
||||
return "普通用户"
|
||||
}),
|
||||
|
||||
// 获取题目权限描述
|
||||
getProblemPermissionLevel: computed(() => {
|
||||
if (!userStore.user) return "无权限"
|
||||
|
||||
switch (userStore.user.problem_permission) {
|
||||
case "All":
|
||||
return "管理所有题目"
|
||||
@@ -59,13 +54,9 @@ export function usePermissions() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 路由权限检查
|
||||
*/
|
||||
export function checkRoutePermission(routeName: string): boolean {
|
||||
const userStore = useUserStore()
|
||||
|
||||
// 需要super admin权限的路由
|
||||
const superAdminRoutes = [
|
||||
"admin home",
|
||||
"admin config",
|
||||
@@ -79,35 +70,39 @@ export function checkRoutePermission(routeName: string): boolean {
|
||||
"admin tutorial list",
|
||||
"admin tutorial create",
|
||||
"admin tutorial edit",
|
||||
]
|
||||
|
||||
const teacherAdminRoutes = [
|
||||
"admin contest list",
|
||||
"admin contest create",
|
||||
"admin contest edit",
|
||||
"admin contest problem list",
|
||||
"admin contest problem create",
|
||||
"admin contest problem edit",
|
||||
"admin contest helper",
|
||||
"admin problemset list",
|
||||
"admin problemset create",
|
||||
"admin problemset edit",
|
||||
"admin problemset detail",
|
||||
]
|
||||
|
||||
// 需要题目权限的路由
|
||||
const problemPermissionRoutes = [
|
||||
"admin problem list",
|
||||
"admin problem create",
|
||||
"admin problem edit",
|
||||
]
|
||||
|
||||
// 需要基本admin权限的路由
|
||||
const adminRoutes: string[] = ["admin problem list"]
|
||||
|
||||
if (superAdminRoutes.includes(routeName)) {
|
||||
return userStore.isSuperAdmin
|
||||
}
|
||||
|
||||
if (teacherAdminRoutes.includes(routeName)) {
|
||||
return userStore.isTeacherOrAbove
|
||||
}
|
||||
|
||||
if (problemPermissionRoutes.includes(routeName)) {
|
||||
return userStore.hasProblemPermission
|
||||
}
|
||||
|
||||
if (adminRoutes.includes(routeName)) {
|
||||
return userStore.isAdminRole
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ export interface Profile {
|
||||
submission_number: number
|
||||
}
|
||||
|
||||
export type UserAdminType = "Regular User" | "Admin" | "Super Admin"
|
||||
export type UserAdminType = "Regular User" | "Student Admin" | "Teacher Admin" | "Super Admin"
|
||||
|
||||
export interface User {
|
||||
id: number
|
||||
|
||||
Reference in New Issue
Block a user