fix: 路由权限控制 - 访客只能访问机器列表,admin页面需登录
This commit is contained in:
@@ -39,8 +39,8 @@
|
||||
<div class="user-info" v-if="isLoggedIn">
|
||||
<el-icon class="user-icon"><UserFilled /></el-icon>
|
||||
<div class="user-meta">
|
||||
<span class="user-name">{{ isAdmin ? '管理员' : '访客' }}</span>
|
||||
<span class="user-role">{{ isAdmin ? 'Admin' : 'Guest' }}</span>
|
||||
<span class="user-name">管理员</span>
|
||||
<span class="user-role">Admin</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-actions" v-if="isLoggedIn">
|
||||
@@ -56,18 +56,8 @@
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 访客:顶部极简标题栏 -->
|
||||
<header class="guest-header" v-if="!isAdmin">
|
||||
<div class="guest-brand">
|
||||
<img src="/logo.svg" alt="LAN Manager" style="width:22px;height:22px;" />
|
||||
<span>LAN Manager</span>
|
||||
</div>
|
||||
<div class="guest-theme-toggle" @click="toggleTheme">
|
||||
<el-icon><component :is="isDark ? Sunny : Moon" /></el-icon>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="main" :class="{ 'guest-main': !isAdmin }">
|
||||
<!-- 未登录用户:无侧边栏,只显示内容 -->
|
||||
<main class="main" :class="{ 'no-sidebar': !isAdmin }">
|
||||
<div class="main-inner">
|
||||
<router-view />
|
||||
</div>
|
||||
@@ -386,54 +376,14 @@ html.dark .brand-logo {
|
||||
background: var(--page-bg);
|
||||
transition: background .25s ease;
|
||||
}
|
||||
.main.no-sidebar {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.main-inner {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.guest-main {
|
||||
margin-left: 0;
|
||||
padding-top: 48px;
|
||||
}
|
||||
|
||||
.guest-header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 48px;
|
||||
background: var(--sidebar-bg);
|
||||
border-bottom: 1px solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 16px;
|
||||
z-index: 100;
|
||||
}
|
||||
.guest-brand {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.guest-theme-toggle {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
color: var(--text);
|
||||
transition: all .2s ease;
|
||||
}
|
||||
.guest-theme-toggle:hover {
|
||||
background: var(--hover-bg);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.sidebar { width: 64px; }
|
||||
.brand-text, .nav-item span, .user-meta, .footer-btn span, .theme-toggle span { display: none; }
|
||||
@@ -442,6 +392,6 @@ html.dark .brand-logo {
|
||||
.user-info { justify-content: center; padding: 10px; }
|
||||
.theme-toggle { justify-content: center; padding: 10px; }
|
||||
.main { margin-left: 64px; }
|
||||
.guest-main { margin-left: 0; }
|
||||
.main.no-sidebar { margin-left: 0; }
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -6,7 +6,7 @@ const routes = [
|
||||
path: '/login',
|
||||
name: 'Login',
|
||||
component: () => import('@/views/Login.vue'),
|
||||
meta: { public: true, guestOnly: true },
|
||||
meta: { guestOnly: true },
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
@@ -59,30 +59,25 @@ router.beforeEach(async (to, from, next) => {
|
||||
if (!authChecked) {
|
||||
try {
|
||||
const { data } = await checkAuth()
|
||||
authState = { ...data, is_logged_in: true }
|
||||
authState = { is_admin: data.is_admin, is_logged_in: true }
|
||||
} catch (e) {
|
||||
authState = { is_admin: false, is_logged_in: false }
|
||||
}
|
||||
authChecked = true
|
||||
}
|
||||
|
||||
// 未登录,且不是公开页面也不是登录页 → 强制去登录
|
||||
if (!authState.is_logged_in && !to.meta.public && !to.meta.guestOnly) {
|
||||
return next('/login?redirect=' + encodeURIComponent(to.fullPath))
|
||||
// 未登录用户访问 admin 专属页面 → 去机器列表
|
||||
if (!authState.is_logged_in && to.meta.admin) {
|
||||
return next('/machines')
|
||||
}
|
||||
|
||||
// 已登录访客,访问需要 admin 的页面 → 去机器列表
|
||||
// 已登录但非管理员(防御性)访问 admin 页面 → 去机器列表
|
||||
if (authState.is_logged_in && !authState.is_admin && to.meta.admin) {
|
||||
return next('/machines')
|
||||
}
|
||||
|
||||
// 已登录访客,访问登录页 → 去机器列表
|
||||
if (authState.is_logged_in && !authState.is_admin && to.meta.guestOnly) {
|
||||
return next('/machines')
|
||||
}
|
||||
|
||||
// 管理员访问登录页 → 去仪表盘
|
||||
if (authState.is_admin && to.meta.guestOnly) {
|
||||
// 管理员已登录,访问登录页 → 去仪表盘
|
||||
if (authState.is_logged_in && authState.is_admin && to.meta.guestOnly) {
|
||||
return next('/dashboard')
|
||||
}
|
||||
|
||||
@@ -95,7 +90,7 @@ export function refreshAuth() {
|
||||
}
|
||||
|
||||
export function setAuth(data) {
|
||||
authState = { ...data, is_logged_in: true }
|
||||
authState = { is_admin: data.is_admin, is_logged_in: true }
|
||||
}
|
||||
|
||||
export function getAuth() {
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 访客卡片:仅主机名 + 状态 + OS,不可点击 -->
|
||||
<!-- 未登录用户卡片:仅主机名 + 状态 + OS,不可点击 -->
|
||||
<div v-if="!isAdmin" v-for="m in machines" :key="m.id" class="server-card guest-card"
|
||||
:class="[{ 'offline-card': !m.is_online }]">
|
||||
<div class="card-header">
|
||||
|
||||
Reference in New Issue
Block a user