From 047e6dd7d369dde77a4a6fe1ce0e8be6dd89b59c Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Tue, 1 Sep 2026 06:57:24 -0600 Subject: [PATCH] =?UTF-8?q?feat(=E7=99=BB=E5=BD=95):=20=E5=AD=A6=E7=94=9F?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=94=B9=E6=88=90=E7=8F=AD=E7=BA=A7+?= =?UTF-8?q?=E5=A7=93=E5=90=8D=E4=B8=A4=E4=B8=AA=E4=B8=8B=E6=8B=89=EF=BC=8C?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E5=AD=97=E9=83=BD=E4=B8=8D=E7=94=A8=E6=89=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 登录框拆成「学生登录 / 管理员登录」两个页签。学生页签选完班级选姓名, ks 前缀提交时自动拼,选完姓名焦点直接跳到密码框,回车登录;上次选的班级 记在 localStorage 下次自动填好(姓名不记 —— 同一台机器换个人坐就是别人)。 管理员页签只有用户名+密码,不拼前缀。 「没有我所在的班级」保留在班级列表末尾,往届的班级从后台 class_list 里删掉后 学生仍能从这里写完整用户名登录。为了把「还没选」和「没有我所在的班级」分开, loginForm.class 的初值从空串改成 null —— 原来两者都是空串,一打开就默认落在 「没有我所在的班级」那一档、显示文本框,正好和「方便学生」相反。username 同样 改成 nullable:空串在 n-select 里是「选了一个空值」,占位符不显示。 clearProfile 的 storage.clear() 给 LOGIN_CLASS 开了个口子:机房一台机器对一个班, 下课登出、下节课再来还是同一个班,清掉的话每个人都得重新选一遍。 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01YQCLjAmz6pPXMNGoZmvAmC --- apps/web/src/shared/components/Login.vue | 359 ++++++++++++++++------- apps/web/src/shared/store/authModal.ts | 6 +- apps/web/src/shared/store/user.ts | 4 + apps/web/src/utils/constants.ts | 1 + 4 files changed, 258 insertions(+), 112 deletions(-) diff --git a/apps/web/src/shared/components/Login.vue b/apps/web/src/shared/components/Login.vue index edaae34..ac19ba9 100644 --- a/apps/web/src/shared/components/Login.vue +++ b/apps/web/src/shared/components/Login.vue @@ -1,4 +1,6 @@ @@ -115,85 +197,142 @@ onMounted(() => { v-model:show="loginModalOpen" preset="card" title="登录" - style="width: 400px" + style="width: 420px" :auto-focus="false" > - - - 关于【选择班级】的提醒:
- 1. 如果是上课统一生成的账号,选择【相应班级】,用户名直接写自己的名字 -
- 2. - 同样是上课用的号,但是没有你的班级。选择【没有我所在的班级】,用户名要写:ks班级+姓名,比如23计算机1班张三,就写ks231张三 -
- 3. 如果是自己注册的号,选择【没有我所在的班级】
-
- - - - - - - - - - - {{ msg }} - - - + + + + + + - 登录 - - - 没有账号?立即注册 - - - -
+ + + + + + + {{ + msg + }} + + + + 登录 + + + 没有账号?立即注册 + + + + + 往届的班级、列表里找不到的班级、以及自己注册的账号,选【没有我所在的班级】,用户名要写完整,比如 + 23 计算机 1 班张三写 ks231张三。 + + + + + + + + + + + + + {{ + msg + }} + + + 登录 + + + + 管理员和老师从这里登录,学生请走【学生登录】页签。 + + + + diff --git a/apps/web/src/shared/store/authModal.ts b/apps/web/src/shared/store/authModal.ts index 5a8f42b..6016e2d 100644 --- a/apps/web/src/shared/store/authModal.ts +++ b/apps/web/src/shared/store/authModal.ts @@ -10,9 +10,11 @@ export const useAuthModalStore = defineStore("authModal", () => { const signupModalOpen = ref(false) // ==================== 登录表单状态 ==================== + // class 为 null 表示还没选,别用空串 —— 空串是「没有我所在的班级」那一项的值。 + // username 同理用 null:空串在 n-select 里是「选了一个空值」,占位符不显示。 const loginForm = reactive({ - class: "", - username: "", + class: null as string | null, + username: null as string | null, password: "", }) diff --git a/apps/web/src/shared/store/user.ts b/apps/web/src/shared/store/user.ts index 1c77ec2..8272f09 100644 --- a/apps/web/src/shared/store/user.ts +++ b/apps/web/src/shared/store/user.ts @@ -82,7 +82,11 @@ export const useUserStore = defineStore("user", () => { function clearProfile() { profile.value = null demoMode.value = false + // 登录框记的班级要跨退登活下来:机房一台机器对一个班,下课登出、下节课再来 + // 还是同一个班,清掉的话每个人都得重新选一遍。它是机器的属性,不是谁的隐私。 + const loginClass = storage.get(STORAGE_KEY.LOGIN_CLASS) storage.clear() + if (loginClass !== null) storage.set(STORAGE_KEY.LOGIN_CLASS, loginClass) } // 退登的两步(吊销服务端会话、清本地状态)绑在一起:只清本地会留一个还活着 diff --git a/apps/web/src/utils/constants.ts b/apps/web/src/utils/constants.ts index 3485ea4..0c73245 100644 --- a/apps/web/src/utils/constants.ts +++ b/apps/web/src/utils/constants.ts @@ -152,6 +152,7 @@ export const STORAGE_KEY = { ADMIN_PROBLEM: "adminProblem", ADMIN_PROBLEM_TAGS: "adminProblemTags", DEMO_MODE: "demoMode", + LOGIN_CLASS: "loginClass", } export const DIFFICULTY = {