From 85145d67c49ac098ef05cbf3ea71fd43ea53f237 Mon Sep 17 00:00:00 2001 From: xuans Date: Sun, 30 Aug 2026 20:43:14 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=99=AE=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E6=97=A0=E6=9D=83=E9=99=90=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/App.js | 7 +++ frontend/src/App.vue | 6 ++ .../src/views/AccessDenied/AccessDenied.css | 60 +++++++++++++++++++ .../src/views/AccessDenied/AccessDenied.js | 29 +++++++++ .../src/views/AccessDenied/AccessDenied.vue | 26 ++++++++ 5 files changed, 128 insertions(+) create mode 100644 frontend/src/views/AccessDenied/AccessDenied.css create mode 100644 frontend/src/views/AccessDenied/AccessDenied.js create mode 100644 frontend/src/views/AccessDenied/AccessDenied.vue diff --git a/frontend/src/App.js b/frontend/src/App.js index a7ffbe6..83259c0 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -3,6 +3,7 @@ import { onMounted, ref } from "vue"; export function useAppShell() { const setupState = ref(null); const authenticated = ref(null); + const isAdmin = ref(null); const bootstrapping = ref(true); const error = ref(""); const routePath = window.location.pathname.replace(/\/+$/, "") || "/"; @@ -20,10 +21,12 @@ export function useAppShell() { await checkAuth(); } else { authenticated.value = false; + isAdmin.value = false; } } catch (err) { setupState.value = null; authenticated.value = null; + isAdmin.value = null; error.value = err.message || "无法连接核心服务,请先启动 scert serve"; } finally { bootstrapping.value = false; @@ -36,16 +39,19 @@ export function useAppShell() { }); if (response.status === 401) { authenticated.value = false; + isAdmin.value = false; return; } const result = await response.json().catch(() => ({})); if (!response.ok) throw new Error(result.error || "读取登录状态失败"); authenticated.value = result.authenticated === true; + isAdmin.value = result.is_admin === true || ["super_admin", "admin"].includes(result.role); } function handleInitialized() { setupState.value = { ...setupState.value, initialized: true }; authenticated.value = false; + isAdmin.value = false; } onMounted(() => { @@ -59,6 +65,7 @@ export function useAppShell() { return { setupState, authenticated, + isAdmin, bootstrapping, error, routePath, diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 07926c3..ac50f0c 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1,5 +1,6 @@ + +