Files
digital-psychology/apps/admin-h5/src/layouts/AdminShell.vue
T
jackyu66gitandCursor 140b08ca01 feat(ECR-021): AICoreConfig SystemPrompt 只读并 Closed
新增 system_prompts 目录、admin.ai_config.read 与 admin-h5「AI」页;本切片不改运行时 Prompt、禁写发布/UGC/真支付。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-08 00:27:17 +08:00

88 lines
2.5 KiB
Vue

<script setup lang="ts">
import { onMounted } from 'vue'
import { RouterLink, RouterView, useRouter } from 'vue-router'
import BrandLogo from '@/components/BrandLogo.vue'
import { useAuthStore } from '@/stores/auth'
const auth = useAuthStore()
const router = useRouter()
onMounted(() => {
void auth.hydrate()
})
async function onLogout() {
await auth.logout()
await router.push({ name: 'login' })
}
</script>
<template>
<div class="shell">
<aside class="nav">
<RouterLink class="brand" to="/">
<BrandLogo size="nav" />
</RouterLink>
<nav>
<RouterLink to="/">概览</RouterLink>
<RouterLink to="/analytics">数据</RouterLink>
<RouterLink to="/content">内容</RouterLink>
<RouterLink to="/users">用户</RouterLink>
<RouterLink to="/plans">套餐</RouterLink>
<RouterLink to="/codes">兑换码</RouterLink>
<RouterLink to="/ask">问答</RouterLink>
<RouterLink to="/safety">安全</RouterLink>
<RouterLink to="/ai">AI</RouterLink>
<RouterLink to="/orders">订单</RouterLink>
<RouterLink to="/audit">审计</RouterLink>
</nav>
<div class="foot">
<span class="muted">{{ auth.username || '管理员' }}</span>
<span v-if="auth.role" class="role">{{ auth.role }} · {{ auth.permissions.length }} </span>
<button class="btn ghost" type="button" @click="onLogout">退出</button>
</div>
</aside>
<main class="main">
<RouterView />
</main>
</div>
</template>
<style scoped>
.shell { display: grid; grid-template-columns: 220px 1fr; min-height: 100vh; }
.nav {
padding: 1.15rem 1rem;
border-right: 1px solid rgba(240, 230, 226, 0.9);
background: rgba(255, 253, 251, 0.88);
backdrop-filter: blur(12px);
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.brand {
display: flex;
align-items: center;
padding: 0.15rem 0.25rem;
}
nav { display: flex; flex-direction: column; gap: 0.35rem; }
nav a {
padding: 0.5rem 0.7rem;
border-radius: 12px;
color: var(--muted);
font-weight: 550;
}
nav a.router-link-active {
background: linear-gradient(135deg, #fff0ec, #ffe4e0);
color: var(--accent);
font-weight: 700;
box-shadow: 0 4px 12px rgba(229, 77, 66, 0.08);
}
.foot { margin-top: auto; display: flex; flex-direction: column; gap: 0.5rem; }
.role { font-size: 0.75rem; color: var(--muted); }
.main { padding: 1.5rem 1.75rem; }
@media (max-width: 800px) {
.shell { grid-template-columns: 1fr; }
.nav { border-right: 0; border-bottom: 1px solid var(--line); }
}
</style>