From 07bbbce0134e8433b393be79d58993b1dfb3f715 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Sun, 26 Jul 2026 07:47:27 -0600 Subject: [PATCH] =?UTF-8?q?feat(user):=20store=20=E5=B1=82=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=E6=BC=94=E7=A4=BA=E6=A8=A1=E5=BC=8F=E4=BC=AA=E8=A3=85?= =?UTF-8?q?=E5=BC=80=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 超管开启后所有角色 getter 降级为普通学生,全站权限判断自动跟随。 realIsSuperAdmin 保留真实身份,用于判断能否切换。 Co-Authored-By: Claude Opus 5 --- src/shared/store/user.ts | 45 ++++++++++++++++++++++++++++++---------- src/utils/constants.ts | 1 + 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/shared/store/user.ts b/src/shared/store/user.ts index 574d0fe..f19c39d 100644 --- a/src/shared/store/user.ts +++ b/src/shared/store/user.ts @@ -11,30 +11,49 @@ export const useUserStore = defineStore("user", () => { const [isFinished] = useToggle(false) const user = computed(() => profile.value?.user ?? null) const isAuthed = computed(() => !!user.value?.email) + + // 演示模式:超管临时把界面伪装成普通学生,方便上课投屏 + const demoMode = ref(storage.get(STORAGE_KEY.DEMO_MODE) ?? false) + + // 不受伪装影响的真实身份,只用于判断能否切换演示模式。 + // 若这里用被伪装后的 isSuperAdmin,一进入演示模式入口就消失了,退不出来。 + const realIsSuperAdmin = computed( + () => user.value?.admin_type === USER_TYPE.SUPER_ADMIN, + ) + const isAdminRole = computed( () => - user.value?.admin_type === USER_TYPE.STUDENT_ADMIN || - user.value?.admin_type === USER_TYPE.TEACHER_ADMIN || - user.value?.admin_type === USER_TYPE.SUPER_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.SUPER_ADMIN), ) const isStudentAdmin = computed( - () => user.value?.admin_type === USER_TYPE.STUDENT_ADMIN, + () => !demoMode.value && user.value?.admin_type === USER_TYPE.STUDENT_ADMIN, ) const isTeacherAdmin = computed( - () => user.value?.admin_type === USER_TYPE.TEACHER_ADMIN, + () => !demoMode.value && user.value?.admin_type === USER_TYPE.TEACHER_ADMIN, ) const isTeacherOrAbove = computed( () => - 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, + !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( - () => 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(() => { let flag = configStore.config.submission_list_show_all if (isAdminRole.value) flag = true @@ -51,6 +70,7 @@ export const useUserStore = defineStore("user", () => { function clearProfile() { profile.value = null + demoMode.value = false storage.clear() } return { @@ -63,6 +83,9 @@ export const useUserStore = defineStore("user", () => { isTeacherOrAbove, isSuperAdmin, hasProblemPermission, + demoMode, + canToggleDemoMode, + toggleDemoMode, isAuthed, showSubmissions, getMyProfile, diff --git a/src/utils/constants.ts b/src/utils/constants.ts index cfee973..bccd7c4 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -150,6 +150,7 @@ export const STORAGE_KEY = { LEARN_CURRENT_STEP: "learnStep", ADMIN_PROBLEM: "adminProblem", ADMIN_PROBLEM_TAGS: "adminProblemTags", + DEMO_MODE: "demoMode", } export const DIFFICULTY = {