feat(user): store 层加入演示模式伪装开关

超管开启后所有角色 getter 降级为普通学生,全站权限判断自动跟随。
realIsSuperAdmin 保留真实身份,用于判断能否切换。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-26 07:47:27 -06:00
parent 5fac75238d
commit 07bbbce013
2 changed files with 35 additions and 11 deletions

View File

@@ -11,30 +11,49 @@ export const useUserStore = defineStore("user", () => {
const [isFinished] = useToggle(false) const [isFinished] = useToggle(false)
const user = computed<User | null>(() => profile.value?.user ?? null) const user = computed<User | null>(() => profile.value?.user ?? null)
const isAuthed = computed(() => !!user.value?.email) 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( const isAdminRole = computed(
() => () =>
user.value?.admin_type === USER_TYPE.STUDENT_ADMIN || !demoMode.value &&
(user.value?.admin_type === USER_TYPE.STUDENT_ADMIN ||
user.value?.admin_type === USER_TYPE.TEACHER_ADMIN || user.value?.admin_type === USER_TYPE.TEACHER_ADMIN ||
user.value?.admin_type === USER_TYPE.SUPER_ADMIN, user.value?.admin_type === USER_TYPE.SUPER_ADMIN),
) )
const isStudentAdmin = computed( const isStudentAdmin = computed(
() => user.value?.admin_type === USER_TYPE.STUDENT_ADMIN, () => !demoMode.value && user.value?.admin_type === USER_TYPE.STUDENT_ADMIN,
) )
const isTeacherAdmin = computed( const isTeacherAdmin = computed(
() => user.value?.admin_type === USER_TYPE.TEACHER_ADMIN, () => !demoMode.value && user.value?.admin_type === USER_TYPE.TEACHER_ADMIN,
) )
const isTeacherOrAbove = computed( const isTeacherOrAbove = computed(
() => () =>
user.value?.admin_type === USER_TYPE.TEACHER_ADMIN || !demoMode.value &&
user.value?.admin_type === USER_TYPE.SUPER_ADMIN, (user.value?.admin_type === USER_TYPE.TEACHER_ADMIN ||
) user.value?.admin_type === USER_TYPE.SUPER_ADMIN),
const isSuperAdmin = computed(
() => user.value?.admin_type === USER_TYPE.SUPER_ADMIN,
) )
const isSuperAdmin = computed(() => !demoMode.value && realIsSuperAdmin.value)
const hasProblemPermission = computed( const hasProblemPermission = computed(
() => user.value?.problem_permission !== PROBLEM_PERMISSION.NONE, () =>
!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(() => { const showSubmissions = computed(() => {
let flag = configStore.config.submission_list_show_all let flag = configStore.config.submission_list_show_all
if (isAdminRole.value) flag = true if (isAdminRole.value) flag = true
@@ -51,6 +70,7 @@ export const useUserStore = defineStore("user", () => {
function clearProfile() { function clearProfile() {
profile.value = null profile.value = null
demoMode.value = false
storage.clear() storage.clear()
} }
return { return {
@@ -63,6 +83,9 @@ export const useUserStore = defineStore("user", () => {
isTeacherOrAbove, isTeacherOrAbove,
isSuperAdmin, isSuperAdmin,
hasProblemPermission, hasProblemPermission,
demoMode,
canToggleDemoMode,
toggleDemoMode,
isAuthed, isAuthed,
showSubmissions, showSubmissions,
getMyProfile, getMyProfile,

View File

@@ -150,6 +150,7 @@ export const STORAGE_KEY = {
LEARN_CURRENT_STEP: "learnStep", LEARN_CURRENT_STEP: "learnStep",
ADMIN_PROBLEM: "adminProblem", ADMIN_PROBLEM: "adminProblem",
ADMIN_PROBLEM_TAGS: "adminProblemTags", ADMIN_PROBLEM_TAGS: "adminProblemTags",
DEMO_MODE: "demoMode",
} }
export const DIFFICULTY = { export const DIFFICULTY = {