Files
ojnext/src/shared/store/user.ts
yuetsh 07bbbce013 feat(user): store 层加入演示模式伪装开关
超管开启后所有角色 getter 降级为普通学生,全站权限判断自动跟随。
realIsSuperAdmin 保留真实身份,用于判断能否切换。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 07:47:27 -06:00

95 lines
2.8 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 { PROBLEM_PERMISSION, STORAGE_KEY, USER_TYPE } from "utils/constants"
import storage from "utils/storage"
import type { Profile, User } from "utils/types"
import { getProfile } from "../api"
import { useConfigStore } from "./config"
export const useUserStore = defineStore("user", () => {
const configStore = useConfigStore()
const profile = ref<Profile | null>(null)
const [isFinished] = useToggle(false)
const user = computed<User | null>(() => profile.value?.user ?? null)
const isAuthed = computed(() => !!user.value?.email)
// 演示模式:超管临时把界面伪装成普通学生,方便上课投屏
const demoMode = ref<boolean>(storage.get(STORAGE_KEY.DEMO_MODE) ?? false)
// 不受伪装影响的真实身份,只用于判断能否切换演示模式。
// 若这里用被伪装后的 isSuperAdmin一进入演示模式入口就消失了退不出来。
const realIsSuperAdmin = computed(
() => user.value?.admin_type === USER_TYPE.SUPER_ADMIN,
)
const isAdminRole = computed(
() =>
!demoMode.value &&
(user.value?.admin_type === USER_TYPE.STUDENT_ADMIN ||
user.value?.admin_type === USER_TYPE.TEACHER_ADMIN ||
user.value?.admin_type === USER_TYPE.SUPER_ADMIN),
)
const isStudentAdmin = computed(
() => !demoMode.value && user.value?.admin_type === USER_TYPE.STUDENT_ADMIN,
)
const isTeacherAdmin = computed(
() => !demoMode.value && user.value?.admin_type === USER_TYPE.TEACHER_ADMIN,
)
const isTeacherOrAbove = computed(
() =>
!demoMode.value &&
(user.value?.admin_type === USER_TYPE.TEACHER_ADMIN ||
user.value?.admin_type === USER_TYPE.SUPER_ADMIN),
)
const isSuperAdmin = computed(() => !demoMode.value && realIsSuperAdmin.value)
const hasProblemPermission = computed(
() =>
!demoMode.value &&
user.value?.problem_permission !== PROBLEM_PERMISSION.NONE,
)
const canToggleDemoMode = computed(() => realIsSuperAdmin.value)
function toggleDemoMode() {
demoMode.value = !demoMode.value
storage.set(STORAGE_KEY.DEMO_MODE, demoMode.value)
}
const showSubmissions = computed(() => {
let flag = configStore.config.submission_list_show_all
if (isAdminRole.value) flag = true
return flag
})
async function getMyProfile() {
isFinished.value = false
const res = await getProfile()
profile.value = res.data
isFinished.value = true
storage.set(STORAGE_KEY.AUTHED, !!user.value?.email)
}
function clearProfile() {
profile.value = null
demoMode.value = false
storage.clear()
}
return {
profile,
isFinished,
user,
isAdminRole,
isStudentAdmin,
isTeacherAdmin,
isTeacherOrAbove,
isSuperAdmin,
hasProblemPermission,
demoMode,
canToggleDemoMode,
toggleDemoMode,
isAuthed,
showSubmissions,
getMyProfile,
clearProfile,
}
})