Files
xh-medical-sign-web/clinical-web/src/components/layout/Menu.vue

253 lines
5.0 KiB
Vue

<script setup lang="ts">
import { RouterLink, useRouter } from 'vue-router'
import { useAppStore } from '@/stores/app'
interface MenuItem {
path: string
label: string
}
interface MenuGroup {
label: string
items: MenuItem[]
}
const appStore = useAppStore()
const router = useRouter()
const menuGroups: MenuGroup[] = [
{
label: '工作台',
items: [
{ path: '/workbench/home', label: '首页' },
{ path: '/workbench/signing', label: '签署工作台' },
],
},
{
label: '管理',
items: [
{ path: '/management/documents', label: '文档库管理' },
{ path: '/management/reports', label: '报表分析' },
{ path: '/management/users', label: '用户与权限' },
{ path: '/management/document-permissions', label: '文档权限' },
{ path: '/management/settings', label: '系统设置' },
],
},
]
function handleLogout() {
appStore.logout()
void router.push('/login')
}
</script>
<template>
<aside class="clinical-menu">
<div class="menu-brand">
<div class="menu-brand-icon" aria-hidden="true">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none">
<path
d="M14 3v5h5M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8l-5-5z"
stroke="#fff"
stroke-width="1.7"
stroke-linejoin="round"
/>
<path
d="m9 13.5 2.5 2.5 4-4.5"
stroke="#fff"
stroke-width="1.7"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</div>
<div class="menu-brand-copy">
<strong>医签通</strong>
<span>MEDISIGN</span>
</div>
</div>
<nav class="menu-nav" aria-label="主导航">
<div v-for="group in menuGroups" :key="group.label" class="menu-group">
<div class="menu-group-title">{{ group.label }}</div>
<RouterLink
v-for="item in group.items"
:key="item.path"
:to="item.path"
class="menu-item"
active-class="is-active"
>
<span class="menu-dot" aria-hidden="true" />
<span>{{ item.label }}</span>
</RouterLink>
</div>
</nav>
<div class="menu-profile">
<div class="menu-profile-avatar">{{ appStore.userName.slice(0, 1) }}</div>
<div class="menu-profile-copy">
<strong>{{ appStore.userName }}</strong>
<span>{{ appStore.department }}</span>
</div>
<button class="menu-logout" type="button" @click="handleLogout">退出</button>
</div>
</aside>
</template>
<style scoped>
.clinical-menu {
display: flex;
flex: 0 0 var(--sidebar-width);
flex-direction: column;
width: var(--sidebar-width);
color: #c8dde6;
background: var(--side);
}
.menu-brand {
display: flex;
flex-shrink: 0;
gap: 10px;
align-items: center;
padding: 18px 16px 16px;
border-bottom: 1px solid rgb(255 255 255 / 8%);
}
.menu-brand-icon {
display: grid;
flex-shrink: 0;
width: 34px;
height: 34px;
place-items: center;
border-radius: 9px;
background: linear-gradient(135deg, #18a0c0, var(--brand));
}
.menu-brand-copy strong,
.menu-brand-copy span {
display: block;
}
.menu-brand-copy strong {
color: #fff;
font-size: 16px;
letter-spacing: 1px;
}
.menu-brand-copy span {
color: #8fb3c2;
font-size: 10px;
letter-spacing: 1px;
}
.menu-nav {
flex: 1;
padding: 12px 10px;
overflow-y: auto;
}
.menu-group-title {
padding: 10px 10px 6px;
color: #7ba2b3;
font-size: 11px;
letter-spacing: 1px;
}
.menu-item {
display: flex;
gap: 10px;
align-items: center;
margin-bottom: 2px;
padding: 10px 12px;
color: #c8dde6;
font-size: 13.5px;
text-decoration: none;
border-radius: 8px;
transition:
color 0.15s ease,
background 0.15s ease;
}
.menu-item:hover {
color: #fff;
background: rgb(255 255 255 / 7%);
}
.menu-item.is-active {
color: #fff;
font-weight: 700;
background: var(--brand);
}
.menu-dot {
flex-shrink: 0;
width: 6px;
height: 6px;
background: transparent;
border-radius: 50%;
}
.menu-item.is-active .menu-dot {
background: #5ee0a8;
}
.menu-profile {
display: flex;
flex-shrink: 0;
gap: 10px;
align-items: center;
padding: 14px 16px;
border-top: 1px solid rgb(255 255 255 / 8%);
}
.menu-profile-avatar {
display: grid;
flex-shrink: 0;
width: 34px;
height: 34px;
color: #fff;
font-size: 14px;
font-weight: 700;
place-items: center;
border-radius: 50%;
background: #18a0c0;
}
.menu-profile-copy {
min-width: 0;
}
.menu-profile-copy strong,
.menu-profile-copy span {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.menu-profile-copy strong {
color: #fff;
font-size: 13px;
}
.menu-profile-copy span {
margin-top: 2px;
color: #8fb3c2;
font-size: 11px;
}
.menu-logout {
flex-shrink: 0;
margin-left: auto;
padding: 0;
color: #8fb3c2;
font-size: 11px;
background: transparent;
}
.menu-logout:hover {
color: #fff;
}
</style>