253 lines
5.0 KiB
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>
|