| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- <script setup lang="ts">
- import { isAllEmpty } from "@pureadmin/utils";
- import { useNav } from "@/layout/hooks/useNav";
- import { transformI18n } from "@/plugins/i18n";
- import LaySearch from "../lay-search/index.vue";
- import LayNotice from "../lay-notice/index.vue";
- import { ref, toRaw, watch, onMounted, nextTick } from "vue";
- import { useRenderIcon } from "@/components/ReIcon/src/hooks";
- import { getParentPaths, findRouteByPath } from "@/router/utils";
- import { useTranslationLang } from "../../hooks/useTranslationLang";
- import { usePermissionStoreHook } from "@/store/modules/permission";
- import LaySidebarExtraIcon from "../lay-sidebar/components/SidebarExtraIcon.vue";
- import LaySidebarFullScreen from "../lay-sidebar/components/SidebarFullScreen.vue";
- import GlobalizationIcon from "@/assets/svg/globalization.svg?component";
- import AccountSettingsIcon from "~icons/ri/user-settings-line";
- import LogoutCircleRLine from "~icons/ri/logout-circle-r-line";
- import Setting from "~icons/ri/settings-3-line";
- import Check from "~icons/ep/check";
- const menuRef = ref();
- const defaultActive = ref(null);
- const swEnable = ref(false);
- const { t, route, locale, translationCh, translationEn } =
- useTranslationLang(menuRef);
- const {
- device,
- logout,
- onPanel,
- resolvePath,
- uid,
- userAvatar,
- getDivStyle,
- avatarsStyle,
- toAccountSettings,
- getDropdownItemStyle,
- getDropdownItemClass
- } = useNav();
- function getDefaultActive(routePath) {
- const wholeMenus = usePermissionStoreHook().wholeMenus;
- /** 当前路由的父级路径 */
- const parentRoutes = getParentPaths(routePath, wholeMenus)[0];
- defaultActive.value = !isAllEmpty(route.meta?.activePath)
- ? route.meta.activePath
- : findRouteByPath(parentRoutes, wholeMenus)?.children[0]?.path;
- }
- onMounted(() => {
- getDefaultActive(route.path);
- });
- nextTick(() => {
- menuRef.value?.handleResize();
- });
- watch(
- () => [route.path, usePermissionStoreHook().wholeMenus],
- () => {
- getDefaultActive(route.path);
- }
- );
- </script>
- <template>
- <div
- v-if="device !== 'mobile'"
- v-loading="usePermissionStoreHook().wholeMenus.length === 0"
- class="horizontal-header"
- >
- <el-menu
- ref="menuRef"
- router
- mode="horizontal"
- popper-class="pure-scrollbar"
- class="horizontal-header-menu"
- :default-active="defaultActive"
- >
- <el-menu-item
- v-for="route in usePermissionStoreHook().wholeMenus"
- :key="route.path"
- :index="resolvePath(route) || route.redirect"
- >
- <template #title>
- <div
- v-if="toRaw(route.meta.icon)"
- :class="['sub-menu-icon', route.meta.icon]"
- >
- <component
- :is="useRenderIcon(route.meta && toRaw(route.meta.icon))"
- />
- </div>
- <div :style="getDivStyle">
- <span class="select-none">
- {{ transformI18n(route.meta.title) }}
- </span>
- <LaySidebarExtraIcon :extraIcon="route.meta.extraIcon" />
- </div>
- </template>
- </el-menu-item>
- </el-menu>
- <div class="horizontal-header-right">
- <!-- 菜单搜索 -->
- <LaySearch id="header-search" />
- <!-- 国际化 -->
- <el-dropdown v-if="swEnable" id="header-translation" trigger="click">
- <GlobalizationIcon
- class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-hidden"
- />
- <template #dropdown>
- <el-dropdown-menu class="translation">
- <el-dropdown-item
- :style="getDropdownItemStyle(locale, 'zh')"
- :class="['dark:text-white!', getDropdownItemClass(locale, 'zh')]"
- @click="translationCh"
- >
- <span v-show="locale === 'zh'" class="check-zh">
- <IconifyIconOffline :icon="Check" />
- </span>
- 简体中文
- </el-dropdown-item>
- <el-dropdown-item
- :style="getDropdownItemStyle(locale, 'en')"
- :class="['dark:text-white!', getDropdownItemClass(locale, 'en')]"
- @click="translationEn"
- >
- <span v-show="locale === 'en'" class="check-en">
- <IconifyIconOffline :icon="Check" />
- </span>
- English
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- <!-- 全屏 -->
- <LaySidebarFullScreen id="full-screen" />
- <!-- 消息通知 -->
- <LayNotice v-if="swEnable" id="header-notice" />
- <!-- 退出登录 -->
- <el-dropdown trigger="click">
- <span class="el-dropdown-link navbar-bg-hover select-none">
- <img :src="userAvatar" :style="avatarsStyle" />
- <p v-if="uid" class="dark:text-white">{{ uid }}</p>
- </span>
- <template #dropdown>
- <!-- <el-dropdown-item @click="toAccountSettings">
- <IconifyIconOffline
- :icon="AccountSettingsIcon"
- style="margin: 5px"
- />
- {{ t("buttons.pureAccountSettings") }}
- </el-dropdown-item> -->
- <el-dropdown-menu class="logout">
- <el-dropdown-item @click="logout">
- <IconifyIconOffline
- :icon="LogoutCircleRLine"
- style="margin: 5px"
- />
- {{ t("buttons.pureLoginOut") }}
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- <span
- class="set-icon navbar-bg-hover"
- :title="t('buttons.pureOpenSystemSet')"
- @click="onPanel"
- >
- <IconifyIconOffline :icon="Setting" />
- </span>
- </div>
- </div>
- </template>
- <style lang="scss" scoped>
- :deep(.el-loading-mask) {
- opacity: 0.45;
- }
- .translation {
- ::v-deep(.el-dropdown-menu__item) {
- padding: 5px 40px;
- }
- .check-zh {
- position: absolute;
- left: 20px;
- }
- .check-en {
- position: absolute;
- left: 20px;
- }
- }
- .logout {
- width: 120px;
- ::v-deep(.el-dropdown-menu__item) {
- display: inline-flex;
- flex-wrap: wrap;
- min-width: 100%;
- }
- }
- </style>
|