117 lines
2.7 KiB
Vue
117 lines
2.7 KiB
Vue
<script setup lang="ts">
|
|
import {
|
|
Banknote,
|
|
BadgeDollarSign,
|
|
Building2,
|
|
ClipboardList,
|
|
FileChartColumn,
|
|
LayoutDashboard,
|
|
LogOut,
|
|
Network,
|
|
PanelLeftClose,
|
|
PanelLeftOpen,
|
|
ScrollText,
|
|
Settings2,
|
|
HandCoins,
|
|
UserCog,
|
|
UsersRound,
|
|
} from "@lucide/vue";
|
|
import { computed } from "vue";
|
|
import { useRouter } from "vue-router";
|
|
|
|
import { useAuthStore } from "../stores/auth";
|
|
|
|
defineProps<{
|
|
collapsed: boolean;
|
|
open: boolean;
|
|
}>();
|
|
|
|
const emit = defineEmits<{
|
|
close: [];
|
|
"toggle-collapse": [];
|
|
}>();
|
|
|
|
const auth = useAuthStore();
|
|
const router = useRouter();
|
|
|
|
const backendIconMap = {
|
|
payroll: Banknote,
|
|
jobs: ClipboardList,
|
|
employees: UserCog,
|
|
organization: Network,
|
|
salary_profiles: BadgeDollarSign,
|
|
commissions: HandCoins,
|
|
reports: FileChartColumn,
|
|
configs: Settings2,
|
|
users: UsersRound,
|
|
operation_logs: ScrollText,
|
|
};
|
|
|
|
const menuItems = computed(() => [
|
|
{
|
|
code: "dashboard",
|
|
name: "工作台",
|
|
path: "/dashboard",
|
|
icon: LayoutDashboard,
|
|
},
|
|
...auth.menus.map((menu) => ({
|
|
...menu,
|
|
icon: backendIconMap[menu.code as keyof typeof backendIconMap] || ClipboardList,
|
|
})),
|
|
]);
|
|
|
|
function logout(): void {
|
|
auth.logout();
|
|
emit("close");
|
|
router.push("/login");
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<aside class="sidebar" :class="{ 'is-open': open }">
|
|
<div class="brand">
|
|
<div class="brand-main">
|
|
<div class="brand-mark">
|
|
<Building2 :size="22" aria-hidden="true" />
|
|
</div>
|
|
<div class="brand-copy">
|
|
<p class="brand-title">企业薪酬管理</p>
|
|
<p class="brand-subtitle">管理门户</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<nav class="sidebar-nav" aria-label="主导航">
|
|
<RouterLink
|
|
v-for="item in menuItems"
|
|
:key="item.code"
|
|
:to="item.path"
|
|
class="nav-link"
|
|
active-class="is-active"
|
|
:title="item.name"
|
|
@click="emit('close')"
|
|
>
|
|
<component :is="item.icon" :size="21" aria-hidden="true" />
|
|
<span>{{ item.name }}</span>
|
|
</RouterLink>
|
|
</nav>
|
|
|
|
<div class="sidebar-footer">
|
|
<button
|
|
class="nav-link nav-button"
|
|
type="button"
|
|
:title="collapsed ? '展开侧边栏' : '收起侧边栏'"
|
|
@click="emit('toggle-collapse')"
|
|
>
|
|
<PanelLeftOpen v-if="collapsed" :size="21" aria-hidden="true" />
|
|
<PanelLeftClose v-else :size="21" aria-hidden="true" />
|
|
<span>{{ collapsed ? "展开侧栏" : "收起侧栏" }}</span>
|
|
</button>
|
|
<button class="nav-link nav-button danger" type="button" title="退出登录" @click="logout">
|
|
<LogOut :size="21" aria-hidden="true" />
|
|
<span>退出登录</span>
|
|
</button>
|
|
</div>
|
|
</aside>
|
|
</template>
|