style: 优化个人中心和偏好设置弹窗样式,重构工作入口为精致分屏布局并移除首字徽标

This commit is contained in:
Cheng Zhou
2026-07-08 20:20:41 +08:00
parent e7b18758b2
commit b73f23c1eb
33 changed files with 2323 additions and 379 deletions
+51 -7
View File
@@ -11,6 +11,8 @@ import Login from "../views/Login.vue";
import Register from "../views/Register.vue";
import ForgotPassword from "../views/ForgotPassword.vue";
import DesktopServerSettings from "../views/DesktopServerSettings.vue";
import DesktopProjectEntry from "../views/DesktopProjectEntry.vue";
import DesktopSessionRestore from "../views/DesktopSessionRestore.vue";
import StudyHome from "../views/StudyHome.vue";
import FaqDetail from "../views/FaqDetail.vue";
import AuditLogs from "../views/admin/AuditLogs.vue";
@@ -57,6 +59,8 @@ import SubjectForm from "../views/subjects/SubjectForm.vue";
import SubjectDetail from "../views/subjects/SubjectDetail.vue";
import { TEXT } from "../locales";
import { resolveDesktopRouteRedirect } from "./desktopGuard";
import { isTauriRuntime } from "../runtime";
import { DESKTOP_SESSION_RESTORE_PATH, shouldPreserveDesktopSessionOnAuthCheckFailure } from "../session/authRecovery";
const SYSTEM_PERMISSION_READ = "system:permissions:read";
const SYSTEM_PERMISSION_PROJECT_CONFIG = "system:permissions:project_config";
@@ -86,6 +90,18 @@ const routes: RouteRecordRaw[] = [
component: DesktopServerSettings,
meta: { public: true, title: "服务器设置" },
},
{
path: DESKTOP_SESSION_RESTORE_PATH,
name: "DesktopSessionRestore",
component: DesktopSessionRestore,
meta: { public: true, title: "恢复登录状态" },
},
{
path: "/desktop/project-entry",
name: "DesktopProjectEntry",
component: DesktopProjectEntry,
meta: { title: "选择工作入口" },
},
{
path: "/",
component: Layout,
@@ -512,6 +528,7 @@ const ensureProjectPermissionAccess = async (
};
router.beforeEach(async (to, _from, next) => {
const isDesktopRuntime = isTauriRuntime();
const desktopRedirect = resolveDesktopRouteRedirect(to);
if (desktopRedirect) {
next({ path: desktopRedirect });
@@ -522,10 +539,15 @@ router.beforeEach(async (to, _from, next) => {
const studyStore = useStudyStore();
const getToken = () => auth.token;
let token = getToken();
if (!auth.user && getToken()) {
const isDesktopSessionRestoreRoute = to.path === DESKTOP_SESSION_RESTORE_PATH;
if (!auth.user && getToken() && !isDesktopSessionRestoreRoute) {
try {
await auth.fetchMe();
} catch {
await auth.fetchMe({ disableNetworkRetry: true, suppressErrorMessage: true });
} catch (error) {
if (isDesktopRuntime && shouldPreserveDesktopSessionOnAuthCheckFailure(error)) {
next({ path: DESKTOP_SESSION_RESTORE_PATH, query: { redirect: to.fullPath } });
return;
}
// 有 token 但无法获取用户,强制回登录,避免进入“无用户上下文”页面
await auth.logout();
next({ path: "/login" });
@@ -534,7 +556,11 @@ router.beforeEach(async (to, _from, next) => {
}
token = getToken();
const isAdmin = isSystemAdmin(auth.user);
if (token && !studyStore.currentStudy) {
if (!to.meta.public && !token) {
next({ path: "/login" });
return;
}
if (token && !studyStore.currentStudy && !isDesktopRuntime) {
if (isAdmin) {
await studyStore.ensureDefaultActiveStudy();
} else {
@@ -544,8 +570,22 @@ router.beforeEach(async (to, _from, next) => {
if (token && studyStore.currentStudy && auth.user?.email) {
studyStore.rememberCurrentStudyForUser(auth.user.email);
}
if (!to.meta.public && !token) {
next({ path: "/login" });
if (isDesktopRuntime && token && to.path === "/desktop/project-entry" && studyStore.currentStudy) {
studyStore.clearCurrentStudy();
}
if (isDesktopRuntime && token && !isAdmin && to.path.startsWith("/admin")) {
next({ path: "/desktop/project-entry" });
return;
}
if (isDesktopRuntime && token && isAdmin && to.path.startsWith("/admin") && studyStore.currentStudy) {
studyStore.clearCurrentStudy();
}
if (isDesktopRuntime && token && to.path === "/") {
next({ path: studyStore.currentStudy ? "/project/overview" : "/desktop/project-entry" });
return;
}
if (isAdmin && to.path === "/") {
@@ -554,6 +594,10 @@ router.beforeEach(async (to, _from, next) => {
}
if ((to.path === "/login" || to.path === "/register") && token) {
if (!auth.forceLogin) {
if (isDesktopRuntime) {
next({ path: "/desktop/project-entry" });
return;
}
next({
path: isAdmin
? studyStore.currentStudy
@@ -621,7 +665,7 @@ router.beforeEach(async (to, _from, next) => {
}
}
if (to.meta.requiresStudy && !studyStore.currentStudy) {
next({ path: isAdmin ? "/admin/users" : "/admin/projects" });
next({ path: isDesktopRuntime ? "/desktop/project-entry" : isAdmin ? "/admin/users" : "/admin/projects" });
return;
}
if (to.meta.requiresStudy && studyStore.currentStudy) {